tpgf 发表于 2024-11-7 10:45

立创CW32F030C8T6移植FreeRTOS

一、下载FreeRTOS源码
首先从代码托管网站上https://sourceforge.net/projects/freertos/files/FreeRTOS/下载最新的FreeRTOS,下载的是v10.4.1版本。



下载解压后的是这些东西。



其中FreeRTOS是需要移植的操作系统。而FreeRTOS-Plus内我感觉是些附加的其他库,而且大部分好像是收费的,所以我们仅需要用到FreeRTOS这个文件夹即可。

二、移植FreeRTOS
首先需要找一套可以用来移植的源码,我从立创开发板https://wiki.lckfb.com/zh-hans/dwx-cw32f030c8t6/。这个网页的百度云盘中找到一份空白工程模板下载后。



这就是代码的文件夹了。



在其中创建一个FreeRTOS的文件夹,用于存放移植的代码。



并且在其中创建三个文件夹。



分别用来移植以下代码。



将Source目录下的代码复制到src中,include也直接复制即可,注意portable仅需要MemMang文件夹和RVDS的ARM_CM0(因为CW32F030C8T6是M0的内核)。



另外复制一份Demo中的FreeRTOSConfig并存入APP文件夹内,我复制的是stm32f103的。



后续我们就可以打开keil,将代码路径等存储进去了。



另外需要配置xPortSysTickHandler这个函数,具体位置如下。



extern void xPortSysTickHandler(void);
void SysTick_Handler(void)
{
    #if (INCLUDE_xTaskGetSchedulerState== 1 )
      if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
      {
    #endif/* INCLUDE_xTaskGetSchedulerState */
      xPortSysTickHandler();
    #if (INCLUDE_xTaskGetSchedulerState== 1 )
      }
    #endif/* INCLUDE_xTaskGetSchedulerState */
}




然后从野火那里抄点main函数代码即可。

#include "board.h"
#include "stdio.h"
#include "bsp_uart.h"
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"


/**************************** 任务句柄 ********************************/
/*
* 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
* 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
* 这个句柄可以为NULL。
*/
/* 创建任务句柄 */
static TaskHandle_t AppTaskCreate_Handle = NULL;
/* LED1任务句柄 */
static TaskHandle_t LED1_Task_Handle = NULL;
/* LED2任务句柄 */
static TaskHandle_t LED2_Task_Handle = NULL;

/*
*************************************************************************
*                           函数声明
*************************************************************************
*/
static void AppTaskCreate(void);/* 用于创建任务 */

static void LED1_Task(void* pvParameters);/* LED1_Task任务实现 */
static void LED2_Task(void* pvParameters);/* LED2_Task任务实现 */

static void BSP_Init(void);/* 用于初始化板载相关资源 */


int32_t main(void)
{
        BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
BSP_Init();
        printf("你好!\r\n");
           /* 创建AppTaskCreate任务 */
xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,/* 任务入口函数 */
                        (const char*    )"AppTaskCreate",/* 任务名字 */
                        (uint16_t       )64,/* 任务栈大小 */
                        (void*          )NULL,/* 任务入口函数参数 */
                        (UBaseType_t    )1, /* 任务的优先级 */
                        (TaskHandle_t*)&AppTaskCreate_Handle);/* 任务控制块指针 */
                                                                                               
       
/* 启动任务调度 */         
if(pdPASS == xReturn)
    vTaskStartScheduler();   /* 启动任务,开启调度 */
else
    return -1;

while(1);   /* 正常不会执行到这里 */   
       
}



/***********************************************************************
* @ 函数名: AppTaskCreate
* @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
* @ 参数    : 无
* @ 返回值: 无
**********************************************************************/
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */

taskENTER_CRITICAL();         //进入临界区

/* 创建LED_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )LED1_Task, /* 任务入口函数 */
                        (const char*    )"LED1_Task",/* 任务名字 */
                        (uint16_t       )64,   /* 任务栈大小 */
                        (void*          )NULL,        /* 任务入口函数参数 */
                        (UBaseType_t    )2,          /* 任务的优先级 */
                        (TaskHandle_t*)&LED1_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
    printf("创建LED1_Task任务成功!\r\n");

        /* 创建LED_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )LED2_Task, /* 任务入口函数 */
                        (const char*    )"LED2_Task",/* 任务名字 */
                        (uint16_t       )64,   /* 任务栈大小 */
                        (void*          )NULL,        /* 任务入口函数参数 */
                        (UBaseType_t    )3,          /* 任务的优先级 */
                        (TaskHandle_t*)&LED2_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn)
    printf("创建LED2_Task任务成功!\r\n");

vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务

taskEXIT_CRITICAL();            //退出临界区
}



/**********************************************************************
* @ 函数名: LED_Task
* @ 功能说明: LED_Task任务主体
* @ 参数    :   
* @ 返回值: 无
********************************************************************/
static void LED1_Task(void* parameter)
{       
    while (1)
    {
                          // 高电平
                  GPIO_WritePin(CW_GPIOC, GPIO_PIN_13, GPIO_Pin_SET);
      vTaskDelay(500);   /* 延时500个tick */
      printf("LED1_Task Running,LED1_ON\r\n");   
                  // 低电平
                  GPIO_WritePin(CW_GPIOC, GPIO_PIN_13, GPIO_Pin_RESET);   
      vTaskDelay(500);   /* 延时500个tick */                              
      printf("LED1_Task Running,LED1_OFF\r\n");
    }
}

/**********************************************************************
* @ 函数名: LED_Task
* @ 功能说明: LED_Task任务主体
* @ 参数    :   
* @ 返回值: 无
********************************************************************/
static void LED2_Task(void* parameter)
{       
    while (1)
    {
                  GPIO_WritePin(CW_GPIOC, GPIO_PIN_14, GPIO_Pin_SET);
      vTaskDelay(500);   /* 延时500个tick */
      printf("LED2_Task Running,LED2_ON\r\n");

                  GPIO_WritePin(CW_GPIOC, GPIO_PIN_14, GPIO_Pin_RESET);
      vTaskDelay(500);   /* 延时500个tick */                              
      printf("LED2_Task Running,LED2_OFF\r\n");
    }
}




static void BSP_Init(void)
{
        board_init();        // 开发板初始化
       
        uart1_init(115200);        // 串口1波特率115200
       
        GPIO_InitTypeDef        GPIO_InitStruct; // GPIO初始化结构体
       
        __RCC_GPIOC_CLK_ENABLE();        // 使能GPIO时钟
       
    GPIO_InitStruct.Pins = GPIO_PIN_13|GPIO_PIN_14;                                // GPIO引脚
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;                // 推挽输出
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;                // 输出速度高
    GPIO_Init(CW_GPIOC, &GPIO_InitStruct);                        // 初始化
       

}









三、解决问题
在移植的过程中遇到数个问题,解决方法如下。

问题1:直接移植报错
.\OBJ\LED.axf: Error: L6218E: Undefined symbol xTaskGetCurrentTaskHandle (referred from stream_buffer.o).
问题主要在于xTaskGetCurrentTaskHandle 这个函数有个宏,把他打开就行。

问题2:主频问题
直接复制过来之后stm32f103的主频其实是72M,所以我们需要改成CW32的64M。



问题3:RAM报错
Error: L6406E: No space in execution regions with .ANY selector matching queue.o(.bss). 这个报错是因为移植的stm32f103它的RAM比CW32大的多,从其手册可知RAM是8KB。



故需要将HEAP_SIZE改小,我改成了5*1024。



问题4:上电卡死在初始化任务上
首先结论是我没有在FreeRTOSConfig中配置下面这个东西。



最开始没配置会卡死在startup中的PendSV这个中断函数上,我加上上面的代码就好了,应该是会用到这两个中断。



四、现象展示及代码
最终结果如下,LED灯闪烁就不展示了,因为其实也就一个灯在闪而已。



大概就是这些了,后续打算继续利用cw32做一些东西,也会发在CSDN上,可以私聊我一起学习共同进步。
代码链接如下:
通过百度网盘分享的文件:cw32移植freertos.rar
链接:https://pan.baidu.com/s/1AUHh22onuiauFJv6K06S5g?pwd=87w7
提取码:87w7
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/huayidw/article/details/141167770

OKAKAKO 发表于 2024-11-13 17:45

移植FreeRTOS参考一下

星辰大海不退缩 发表于 2024-11-22 18:04

移植学习一下

中国龙芯CDX 发表于 2024-11-24 14:44

应该是芯源的芯片吧,嘉立创做的板子进行的移植?
页: [1]
查看完整版本: 立创CW32F030C8T6移植FreeRTOS