前言
学的东西多了难免有些记不住,通过博客形式记录下来虽然耗费些时间,但总算是留下了一些东西,回头想起来也有迹可循不用完全依赖记忆,顺便也许能对一些同仁提供些许帮助。
本文章主要记录RT-Thread系统的一些简述。
这里还是要为RT-Thread打call,毕竟是我们的国产开源操作系统,支持国产,希望在众多开发者维护下会越来越好。
我用的开发板是正点原子的潘多拉STM32L4开发板,是原子和RT-Thread联合打造的,原子的资料中有两套源码,一套是原子给的HAL库使用例程,另一套是用RT-Thread上的相关外设使用例程。下面我的一些源码展示来自RT-Thread外设使用例程,注意与RT-Thread的最新源码会有一定出入。
学习RT-Thread系统主要的获取资料和信息的通道当然还是官网:RT-Thread 官网
同时还提供了社区:RT-Thread 开源社区
官网有一篇文档《RT-Thread编程指南》非常适合初次接触RT-Thread的同学阅读。
内核源码下载:官网下载 (官网给了多个方式提供下载,非常贴心)
github 地址
启动流程
RT-Thread的启动流程有点特殊,在xxx.s启动文件之后没有直接到用户的main函数,而是利用MDK的特殊符号$ Super $ $ and $ Sub $ $ 在用户的main函数前还插入了一段程序用于一些硬件初始化以及系统初始化。
components.c文件中:
关于 S u p e r Super Super$ and S u b Sub Sub$的用法,见ARM官网描述
S u p e r Super Super$foo
Identifies the original unpatched function foo(). Use this to call the original function directly.
S u b Sub Sub$foo
Identifies the new function that is called instead of the original function foo(). Use this to add processing before or after the original function.
对这两个符号有兴趣可参考这位大佬的博客进一步了解:$ Super$ $ and $Sub $ $的用法
针对这个符号我也另起了一篇$ Super$ $ and $Sub $ $的用法
注意:$ Super $ $ and $ Sub $ $要成对使用,且只在MDK中使用。
主要看rtthread_startup()函数:
int rtthread_startup(void)
{
rt_hw_interrupt_disable();
/* 板级硬件初始化 使用的硬件初始化,包括串口初始化,系统时钟配置等 HAL库的HAL_Init()也在这里
* NOTE: please initialize heap inside board initialization.
*/
rt_hw_board_init();
/* 显示 RT-Thread 的版本号 */
rt_show_version();
/* timer system initialization */
rt_system_timer_init();
/* scheduler system initialization */
rt_system_scheduler_init();
#ifdef RT_USING_SIGNALS
/* signal system initialization */
rt_system_signal_init();
#endif
/* create init_thread */
rt_application_init();//这里面很有意思,把main函数当成一个进程来运行了
/* timer thread initialization */
rt_system_timer_thread_init();
/* 创建空闲任务 */
rt_thread_idle_init();
#ifdef RT_USING_SMP
rt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*/
/* 开启调度器 */
rt_system_scheduler_start();
/* never reach here */
return 0;
}
官方的启动流程图:
其中有一个应用初始化的函数里面创建了一个main进程,这里面的处理很有意思,main进程里把main函数当成一个进程的一部分代码去运行了(相当于main()函数变成了一个进程,这跟我们用ucos,freeRTOS的思路不太一样)。
真正的main函数就比较简单了。
int main(void)
{
unsigned int count = 1;
/* set LED pin mode to output */
rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);
while (count > 0)
{
/* led on */
rt_pin_write(LED_PIN, PIN_LOW);
rt_kprintf("led on, count: %d\n", count);
rt_thread_mdelay(500);
/* led off */
rt_pin_write(LED_PIN, PIN_HIGH);
rt_kprintf("led off\n");
rt_thread_mdelay(500);
count++;
}
return 0;
}