自己画的MSPM0G3507板子

Lead In

最近在跟着正点原子学习FreeRTOS,刚好学院微机原理用的是TI板,于是用新学的Cadence画了块板子之后就打算把FreeRTOS搬上MSPM0G3507。结果发现,SDK的模板全都不支持sysconfig,在kernel文件夹里面的两个例程看似有sysconfig,实则被禁用了。去官方论坛的帖子一查——

TI论坛里的官方回复果然,TI官方目前没有支持sysconfig和FreeRTOS的融合。。。

《To be honest, this would be potentially too late》——时不我待,那就来自己搞一搞吧!

CCS环境

来翻这篇文章的想必手上都有环境了。没有也没关系,这个环境很好配,sysconfig包含在CCS中了,SDK其实也可以在CCS里面自动下载,但是今天SDK是主角,我也把链接端上来。

如果(建议)手动安装SDK(毕竟不要什么都往C盘放),可以在CCS界面的左下角打开菜单-CCS Settings...,左侧找到Products的tag。如果是自己安装的SDK,就把SDK的安装路径补上去,后续就可以被软件、工程索引。如果是内置安装的SDK就在这个界面里面找到SDK的安装路径。

CCS Settings
查看、配置各个组件的路径

理论上,本文介绍的移植的方法并不依赖于CCS的开发环境,但是我没试过其他方案(IAR,Keil),留给大家探索叭~

创建、配置工程

基础工程——sysconfig启动!

左上角File - Import Project,然后browse索引,去SDK的路径下找到最基本的、含有sysconfig的空工程:

mspm0_sdk_2_04_00_06\examples\nortos\LP_MSPM0G3507\driverlib\empty

  • 注意,你选择了哪个编译器,GCC还是TIClang,要记住,我跑起来的是TIClang。

Sysconfig基础模板工程

然后打开sysconfig文件,配置好和板子适配的时钟树、debug引脚、GPIO,UART,跑一跑最基本的点灯和UART操作。

配置FreeRTOS文件

接下来,打开SDK的安装路径,开始配置FreeRTOS的文件:

配置工程路径

在刚才的工程主目录下创建FreeRTOS文件夹,并配置好目录。这里的目录可以根据个人喜好来处理,但是要记清楚,后面要头文件。

工程文件夹
FreeRTOS文件夹结构

从SDK复制文件

\mspm0_sdk_2_04_00_06\kernel\freertos\Source

│  croutine.c
│  event_groups.c
│  list.c
│  queue.c
│  stream_buffer.c
│  tasks.c
│  timers.c
  • 把这七个.c文件复制到工程文件夹下的Src文件夹下

\mspm0_sdk_2_04_00_06\kernel\freertos\Source\include

│  atomic.h
│  croutine.h
│  deprecated_definitions.h
│  event_groups.h
│  FreeRTOS.h
│  list.h
│  message_buffer.h
│  mpu_prototypes.h
│  mpu_wrappers.h
│  portable.h
│  projdefs.h
│  queue.h
│  semphr.h
│  StackMacros.h
│  stack_macros.h
│  stream_buffer.h
│  task.h
│  timers.h
  • 把所有头文件复制到Inc文件夹下。

\mspm0_sdk_2_04_00_06\kernel\freertos\Source\portable

├─GCC
│  └─ARM_CM0
│          port.c
│          portmacro.h
│
├─IAR
│  └─ARM_CM0
│          port.c
│          portasm.s
│          portmacro.h
│
├─MemMang
│      heap_1.c
│      heap_2.c
│      heap_3.c
│      heap_4.c
│      heap_5.c
│
└─TI_ARM_CLANG
    └─ARM_CM0
            port.c
            portmacro.h
  • 刚才模板工程选择了TICLang编译器的,就把TI_ARM_CLANG放进Port文件夹。如果选择的是GCC编译器,就把GCC文件夹复制过去。

可以点进去看一下,TI_ARM_CLANG下面是ARM_CM0,顾名思义;再进去是两个文件,port.cportmarco.h,这一个文件夹下的内容是对编译器和 MSPM0 做的适配。

  • 回到portable文件夹,打开MemMang(Memory Management),这几个文件是选择内存管理方案的,选择一个即可,具体区别是什么问问AI,大部分情况下选的是heap_4.c。把你选择的文件复制到工程文件夹的Port文件夹下。

\mspm0_sdk_2_04_00_06\kernel\freertos\builds\LP_MSPM0G3507\release\FreeRTOSConfig.h

注意这里的路径不是source了,是build,把FreeRTOSConfig.h复制到工程文件夹下FreeRTOS直接的目录下。


这样,所有需要的文件就配置到工程里了,检查一下路径:

\FreeRTOS

