1. 前言
本篇将会从FreeRTOS官网下载内核源码,移植到MM32F320处理器的工程中,验证方法是创建一个任务,在任务中闪烁LED。
- 下载版本: 

2.2 移植源文件
先在工程目录下面新建Middleware/FreeRTOS文件夹,把源根目录下的FreeRTOS-Kernel复制到这个目录下。

新建项目分组,将源文件根目录下的所有的.c添加到工程中:

添加port.c到工程中,由于我们使用的是VC6所以需要将FreeRTOS\portable\GCC\ARM_CM33_NTZ\non_secure目录下面的port.c、portasm.c添加进工程。当然如果你使用vc5那就添加keil下面的库
添加内存管理文件,这里选择portable/MemMang下面的heap_4.c

设置FreeRTOS的配置文件,他在example下面有一个,我将他复到的FreeRTOS目录下面并添加进工程。
添加完工程后,工程如下:

添加好后,将编译的头文件路径也添加如下:

【配置文件】
#ifndef FREERTOS_CONFIG_H
 
#define FREERTOS_CONFIG_H
 #include "platform.h"
 
extern uint32_t SystemCoreClock;
 
 
/* Star-MC1 port configuration. */
 
#define configENABLE_MPU                                0
 
#define configENABLE_FPU                                1
 
#define configENABLE_TRUSTZONE                          0
 
 
 
/* Constants related to the behaviour or the scheduler. */
 
#define configUSE_PORT_OPTIMISED_TASK_SELECTION         0
 
#define configUSE_PREEMPTION                            1
 
#define configUSE_TIME_SLICING                          1
 
#define configMAX_PRIORITIES                            ( 5 )
 
#define configIDLE_SHOULD_YIELD                         1
 
#define configUSE_16_BIT_TICKS                          0 /* Only for 8 and 16-bit hardware. */
 
 
 
/* Constants that describe the hardware and memory usage. */
 
#define configCPU_CLOCK_HZ                              SystemCoreClock//系统时钟
 
#define configMINIMAL_STACK_SIZE                        ( ( uint16_t ) 128 )  // 定义空闲任务使用的堆栈大小。
 
#define configMAX_TASK_NAME_LEN                         ( 12 )
 
#define configTOTAL_HEAP_SIZE                           ( ( size_t ) ( 10 * 1024 ) )//配置FreeRTOS任务栈可用的RAM总量。
 
#define configTICK_RATE_HZ                          ( ( TickType_t ) 1000 )
 
/* Constants that build features in or out. */
 
#define configUSE_MUTEXES                               1
 
#define configUSE_TICKLESS_IDLE                         1
 
#define configUSE_APPLICATION_TASK_TAG                  0
 
#define configUSE_NEWLIB_REENTRANT                      0
 
#define configUSE_CO_ROUTINES                           0
 
#define configUSE_COUNTING_SEMAPHORES                   1
 
#define configUSE_RECURSIVE_MUTEXES                     1
 
#define configUSE_QUEUE_SETS                            0
 
#define configUSE_TASK_NOTIFICATIONS                    1
 
#define configUSE_TRACE_FACILITY                        1
 
 
 
/* Constants that define which hook (callback) functions should be used. */
 
#define configUSE_IDLE_HOOK                             0
 
#define configUSE_TICK_HOOK                             0
 
#define configUSE_MALLOC_FAILED_HOOK                    0
 
 
 
/* Constants provided for debugging and optimisation assistance. */
 
#define configCHECK_FOR_STACK_OVERFLOW                  0
 
#define configASSERT( x )                               if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
 
#define configQUEUE_REGISTRY_SIZE                       0
 
 
 
/* Software timer definitions. */
 
#define configUSE_TIMERS                                1
 
#define configTIMER_TASK_PRIORITY                       ( 3 )
 
#define configTIMER_QUEUE_LENGTH                        5
 
#define configTIMER_TASK_STACK_DEPTH                    ( configMINIMAL_STACK_SIZE  )
 
 
 
/* Set the following definitions to 1 to include the API function, or zero
 
 * to exclude the API function.  NOTE:  Setting an INCLUDE_ parameter to 0 is
 * only necessary if the linker does not automatically remove functions that are
 * not referenced anyway. */
#define INCLUDE_vTaskPrioritySet                        1
 
#define INCLUDE_uxTaskPriorityGet                       1
 
#define INCLUDE_vTaskDelete                             1
 
#define INCLUDE_vTaskCleanUpResources                   0
 
#define INCLUDE_vTaskSuspend                            1
 
#define INCLUDE_vTaskDelayUntil                         1
 
#define INCLUDE_vTaskDelay                              1
 
#define INCLUDE_uxTaskGetStackHighWaterMark             0
 
#define INCLUDE_xTaskGetIdleTaskHandle                  0
 
#define INCLUDE_eTaskGetState                           1
 
#define INCLUDE_xTaskResumeFromISR                      0
 
#define INCLUDE_xTaskGetCurrentTaskHandle               1
 
#define INCLUDE_xTaskGetSchedulerState                  0
 
#define INCLUDE_xSemaphoreGetMutexHolder                0
 
#define INCLUDE_xTimerPendFunctionCall                  1
 
 
 
