移植FREEROTS需要先下载FREERTOS组件,去官网下载即可,这里就不多赘述了
下载好的freerots组件有以下几个文件夹
在之前创建的工程内添加这些文件,一个是port文件夹,一个是core文件夹,按以下方式添加即可
在includepath添加这些文件的路径
由于mm32f0121是cortex-m0内核,所以port.c文件选择ARM_CM0内的port.c
在mm32f0120_it.c内删除PendSV_Handler和SVC_Handler函数,因为FreeRTOS需要使用这两个函数,所以会重复定义。
在SysTick_Handler函数内还需要做处理,SYSTICK使用1KHzsystick定时器中断处理函数,在SysTick_Handler添加FreeRTOS的计数函数
- extern void xPortSysTickHandler(void);
- void SysTick_Handler(void)
- {
- if (0 != PLATFORM_DelayTick)
- {
- PLATFORM_DelayTick--;
- }
- #if (INCLUDE_xTaskGetSchedulerState == 1 )
- if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
- {
- #endif /* INCLUDE_xTaskGetSchedulerState */
- xPortSysTickHandler();
- #if (INCLUDE_xTaskGetSchedulerState == 1 )
- }
- #endif /* INCLUDE_xTaskGetSchedulerState */
- }
以上基本就移植完成
然后开始配置FreeRTOSConfig.h,主要是修改中断节拍频率和堆栈大小,这里设置的频率是1KHZ,堆栈大小是128字节
- #define configCPU_CLOCK_HZ (SystemCoreClock)
- //RTOS系统节拍中断的频率。即一秒中断的次数,每次中断RTOS都会进行任务调度
- #define configTICK_RATE_HZ (( TickType_t )1000)
- //可使用的最大优先级
- #define configMAX_PRIORITIES (32)
- //空闲任务使用的堆栈大小
- #define configMINIMAL_STACK_SIZE ((unsigned short)128)
-
然后开始创建工程
- void Task_Start_Init(void)
- {
- // 创建开始任务
- xTaskCreate( (TaskFunction_t)Task_Start, // 任务函数
- (const char * )"task_start", // 任务名
- (uint16_t )START_STK_SIZE, // 任务堆栈大小
- (void* )NULL, // 传递给任务函数的参数
- (UBaseType_t )START_TASK_PRIO, // 任务优先级
- (TaskHandle_t* )StartTask_Handler);// 任务句柄
- vTaskStartScheduler();
- }
先创建一个启动任务,在该任务内创建LED任务和Printf任务,然后删除启动任务
- void Task_Start(void *pvParamemters)
- {
- taskENTER_CRITICAL(); // 进入临界区
- // 创建其它任务
- xTaskCreate( (TaskFunction_t) Task_LED, // 任务函数
- (const char * ) "task_Led", // 任务名
- (uint16_t ) LED_STK_SIZE, // 任务堆栈大小
- (void* ) NULL, // 传递给任务函数的参数
- (UBaseType_t ) LED_TASK_PRIO, // 任务优先级
- (TaskHandle_t* ) LEDTask_Handler); // 任务句柄
- // // 创建开始任务
- xTaskCreate( (TaskFunction_t) Task_Printf, // 任务函数
- (const char * ) "task_Printf", // 任务名
- (uint16_t ) PRINTF_STK_SIZE, // 任务堆栈大小
- (void* ) NULL, // 传递给任务函数的参数
- (UBaseType_t ) PRINTF_TASK_PRIO, // 任务优先级
- (TaskHandle_t* ) PrintfTask_Handler); // 任务句柄
- vTaskDelete(StartTask_Handler);
- taskEXIT_CRITICAL();
- }
由于该任务比较简单,因此使用的堆栈大小也不大
- TaskHandle_t LEDTask_Handler = NULL; // 任务句柄
- #define LED_TASK_PRIO 6 // 任务优先级
- #define LED_STK_SIZE 64 // 任务堆栈大小
- TaskHandle_t PrintfTask_Handler = NULL; // 任务句柄
- #define PRINTF_TASK_PRIO 6 // 任务优先级
- #define PRINTF_STK_SIZE 64 // 任务堆栈大小
LED任务和Printf任务函数,LED是呼吸灯,Printf是1秒打印一次Hello 21ic, Hello MM32F0121
- void Task_LED(void *pvParamemters)
- {
- uint32_t i = 0;
- while(1)
- {
- TIM1->CCR1 = 1440 - (i++%1440);
- TIM1->CCR2 = (i++%1440);
- vTaskDelay(3);
- }
- }
- void Task_Printf(void *pvParamemters)
- {
- while(1)
- {
- printf("Hello 21ic, Hello MM32F0121\r\n");
- vTaskDelay(1000);
- }
- }
效果如下,间隔1秒打印一次
|