│
│  FreeRTOSConfig.h
│
├─Inc
│      atomic.h
│      croutine.h
│      deprecated_definitions.h
│      event_groups.h
│      FreeRTOS.h
│      list.h
│      message_buffer.h
│      mpu_prototypes.h
│      mpu_wrappers.h
│      portable.h
│      projdefs.h
│      queue.h
│      semphr.h
│      StackMacros.h
│      stack_macros.h
│      stream_buffer.h
│      task.h
│      timers.h
│
├─Port
│  │  heap_4.c
│  │
│  └─TI_ARM_CLANG
│      └─ARM_CM0
│              port.c
│              portmacro.h
│
└─Src
        croutine.c
        event_groups.c
        list.c
        queue.c
        stream_buffer.c
        tasks.c
        timers.c

设置引用路径

  • 如果在Keil里面配置,要先把所有的.c文件添加到左侧的工程文件中,这样才会编译。
  • CCS好像会自己检索所有的工程文件夹,或者自己处理函数引用关系进行编译,反正我没处理过源文件的引用问题,编译就完整通过了。
  • 右键点击工程文件夹,进入Properties...

进入工程配置

  • 左侧打开Build - tools - Arm Compiler - Include Options,然后把存在.h头文件的所有目录都添加到Include Path

添加引用路径

如果是GCC编译器,菜单不一样,在Directory配置引用路径。如果是Keil,就打开魔法棒添加引用路径,左侧工程添加编译源文件。

修改FreeRTOSConfig.h

众所周知,FreeRTOS的内核是可裁剪的,有些功能是需要额外添加代码实现的,在配置第一个demo的时候,可以先裁剪掉,聚焦于最基本的调度。因此,这里先对FreeRTOSConfig.h进行修改。

注意,这些裁剪都有对应的宏定义,不要自己添加,先找到宏定义项,再修改对应的数值!

#include "ti_msp_dl_config.h"
/* Other Codes */
#define configCPU_CLOCK_HZ ((unsigned long) CPUCLK_FREQ)
  • 在开头引用Driverlib的头文件,然后把系统主频改成Sysconfig生成的Marco:
#define configSUPPORT_STATIC_ALLOCATION 0
  • 禁用静态管理内存,这样不需要手动配置空闲任务
#define configUSE_TIMERS 0
  • 禁用软件定时器,在配置的时候用不上,而且不去管他的话会报错。
#define configCHECK_FOR_STACK_OVERFLOW 0
  • 不检查栈溢出。对于这个小内存的板子,为了程序的安全性其实应该打开的,但是我们需要手动定义栈溢出的异常处理函数,所以先关掉了,上手后记得重新开起来。
#define configTOTAL_HEAP_SIZE ((size_t)(16 * 1024))
  • MSPM0G3507 的 SRAM 有 32KB,这里配置16KB给RTOS自动管理,有需要后面再做调整。在 Create Task 的时候养成好习惯,检查返回值。

试试看跑任务!

配置完这些文件后,就可以编译、烧录、调试了!这里附上主文件的代码:

#include "ti_msp_dl_config.h"
#include "FreeRTOS.h"
#include "task.h"

void task_Blink(void*);
TaskHandle_t task_Blink_Handle = {0};

void task_TX(void*);
TaskHandle_t task_TX_Handle = {0};

int main(void)
{
    SYSCFG_DL_init();
    
    BaseType_t xReturn = pdPASS;

    xReturn = xTaskCreate(task_Blink, "Blink", 128, NULL, 2, &task_Blink_Handle);
    if (xReturn != pdPASS) while(1);

    xReturn = xTaskCreate(task_TX, "UART_TX", 384, NULL, 1, &task_TX_Handle);
    if (xReturn != pdPASS) while(1);

    DL_GPIO_setPins(LED_PORT, LED_LEDR_PIN | LED_LEDY_PIN);
    vTaskStartScheduler();

    return 0;
}


/* ==================== DEFINITIONS ==================== */

void task_Blink(void* p)
{
    (void)p;
    while(1)
    {
        DL_GPIO_togglePins(LED_PORT, LED_LEDY_PIN);
        vTaskDelay(500);
    }
}

void task_TX(void* p)
{
    (void)p;
    char msg[8] = "task_TX\n";
    while(1)
    {
        for(uint8_t i=0;i<8;i++)
        {
            DL_UART_transmitDataBlocking(UART0,msg[i]);
        }
        vTaskDelay(2000);
    }
}

两个死循环能够“同时”运行,就说明任务调度器在正常工作,FreeRTOS成功跑起来了。

我把我自己配置完成的工程挂在 Gitee的仓库里 了,有需要的自取 QwQ

总结

听了 FreeRTOS 的课程,使用过 CCS 的人来配置这个环境,过程应该是比较简单的。Sysconfig虽然在 SDK 的 FreeRTOS 工程里不支持,但是目前看来是不影响 FreeRTOS运行的,毕竟在port.c文件中,强制覆盖 Systick 中断配置、Systick 中断、PendSV 中断、SVC 中断都写好了,在学习好 FreeRTOS 和 Arm Cortex-M0 的基础知识后,或许可以更加随心所欲地掌控这片 MCU 了。

有趣的是,TI 还给 FreeRTOS 的库又套了一层 POSIX 的壳,估计是为了更好地在嵌入式系统之间迁移,但是这就超出了我的知识范畴了——

若有错误与疏漏,还请多多指教!

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