本文目的:移植RTOS到MM32F0121系列MCU
首先要准备一个MM32F0121基本模板,可以以GPIO_LED_Toggle为基础。
在LibSamples_MM32F0120_V1.13.4中建立了middlewares\freertos目录,复制一份freeRTOS库文件此目录
将freeRTOS下各路径下7个文件添加到工程中
添加include paths
..\..\..\..\..\middlewares\freertos\source\include
..\..\..\..\..\middlewares\freertos\source\portable\rvds\ARM_CM0
在freeRTOS中找到FreeRTOSConfig.h、portmacro.h,复制到工程根目录下
FreeRTOSConfig.h中修改
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( 72000000 )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 3*1024 ) )
#define configMAX_TASK_NAME_LEN ( 5 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configGENERATE_RUN_TIME_STATS 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 0
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 5
#define configTIMER_TASK_STACK_DEPTH ( 80 )
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
//#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
#endif /* FREERTOS_CONFIG_H */
注意其中:
#define configCPU_CLOCK_HZ ( 72000000 ) //主频72MHZ
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) //stack根据情况设置,LED task可以设小点,printf需要设大一点
#define xPortPendSVHandler PendSV_Handler //
#define xPortSysTickHandler SysTick_Handler //这两个中断需要被freeRTOS接管
mm32f0120_it.c中将这两个中断处理函数注释掉,避免编译冲突
/*
void PendSV_Handler(void)
{
}
*/
/*
void SysTick_Handler(void)
{
if (0 != PLATFORM_DelayTick)
{
PLATFORM_DelayTick--;
}
}
*/
main()修改,执行freeRTOS_Sample()
int main(void)
{
PLATFORM_Init();
freeRTOS_Sample();
while (1)
{
}
}
PLATFORM_Init中注释掉PLATFORM_InitDelay()
void PLATFORM_Init(void)
{
// PLATFORM_InitDelay();
PLATFORM_InitConsole(115200);
PLATFORM_InitLED();
PLATFORM_PrintInfo();
}
新建freeRTOS_demo.c存放以下内容:
freeRTOS_Sample()
建立3个Task
#define PRINT_TASK_STACK_SIZE (256) // 256 words = 1024 bytes
#define LED_TASK_STACK_SIZE (configMINIMAL_STACK_SIZE) // 128 words = 512 bytes
void freeRTOS_Sample(void)
{
printf("【灵动微电子MM32F0121测评】8、移植RTOS到MM32F0121系列MCU\r\n");
SysTick_Init();
xTaskCreate( vLED1Task, "LED1", LED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY + 6 , NULL );
xTaskCreate( vLED2Task, "LED2", LED_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY + 7 , NULL );
xTaskCreate( printTask, "print", PRINT_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY + 8 , NULL );
vTaskStartScheduler();
while(1); // 正常情况下不会执行到这里
}
SysTick_Init()
static void SysTick_Init(void)
{
if (SysTick_Config(SystemCoreClock / configTICK_RATE_HZ)) {
printf("SysTick config failed\r\n");
while (1); // 初始化失败
}
}
三个TASK
void vLED1Task( void *pvParameters )
{
for( ;; )
{
PLATFORM_LED_Toggle(LED1);
//printf("1 Free Heap: %d\n", xPortGetFreeHeapSize());
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void vLED2Task( void *pvParameters )
{
for( ;; )
{
PLATFORM_LED_Toggle(LED2);
//printf("2 Free Heap: %d\n", xPortGetFreeHeapSize());
vTaskDelay(pdMS_TO_TICKS(500));
}
}
void printTask( void *pvParameters )
{
for( ;; )
{
printf("Hello 21ic, Hello MM32F0121\r\n");
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
运行情况:
|