前言
本人正在学习rt-thread操作系统,rt-thread系统是一款非常优秀的国产的嵌入式实时操作系统,并且是完全开源和免费的,可以直接应用于商业产品开发。手里只有一款正点原子的STM32F4探索者开发板,所以就用这块开发板来学习了。该开发板的功能还是比较多的,其中的综合测试实验非常丰富,但是这款开发板是使用uC/OS-II操作系统来实现综合测试实验的,所以就想着用rt-thread系统来替换uC/OS-II系统来实现综合测试实验。
一、需要哪些知识?
用rt-thread系统来替换uC/OS-II系统来实现综合测试实验都需要具备哪些知识呢?至少需要以下几点:
1、移植
首先就是要把rt-thread系统移植到我们的工程里,这个很好理解,不移植咋用啊。
2、线程
所有嵌入式实时操作系统都有任务/线程的概念,在uC/OS-II系统里叫任务,在rt-thread系统里叫线程。线程就是一个小的程序单元,每个线程做一件事,互相不干扰,由系统进行调配和管理。这里我们需要掌握线程的创建、切换等知识。
3、线程间同步和通信
很多时候不仅需要线程间切换,而且还需要各个线程间的同步和通信。比如几个线程都需要操作同一个数组,或者几个线程需要使用同一个变量等等。各种嵌入式实时操作系统都有自己的线程间同步和通信的工具,比如,信号量、邮箱等等。我们需掌握这些工具的创建和使用。
掌握这3点就基本可以完成rt-thread系统对uC/OS-II系统的替换了,但是rt-thread系统可不只这些内容,它还有设备框架、文件系统等概念。后续可以用rt-thread系统的设备框架实现开发板的外设操作,还可以使用rt-thread系统的文件系统来替换综合实验里使用的FATFS文件系统等等,慢慢来,需要学习的东西还有很多。
二、移植
具体移植过程如下:
1、准备rt-thread系统源码,我用的是rt-thread-4.0.3正式发布版,发布版比较稳定,是rt-thread官网推荐的可用于正式产品中的版本。
2、准备探索者开发板里面的综合测试实验源码,我用的是寄存器版本,用库函数版本也一样,我们只针对操作系统的替换,其他具体实现的函数不做修改。
3、在综合测试实验下建立名为rtthread的文件夹,文件夹里放入如下图所示内容。
这些文件都是从rt-thread-4.0.3正式发布版里面复制过来的。发布版里面有很多文件,我们只选择对我们有用的,其他的文件不需要。上面图片里的include和src都是直接复制过来的;libcpu里面只复制了libcpu\arm\cortex-m4文件夹;board文件夹是复制了bsp\stm32\stm32f407-atk-explorer\board文件夹。这里我们先只使用rt-thread系统的内核文件,后续再把rt-thread系统的设备框架、文件系统等逐步加上。
4、修改工程文件。打开工程,在项目里添加两个文件夹rt-thread-Kernel和rt-thread-CORTEX-M4。rt-thread-Kernel里添加rt-thread内核源文件;rt-thread-CORTEX-M4里添加cpuport.c和context_rvds.s文件;在USER里面添加board.c文件,然后添加对应的.h文件。把uC/OS-II的文件夹移除。
5、修改board.c文件。board文件夹里面的board.c文件,需要修改一下。这里面只需要放一个rt_hw_board_init()函数即可,这个函数主要完成在进入main函数之前的一些初始化工作。函数里的具体程序如下:
void rt_hw_board_init()
{
#ifdef SCB_EnableICache
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
#endif
#ifdef SCB_EnableDCache
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* Heap initialization */
#if defined(RT_USING_HEAP)
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
/* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
rt_hw_pin_init();
#endif
/* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
rt_hw_usart_init();
#endif
/* Set the shell console output device */
#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
6、简化替换。探索者开发板综合测试实验实现了很多功能。这里为了先让rt-thread系统跑起来,第一阶段我们先实现部分功能。具体如下:具体实现的功能如下:
case 0:ebook_play();break; //电子图书
case 1:picviewer_play();break; //数码相框
case 4:calendar_play();break; //时钟
case 7:notepad_play();break; //记事本
case 8:exe_play();break; //运行器
case 9:paint_play();break; //手写画笔
case 15:calc_play();break; //计算器
case 17:app_play();break; //APP
这些功能的实现只用到了线程的知识,上手比较快。其他的功能先注释掉,同时在工程里移除相应功能的文件夹,要不会报错。
以上移植的工作就完成了,下面该具体修改程序,完成替换了。
三、修改程序。
需要修改的程序不算多,主要是用rt-thread系统里的函数替换掉对应uC/OS-II系统里的函数。具体修改内容如下:
1、修改delay.c文件。开发板里的delay.c文件要修改一下,其中包括调度上锁,调度解锁,延时函数,systick中断服务函数,2个宏定义,3个函数。具体如下:
#define delay_ostickspersec RT_TICK_PER_SECOND //OS时钟节拍,即每秒调度次数
#define delay_osintnesting rt_interrupt_nest //中断嵌套级别,即中断嵌套次数
//us级延时时,关闭任务调度(防止打断us级延迟)
void delay_osschedlock(void)
{
rt_enter_critical(); //RT-Thread调度器上锁
}
//us级延时时,恢复任务调度
void delay_osschedunlock(void)
{
rt_exit_critical(); //RT-Thread调度器解锁
}
//调用OS自带的延时函数延时
//ticks:延时的节拍数
void delay_ostimedly(u32 ticks)
{
rt_thread_delay(ticks); //RT-Thread延时
}
//systick中断服务函数,使用OS时用到
void SysTick_Handler(void)
{
if(delay_osrunning==1) //OS开始跑了,才执行正常的调度处理
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
2、删掉重复的函数。HardFault_Handler函数使用开发板里面的,把context_rvds.s里面的HardFault_Handler函数删掉。
3、uC/OS-II系统里的进入中断和离开中断函数全部用rt-thread系统里相应的函数替换。
rt_interrupt_enter();替换OSIntEnter();
rt_interrupt_leave();替换OSIntExit();
rt_enter_critical();替换OS_ENTER_CRITICAL();
rt_exit_critical();替换OS_EXIT_CRITICAL();
4、线程替换任务。在rt-thread系统下创建4个线程,替换uC/OS-II系统下的4个任务。分别为START线程、USART线程、MAIN线程和WATCH线程。uC/OS-II系统创建任务用的是OSTaskCreate函数,rt-thread系统创建线程用的rt_thread_create函数。如何创建线程和具体的代码,这里就不写了,最后我会上传整个工程的源文件,可以看里面内容。值得注意的是,这里遇到了一个问题,就是线程的栈大小设置。最开始我把线程栈的大小设置成和uC/OS-II系统对应任务栈的大小一样,结果程序总是卡死,最后发现是栈溢出错误。然后我将线程的栈改大一些,就正常了。这里具体为什么会出现这个问题,还没有弄明白,有时间仔细研究一下。
总结
以上就是用rt-thread系统来替换uC/OS-II系统来实现探索者开发板综合测试实验的第一阶段,这一阶段完成了rt-thread系统的移植,主要线程的创建,实现了综合实验的部分功能。总体来说还是比较简单的,但是从初学操作系统到完成以上工作还是费了一点力气。希望能给需要的人带来一点帮助。
接下来第二阶段的文章将实现音频播放功能,这里需要用到线程间通信,邮箱的功能,同时还需要创建一个音乐播放线程。好了,这篇文章就到这里。
版权声明:本文为CSDN博主「i5201576」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/i5201576/article/details/122732327
前言
本人正在学习rt-thread操作系统,rt-thread系统是一款非常优秀的国产的嵌入式实时操作系统,并且是完全开源和免费的,可以直接应用于商业产品开发。手里只有一款正点原子的STM32F4探索者开发板,所以就用这块开发板来学习了。该开发板的功能还是比较多的,其中的综合测试实验非常丰富,但是这款开发板是使用uC/OS-II操作系统来实现综合测试实验的,所以就想着用rt-thread系统来替换uC/OS-II系统来实现综合测试实验。
一、需要哪些知识?
用rt-thread系统来替换uC/OS-II系统来实现综合测试实验都需要具备哪些知识呢?至少需要以下几点:
1、移植
首先就是要把rt-thread系统移植到我们的工程里,这个很好理解,不移植咋用啊。
2、线程
所有嵌入式实时操作系统都有任务/线程的概念,在uC/OS-II系统里叫任务,在rt-thread系统里叫线程。线程就是一个小的程序单元,每个线程做一件事,互相不干扰,由系统进行调配和管理。这里我们需要掌握线程的创建、切换等知识。
3、线程间同步和通信
很多时候不仅需要线程间切换,而且还需要各个线程间的同步和通信。比如几个线程都需要操作同一个数组,或者几个线程需要使用同一个变量等等。各种嵌入式实时操作系统都有自己的线程间同步和通信的工具,比如,信号量、邮箱等等。我们需掌握这些工具的创建和使用。
掌握这3点就基本可以完成rt-thread系统对uC/OS-II系统的替换了,但是rt-thread系统可不只这些内容,它还有设备框架、文件系统等概念。后续可以用rt-thread系统的设备框架实现开发板的外设操作,还可以使用rt-thread系统的文件系统来替换综合实验里使用的FATFS文件系统等等,慢慢来,需要学习的东西还有很多。
二、移植
具体移植过程如下:
1、准备rt-thread系统源码,我用的是rt-thread-4.0.3正式发布版,发布版比较稳定,是rt-thread官网推荐的可用于正式产品中的版本。
2、准备探索者开发板里面的综合测试实验源码,我用的是寄存器版本,用库函数版本也一样,我们只针对操作系统的替换,其他具体实现的函数不做修改。
3、在综合测试实验下建立名为rtthread的文件夹,文件夹里放入如下图所示内容。
这些文件都是从rt-thread-4.0.3正式发布版里面复制过来的。发布版里面有很多文件,我们只选择对我们有用的,其他的文件不需要。上面图片里的include和src都是直接复制过来的;libcpu里面只复制了libcpu\arm\cortex-m4文件夹;board文件夹是复制了bsp\stm32\stm32f407-atk-explorer\board文件夹。这里我们先只使用rt-thread系统的内核文件,后续再把rt-thread系统的设备框架、文件系统等逐步加上。
4、修改工程文件。打开工程,在项目里添加两个文件夹rt-thread-Kernel和rt-thread-CORTEX-M4。rt-thread-Kernel里添加rt-thread内核源文件;rt-thread-CORTEX-M4里添加cpuport.c和context_rvds.s文件;在USER里面添加board.c文件,然后添加对应的.h文件。把uC/OS-II的文件夹移除。
5、修改board.c文件。board文件夹里面的board.c文件,需要修改一下。这里面只需要放一个rt_hw_board_init()函数即可,这个函数主要完成在进入main函数之前的一些初始化工作。函数里的具体程序如下:
void rt_hw_board_init()
{
#ifdef SCB_EnableICache
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
#endif
#ifdef SCB_EnableDCache
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
#endif
/* Heap initialization */
#if defined(RT_USING_HEAP)
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
/* Pin driver initialization is open by default */
#ifdef RT_USING_PIN
rt_hw_pin_init();
#endif
/* USART driver initialization is open by default */
#ifdef RT_USING_SERIAL
rt_hw_usart_init();
#endif
/* Set the shell console output device */
#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
/* Board underlying hardware initialization */
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
6、简化替换。探索者开发板综合测试实验实现了很多功能。这里为了先让rt-thread系统跑起来,第一阶段我们先实现部分功能。具体如下:具体实现的功能如下:
case 0:ebook_play();break; //电子图书
case 1:picviewer_play();break; //数码相框
case 4:calendar_play();break; //时钟
case 7:notepad_play();break; //记事本
case 8:exe_play();break; //运行器
case 9:paint_play();break; //手写画笔
case 15:calc_play();break; //计算器
case 17:app_play();break; //APP
这些功能的实现只用到了线程的知识,上手比较快。其他的功能先注释掉,同时在工程里移除相应功能的文件夹,要不会报错。
以上移植的工作就完成了,下面该具体修改程序,完成替换了。
三、修改程序。
需要修改的程序不算多,主要是用rt-thread系统里的函数替换掉对应uC/OS-II系统里的函数。具体修改内容如下:
1、修改delay.c文件。开发板里的delay.c文件要修改一下,其中包括调度上锁,调度解锁,延时函数,systick中断服务函数,2个宏定义,3个函数。具体如下:
#define delay_ostickspersec RT_TICK_PER_SECOND //OS时钟节拍,即每秒调度次数
#define delay_osintnesting rt_interrupt_nest //中断嵌套级别,即中断嵌套次数
//us级延时时,关闭任务调度(防止打断us级延迟)
void delay_osschedlock(void)
{
rt_enter_critical(); //RT-Thread调度器上锁
}
//us级延时时,恢复任务调度
void delay_osschedunlock(void)
{
rt_exit_critical(); //RT-Thread调度器解锁
}
//调用OS自带的延时函数延时
//ticks:延时的节拍数
void delay_ostimedly(u32 ticks)
{
rt_thread_delay(ticks); //RT-Thread延时
}
//systick中断服务函数,使用OS时用到
void SysTick_Handler(void)
{
if(delay_osrunning==1) //OS开始跑了,才执行正常的调度处理
{
/* enter interrupt */
rt_interrupt_enter();
rt_tick_increase();
/* leave interrupt */
rt_interrupt_leave();
}
2、删掉重复的函数。HardFault_Handler函数使用开发板里面的,把context_rvds.s里面的HardFault_Handler函数删掉。
3、uC/OS-II系统里的进入中断和离开中断函数全部用rt-thread系统里相应的函数替换。
rt_interrupt_enter();替换OSIntEnter();
rt_interrupt_leave();替换OSIntExit();
rt_enter_critical();替换OS_ENTER_CRITICAL();
rt_exit_critical();替换OS_EXIT_CRITICAL();
4、线程替换任务。在rt-thread系统下创建4个线程,替换uC/OS-II系统下的4个任务。分别为START线程、USART线程、MAIN线程和WATCH线程。uC/OS-II系统创建任务用的是OSTaskCreate函数,rt-thread系统创建线程用的rt_thread_create函数。如何创建线程和具体的代码,这里就不写了,最后我会上传整个工程的源文件,可以看里面内容。值得注意的是,这里遇到了一个问题,就是线程的栈大小设置。最开始我把线程栈的大小设置成和uC/OS-II系统对应任务栈的大小一样,结果程序总是卡死,最后发现是栈溢出错误。然后我将线程的栈改大一些,就正常了。这里具体为什么会出现这个问题,还没有弄明白,有时间仔细研究一下。
总结
以上就是用rt-thread系统来替换uC/OS-II系统来实现探索者开发板综合测试实验的第一阶段,这一阶段完成了rt-thread系统的移植,主要线程的创建,实现了综合实验的部分功能。总体来说还是比较简单的,但是从初学操作系统到完成以上工作还是费了一点力气。希望能给需要的人带来一点帮助。
接下来第二阶段的文章将实现音频播放功能,这里需要用到线程间通信,邮箱的功能,同时还需要创建一个音乐播放线程。好了,这篇文章就到这里。
版权声明:本文为CSDN博主「i5201576」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/i5201576/article/details/122732327
暂无评论