在国产单片机上移植国产操作系统2021-10-01

最近受产能影响,S**32单片机又涨价了,再好用也用不起。不过国产的雅*力单片机,规格之高,远超s**32,他们没有M0 M3内核,直接就上M4内核。对应如下:421---stM0  415--M3  401--M4   虽然421对应M0内核,但主频达到了120MHz。他的时钟可以通过一个图形工具 进行配置成48MHz 72Mhz  ,关键是价格很便宜。

1.keiL添加:Keil.AT32F4xx_DFP.1.3.7.pack 安装包

首先,碰到第一个问题是ststick时钟和定时器定时不准确,原来我们使用的内部晶振,所以要配置成内部晶振,在雅*力官网上有类似s**32 clubmx图形配置工具来配置他的时钟树。可以配置成和s**32M3内核72M的时钟频率。

点击生成代码,生成PLL的配置文件,把他加到keill工程  并引用他的初始化

2.  打开system_at32f4xx.c文件,

找到并开启带_HSI结尾的宏定义就可以了。(_HSE结尾的就是外部晶振宏定义)在时钟树上配的多少M的频率,在下面的宏定义就要打开相应的频率。

#if defined (AT32F403xx) || defined (AT32F413xx) || \

    defined (AT32F415xx) || defined (AT32F403Axx)|| \

    defined (AT32F407xx) || defined (AT32F421xx)

/* #define SYSCLK_FREQ_HSE          HSE_VALUE */

/* #define SYSCLK_FREQ_24MHz        24000000 */

/* #define SYSCLK_FREQ_36MHz        36000000 */

/* #define SYSCLK_FREQ_48MHz        48000000 */

/* #define SYSCLK_FREQ_56MHz        56000000 */

/* #define SYSCLK_FREQ_72MHz        72000000 */

/* #define SYSCLK_FREQ_96MHz        96000000 */

/* #define SYSCLK_FREQ_108MHz       108000000 */

/* #define SYSCLK_FREQ_120MHz       120000000 */

/* #define SYSCLK_FREQ_24MHz_HSI    24000000 */

/* #define SYSCLK_FREQ_36MHz_HSI    36000000 */

/* #define SYSCLK_FREQ_48MHz_HSI    48000000 */

/* #define SYSCLK_FREQ_56MHz_HSI    56000000 */

/* #define SYSCLK_FREQ_72MHz_HSI    72000000 */

/* #define SYSCLK_FREQ_96MHz_HSI    96000000 */

/* #define SYSCLK_FREQ_108MHz_HSI   108000000 */

/* #define SYSCLK_FREQ_120MHz_HSI   120000000 */

#endif

3.时钟搞定了,就可以参考官方的Demo程序,进行BSP移植,很容易就上手写逻辑。


然后进行国产操作系统RT thread的移植

我们移植的是 Nano 版本  即内核版本  还有功能强大的标准版 号称小Linux操作系统

我们可以从官网下载安装文件,RT-Thread Nano 离线安装包下载,下载结束后双击文件进行安装

打开已经准备好的可以运行的裸机程序,将 RT-Thread 添加到工程。如下图,点击 Manage Run-Time Environment

在 Manage Rum-Time Environment 里 "Software Component" 栏找到 RTOS,Variant 栏选择 RT-Thread,然后勾选 kernel,点击 "OK" 就添加 RT-Thread 内核到工程了。

现在可以在 Project 看到 RT-Thread RTOS 已经添加进来了,展开 RTOS,可以看到添加到工程的文件:

中断与异常处理

RT-Thread 会接管异常处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler(),这两个函数已由 RT-Thread 实现,所以需要删除工程里中断服务例程文件中的这两个函数,避免在编译时产生重复定义。如果此时对工程进行编译,没有出现函数重复定义的错误,则不用做修改。

系统时钟配置

需要在 board.c 中实现 系统时钟配置(为 MCU、外设提供工作时钟)与 os tick  的配置 (为操作系统提供心跳 / 节拍)。

如下代码所示,用户需要在 board.c 文件中系统初始化和 OS Tick 的配置,用户需在 timer 定时器中断服务函数调用 rt_os_tick_callback function,cortex-m 架构使用 SysTick_Handler()

/* board.c *//* timer 定时器中断服务函数调用 rt_os_tick_callback function,cortex-m 架构使用 SysTick_Handler() */voidrt_os_tick_callback(void){rt_interrupt_enter();/* 进入中断时必须调用 */rt_tick_increase();/* RT-Thread 系统时钟计数 */rt_interrupt_leave();/* 退出中断时必须调用 */}/* cortex-m 架构使用 SysTick_Handler() */SysTick_Handler(){rt_os_tick_callback();}voidrt_hw_board_init(void){/*

  * TODO 1: OS Tick Configuration

  * Enable the hardware timer and call the rt_os_tick_callback function

  * periodically with the frequency RT_TICK_PER_SECOND.

  *//* 1、系统、时钟初始化 */HAL_Init();// 初始化 HAL 库SystemClock_Config();// 配置系统时钟SystemCoreClockUpdate();// 对系统时钟进行更新/* 2、OS Tick 频率配置,RT_TICK_PER_SECOND = 1000 表示 1ms 触发一次中断 */_SysTick_Config(SystemCoreClock/RT_TICK_PER_SECOND);/* Call components board initial (use INIT_BOARD_EXPORT()) */#ifdefRT_USING_COMPONENTS_INITrt_components_board_init();#endif#ifdefined(RT_USING_USER_MAIN)&&defined(RT_USING_HEAP)rt_system_heap_init(rt_heap_begin_get(),rt_heap_end_get());#endif}

上面写那么多,实际就是把裸机的初始化,拷贝到RTT的初始化, board.c文件里。

屏蔽掉报错的中断,裸机和RTT都进行了定义,必须屏蔽掉裸机的中断函数

修改和裁剪rtconfig.h中的功能,打开和关闭要用和不要用的宏定义。

修改完 编译后会有一个报错

这是因为分配空间不足,修改如下:把RAM空间改成0x8000 即可运行

然后写个点灯的小程序验证一下。

具体可以参考RTT官网 ,有非常详细的移植文档。

你可能感兴趣的:(在国产单片机上移植国产操作系统2021-10-01)