/* This demo makes use of one or more example stats formatting functions.  These
 
 * format the raw data provided by the uxTaskGetSystemState() function in to
 * human readable ASCII form.  See the notes in the implementation of vTaskList()
 * within FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS            1
 
 
 
/* Dimensions a buffer that can be used by the FreeRTOS+CLI command interpreter.
 
 * See the FreeRTOS+CLI documentation for more information:
 * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_CLI/ */
#define configCOMMAND_INT_MAX_OUTPUT_SIZE               4096
 
 
 
/* Interrupt priority configuration follows...................... */
 
 
 
/* Use the system definition, if there is one. */
 
#ifdef __NVIC_PRIO_BITS
 
    #define configPRIO_BITS                             __NVIC_PRIO_BITS
 
#else
 
    #define configPRIO_BITS                             3   /* 8 priority levels. */
 
#endif
 
 
 
/* The lowest interrupt priority that can be used in a call to a "set priority"
 
 * function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0x07
 
 
 
/* The highest interrupt priority that can be used by any interrupt service
 
 * routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT
 * CALL INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A
 * HIGHER PRIORITY THAN THIS! (higher priorities are lower numeric values). */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
 
 
 
/* Interrupt priorities used by the kernel port layer itself.  These are generic
 
 * to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY                 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
 
 
 
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
 
 * See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY            ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << ( 8 - configPRIO_BITS ) )
 
 
 
/* The #ifdef guards against the file being included from IAR assembly files. */
 
#ifndef __IASMARM__
 
 
 
    /* Constants related to the generation of run time stats. */
 
    #define configGENERATE_RUN_TIME_STATS               0
 
    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
 
    #define portGET_RUN_TIME_COUNTER_VALUE()            0
 
  //  #define configTICK_RATE_HZ                          ( ( TickType_t ) 1000 )
 
 
 
#endif /* __IASMARM__ */
 
 
 
/* Enable static allocation. */
 
#define configSUPPORT_STATIC_ALLOCATION                 0
 
 
 
/* System Handler */
 
#define SVC_Handler                                     SVCall_Handler
 
#define xPortPendSVHandler                              PendSV_Handler
 
#define xPortSysTickHandler                             SysTick_Handler
 
 
 
#endif /* FREERTOS_CONFIG_H */具体的配置文件还需要看具体自己需要的什么功能来配置
【注意】
由于freertos实现了SVCall_Handler、PendSV_Handler、SysTick_Handler,所以我们需要在mm32f5260_it.c中注释掉这三个函数,要不会编译报错。

【测试程序】
修改main.c如下:
#define _MAIN_C_
/* Files include */
#include "platform.h"
#include "gpio_led_toggle.h"
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
/***********************************************************************************************************************
  * @brief  This function is main entrance
  * @note   main
  * @param  none
  * @retval none
  *********************************************************************************************************************/
//任务优先级
#define START_TASK_PRIO                1
//任务堆栈大小        
#define START_STK_SIZE                 256
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//任务优先级
#define LED1_TASK_PRIO                2
//任务堆栈大小        
#define LED1_STK_SIZE                 256
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
//任务优先级
#define LED2_TASK_PRIO                3
//任务堆栈大小        
#define LED2_STK_SIZE                 256
//任务句柄
TaskHandle_t LED2Task_Handler;
//任务函数
void led2_task(void *pvParameters);
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
    PLATFORM_InitConsole(115200);
    PLATFORM_InitLED();
                //创建开始任务
    xTaskCreate(  start_task  ,      //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄    
                
    vTaskStartScheduler();          //开启任务调度
        
                while (1)
                {
                }        
}
//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    xTaskCreate((TaskFunction_t )led1_task,             
                (const char*    )"led1_task",           
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,                                
                (UBaseType_t    )LED1_TASK_PRIO,        
                (TaskHandle_t*  )&LED1Task_Handler);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led2_task,     
                (const char*    )"led2_task",   
                (uint16_t       )LED2_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED2_TASK_PRIO,
                (TaskHandle_t*  )&LED2Task_Handler);         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}
//LED0任务函数 
void led1_task(void *pvParameters)
{
    while(1)
    {
				
        GPIO_WriteBit(GPIOB, GPIO_Pin_15, 0);
        vTaskDelay(500);
			GPIO_WriteBit(GPIOB, GPIO_Pin_15, 1);
			vTaskDelay(500);
    }
}   
//LED1任务函数
void led2_task(void *pvParameters)
{
    while(1)
    {
			//	printf("task2\r\n");
        GPIO_WriteBit(GPIOB, GPIO_Pin_14, 0);
        vTaskDelay(200);
        GPIO_WriteBit(GPIOB, GPIO_Pin_14, 1);
        vTaskDelay(200);
    }
}
/********************************************** (C) Copyright MindMotion **********************************************/下载到开发板上,可以可看到板载的两个LED灯会按不同的频率闪烁。
【printf卡死的问题】
经过查找资料,因为printf需要申请大的内存空间,因此必须把总栈分配大一些:
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 20 * 1024 ) )//配置FreeRTOS任务栈可用的RAM总量。
然后就可以正常的打印了。


 
					
				 
						
 
			
			
			
						
			 
					
				
 
					
				 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

