穿西装的强子 发表于 2025-6-14 22:41

【灵动微电子MM32F0121测评】5、FreeRTOS移植

移植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秒打印一次



页: [1]
查看完整版本: 【灵动微电子MM32F0121测评】5、FreeRTOS移植