当前位置:   article > 正文

RT-Thread 移植到stm32_rtthread移植到stm32

rtthread移植到stm32

系列文章目录


RT_thread移植到stm32


目录

系列文章目录

前言

一、RT_Thread源码下载

二、文件目录简介

1、bsp文件

2.components 文件夹简介

3.include 文件夹简介

4 、libcpu 文件夹简介

5.src文件

二、移植RT-THREAD

1、新建目录与添加文件

2、添加头文件 

3、rtconfig.h文件

4、修改board.c文件

5、修改定时器文件

总结



前言

实时操作系统RT_Thread移植到stm32。

一、RT_Thread源码下载

RT-Thread 源码分 RT-Thread Master 和 RT-Thread Nano。Nano 是 Master 的精简版,去掉了一些组件和各种开发板的 BSP,保留了 OS 的核心功能。

二、文件目录简介

1、bsp文件

  • bsp 文件夹里面存放的是板级支持包,即 board support package 的英文缩写。
  • bsp 文件夹下面的 board.c 是 RT-Thread 用来初始化开发板硬件的相 关函数。
  • rtconfig.h 是 RT-Thread 功能的配置头文件,里面定义了很多宏,通过这些宏定义,裁剪 RT-Thread 的功能。

2.components 文件夹简介

其它第三方加进来的软件都是组件,比如 gui、 fatfs、lwip 和 finsh 等。

3.include 文件夹简介

include 目录下面存放的是 RT-Thread 内核的头文件,是内核不可分割的一 部分。

4 、libcpu 文件夹简介

  • 存放RT-thread与单片机的关联,这些文件叫接口文件,通常由汇编和 C 联合编写。
  • 这些接口文件都是跟 硬件密切相关的,不同的硬件接口文件是不一样的,但都大同小异。编写这些接 口文件的过程我们就叫移植。

5.src文件

src 目录下面存放的是 RT-Thread 内核的源文件,是内核的核心。

二、移植RT-THREAD

1、新建目录与添加文件

2、添加头文件 

3、rtconfig.h文件

  1. /* RT-Thread config file */
  2. #ifndef __RTTHREAD_CFG_H__
  3. #define __RTTHREAD_CFG_H__
  4. //#include "RTE_Components.h"
  5. // <<< Use Configuration Wizard in Context Menu >>>
  6. // <h>Basic Configuration
  7. // <o>Maximal level of thread priority <8-256>
  8. // <i>Default: 32
  9. // RT_thread支持多个优先级
  10. #define RT_THREAD_PRIORITY_MAX 32
  11. // <o>OS tick per second
  12. // <i>Default: 1000 (1ms)
  13. // 每秒钟有多少个tick,tick即是操作系统的时钟周期,默认为1000,及操作系统的时钟周期tick等于1ms
  14. #define RT_TICK_PER_SECOND 1000
  15. // <o>Alignment size for CPU architecture data access
  16. // <i>Default: 4
  17. // 表示 CPU 处理的数据需要多少个 字节对齐,默认为 4 个字节。
  18. #define RT_ALIGN_SIZE 4
  19. // <o>the max length of object name<2-16>
  20. // <i>Default: 8
  21. // RT_NAME_MAX 这个宏表示内核对象名字的最大长度,取值 范围为 2~16,默认为 8
  22. #define RT_NAME_MAX 8
  23. // <c1>Using RT-Thread components initialization
  24. // <i>Using RT-Thread components initialization
  25. // 使用 RT-Thread 组件初始化,默认使能。
  26. #define RT_USING_COMPONENTS_INIT
  27. // </c>
  28. // <c1>Using user main
  29. // <i>Using user main
  30. // 使用用户 main 函数,默认打开
  31. #define RT_USING_USER_MAIN
  32. // </c>
  33. // <o>the size of main thread<1-4086>
  34. // <i>Default: 512
  35. // main 线程栈大小,取值范围为 1~4086,单位为字节,默 认为 512
  36. #define RT_MAIN_THREAD_STACK_SIZE 512
  37. // </h>
  38. // 钩子函数配置,目前全部关闭
  39. // <h>Debug Configuration
  40. // <c1>enable kernel debug configuration
  41. // <i>Default: enable kernel debug configuration
  42. //#define RT_DEBUG
  43. // </c>
  44. // <o>enable components initialization debug configuration<0-1>
  45. // <i>Default: 0
  46. //调试配置。包括了内核调试配置,组件调试配置和线程栈溢 出检测,目前全部关闭
  47. #define RT_DEBUG_INIT 0
  48. // <c1>thread stack over flow detect
  49. // <i> Diable Thread stack over flow detect
  50. //#define RT_USING_OVERFLOW_CHECK
  51. // </c>
  52. // </h>
  53. // <h>Hook Configuration
  54. // <c1>using hook
  55. // <i>using hook
  56. //#define RT_USING_HOOK
  57. // </c>
  58. // <c1>using idle hook
  59. // <i>using idle hook
  60. //#define RT_USING_IDLE_HOOK
  61. // </c>
  62. // </h>
  63. // <e>Software timers Configuration
  64. // <i> Enables user timers
  65. //软件定时器配置,目前关闭,不使用软件定时器。
  66. #define RT_USING_TIMER_SOFT 0
  67. #if RT_USING_TIMER_SOFT == 0
  68. #undef RT_USING_TIMER_SOFT
  69. #endif
  70. // <o>The priority level of timer thread <0-31>
  71. // <i>Default: 4
  72. #define RT_TIMER_THREAD_PRIO 4
  73. // <o>The stack size of timer thread <0-8192>
  74. // <i>Default: 512
  75. #define RT_TIMER_THREAD_STACK_SIZE 512
  76. // <o>The soft-timer tick per second <0-1000>
  77. // <i>Default: 100
  78. #define RT_TIMER_TICK_PER_SECOND 1000
  79. // </e>
  80. // 内部通信配置,包括信号量、互斥量、事件、邮箱和消息队 列, 根据需要配置。
  81. // <h>IPC(Inter-process communication) Configuration
  82. // <c1>Using Semaphore
  83. // <i>Using Semaphore
  84. #define RT_USING_SEMAPHORE
  85. // </c>
  86. // <c1>Using Mutex
  87. // <i>Using Mutex
  88. //#define RT_USING_MUTEX
  89. // </c>
  90. // <c1>Using Event
  91. // <i>Using Event
  92. //#define RT_USING_EVENT
  93. // </c>
  94. // <c1>Using MailBox
  95. // <i>Using MailBox
  96. #define RT_USING_MAILBOX
  97. // </c>
  98. // <c1>Using Message Queue
  99. // <i>Using Message Queue
  100. //#define RT_USING_MESSAGEQUEUE
  101. // </c>
  102. // </h>
  103. // 内存管理配置
  104. // <h>Memory Management Configuration
  105. // <c1>Using Memory Pool Management
  106. // <i>Using Memory Pool Management
  107. //RT_USING_MEMPOOL 这个宏用于表示是否使用内存池,目 前关闭,不使用内存池。
  108. #define RT_USING_MEMPOOL
  109. // </c>
  110. // <c1>Dynamic Heap Management
  111. // <i>Dynamic Heap Management
  112. // RT_USING_HEAP 这个宏用于表示是否堆,目前关闭,不使 用堆
  113. //#define RT_USING_HEAP
  114. // </c>
  115. // <c1>using small memory
  116. // <i>using small memory
  117. // RT_USING_SMALL_MEM 这个宏用于表示是否使用小内存, 目前使能
  118. #define RT_USING_SMALL_MEM
  119. // </c>
  120. // <c1>using tiny size of memory
  121. // <i>using tiny size of memory
  122. // RT_USING_TINY_SIZE 这个宏用于表示是否使用极小内存, 目前关闭,不使用。
  123. //#define RT_USING_TINY_SIZE
  124. // </c>
  125. // </h>
  126. // 控制台配置。控制台即是 rt_kprintf()函数调试输出的设备, 通常使用串口
  127. // <h>Console Configuration
  128. // <c1>Using console
  129. // <i>Using console
  130. #define RT_USING_CONSOLE
  131. // </c>
  132. // <o>the buffer size of console <1-1024>
  133. // <i>the buffer size of console
  134. // <i>Default: 128 (128Byte)
  135. #define RT_CONSOLEBUF_SIZE 128
  136. // <s>The device name for console
  137. // <i>The device name for console
  138. // <i>Default: uart1
  139. #define RT_CONSOLE_DEVICE_NAME "uart1"
  140. // </h>
  141. // FINSH 配置
  142. #if defined(RTE_FINSH_USING_MSH)
  143. #define RT_USING_FINSH
  144. #define FINSH_USING_MSH
  145. #define FINSH_USING_MSH_ONLY
  146. // <h>Finsh Configuration
  147. // <o>the priority of finsh thread <1-7>
  148. // <i>the priority of finsh thread
  149. // <i>Default: 6
  150. #define __FINSH_THREAD_PRIORITY 5
  151. #define FINSH_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX / 8 * __FINSH_THREAD_PRIORITY + 1)
  152. // <o>the stack of finsh thread <1-4096>
  153. // <i>the stack of finsh thread
  154. // <i>Default: 4096 (4096Byte)
  155. #define FINSH_THREAD_STACK_SIZE 512
  156. // <o>the history lines of finsh thread <1-32>
  157. // <i>the history lines of finsh thread
  158. // <i>Default: 5
  159. #define FINSH_HISTORY_LINES 1
  160. // <c1>Using symbol table in finsh shell
  161. // <i>Using symbol table in finsh shell
  162. #define FINSH_USING_SYMTAB
  163. // </c>
  164. // </h>
  165. #endif
  166. // 设备配置
  167. #if defined(RTE_USING_DEVICE)
  168. #define RT_USING_DEVICE
  169. #endif
  170. // <<< end of configuration section >>>
  171. #endif

4、修改board.c文件

  1. /*
  2. * File : board.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2017-07-24 Tanek the first version
  13. */
  14. #include <rthw.h>
  15. #include <rtthread.h>
  16. #include "board.h"
  17. #ifdef __CC_ARM
  18. //如果同时定义了 RT_USING_USER_MAIN 和 RT_USING_HEAP 这两个宏,表示 RT-Thread 里面创建内核对象时使用动态内存 分配方案
  19. //堆可以是内部的 SRAM 也可以是外部的 SRAM 或 SDRAM,目前的方法 是从内部 SRAM 里面分配一部分静态内存来作为堆空间,这里配置为 4KB
  20. // RT_USING_USER_MAIN 默认使能,通过使能或者失能 RT_USING_HEAP 这个宏来选择使用静态或者动态内存
  21. // 动态内存与静态内存的区别:区别是使用的内存是在程序编译的时候分配还是在运行的时候分配
  22. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
  23. #define RT_HEAP_SIZE 1024
  24. //从内部SRAM里面分配一部分静态内存来作为rtt的堆空间,这里配置为4KB
  25. static uint32_t rt_heap[RT_HEAP_SIZE];
  26. // 堆的起始地址
  27. RT_WEAK void *rt_heap_begin_get(void)
  28. {
  29. return rt_heap;
  30. }
  31. // 堆的结束地址
  32. RT_WEAK void *rt_heap_end_get(void)
  33. {
  34. return rt_heap + RT_HEAP_SIZE;
  35. }
  36. #endif
  37. #endif
  38. extern uint8_t OSRunning;
  39. /**
  40. * This function will initial your board.
  41. *初始化开发板硬件
  42. */
  43. void rt_hw_board_init()
  44. {
  45. //更新系统时钟,如果硬件已经能够跑起来都表示系统时钟 是没有问题的,该函数一般由固件库提供
  46. // SystemCoreClockUpdate();
  47. // 用于配置 SysTick 每 秒中断多少次,这里配置为 1000,即 1 秒钟内 SysTick 会中断 1000 次,即 中断周期为 1ms
  48. SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
  49. // 初始化系统定时器 SysTick,SysTick 给操作系统提供时 基,1 个时基我们称之为一个 tick,tick 是操作系统最小的时间单位
  50. SysTick_Init(72);
  51. // 硬件 BSP 初始化统统放在这里,比如 LED,串口,LCD 等。
  52. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
  53. LED_Init();
  54. USART1_Init(115200);
  55. OSRunning=1;
  56. /* Call components board initial (use INIT_BOARD_EXPORT()) */
  57. // RT-Thread 为开发板组件提供的一个初始化函 数
  58. #ifdef RT_USING_COMPONENTS_INIT
  59. rt_components_board_init();
  60. #endif
  61. #if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
  62. // RT-Thread 提供的一个控制 台设置函数,它将指定 rt_kprintf()函数的输出内容具体从什么设备打印出来
  63. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  64. #endif
  65. #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
  66. // RT-Thread 提供的一个内存初 始化函数,只有在使用 RT-Thread 提供的动态内存分配函数时才需要使用到
  67. rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
  68. #endif
  69. }
  70. // 中断服务函数
  71. void SysTick_Handler(void)
  72. {
  73. // 进入中断,对中断计数器 rt_interrupt_nest 加 1 操作。
  74. /* enter interrupt */
  75. rt_interrupt_enter();
  76. /* 更新时基 */
  77. //用于更新时基,实现时间片,扫描系统 定时器。
  78. rt_tick_increase();
  79. /* leave interrupt */
  80. // 退出中断,对中断计数器 rt_interrupt_nest 减 1 操作
  81. rt_interrupt_leave();
  82. }

5、修改定时器文件

  1. #include "SysTick.h"
  2. #include "rtthread.h"
  3. static u8 fac_us=0; //us延时倍乘数
  4. static u16 fac_ms=0; //ms延时倍乘数,在os下,代表每个节拍的ms数
  5. extern volatile rt_uint8_t rt_interrupt_nest;
  6. //在board.c文件的rt_hw_board_init()里面将其置为1
  7. uint8_t OSRunning=0;
  8. #ifdef RT_THREAD_PRIORITY_MAX //RT_THREAD_PRIORITY_MAX定义了,说明要支持RT-Thread
  9. #define delay_osrunning OSRunning //OS是否运行标记,0,不运行;1,在运行
  10. #define delay_ostickspersec RT_TICK_PER_SECOND //OS时钟节拍,即每秒调度次数
  11. #define delay_osintnesting rt_interrupt_nest //中断嵌套级别,即中断嵌套次数
  12. #endif
  13. //us级延时时,关闭任务调度(防止打断us级延迟)
  14. void delay_osschedlock(void)
  15. {
  16. #ifdef RT_THREAD_PRIORITY_MAX
  17. rt_enter_critical();
  18. #endif
  19. }
  20. //us级延时时,恢复任务调度
  21. void delay_osschedunlock(void)
  22. {
  23. #ifdef RT_THREAD_PRIORITY_MAX
  24. rt_exit_critical();
  25. #endif
  26. }
  27. //调用OS自带的延时函数延时
  28. //ticks:延时的节拍数
  29. void delay_ostimedly(u32 ticks)
  30. {
  31. #ifdef RT_THREAD_PRIORITY_MAX
  32. rt_thread_delay(ticks);
  33. #endif
  34. }
  35. //初始化延迟函数
  36. //SYSTICK的时钟固定为AHB时钟的1/8
  37. //SYSCLK:系统时钟频率
  38. void SysTick_Init(u8 SYSCLK)
  39. {
  40. u32 reload;
  41. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  42. fac_us=SYSCLK/8; //不论是否使用OS,fac_us都需要使用
  43. reload=SYSCLK/8; //每秒钟的计数次数
  44. reload*=1000000/delay_ostickspersec; //根据delay_ostickspersec设定溢出时间
  45. //reload为24位寄存器,最大值:16777216,在72M下,约合1.86s左右
  46. fac_ms=1000/delay_ostickspersec; //代表OS可以延时的最少单位
  47. SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
  48. SysTick->LOAD=reload; //每1/delay_ostickspersec秒中断一次
  49. SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
  50. }
  51. //延时nus
  52. //nus为要延时的us数.
  53. void delay_us(u32 nus)
  54. {
  55. u32 ticks;
  56. u32 told,tnow,tcnt=0;
  57. u32 reload=SysTick->LOAD; // LOAD的值
  58. ticks=nus*fac_us; // 需要的节拍数
  59. tcnt=0;
  60. delay_osschedlock(); // 阻止OS调度,防止打断us延时
  61. told=SysTick->VAL; // 刚进入时的计数器值
  62. while(1)
  63. {
  64. tnow=SysTick->VAL;
  65. if(tnow!=told)
  66. {
  67. if(tnow<told)tcnt+=told-tnow; // 这里注意一下SYSTICK是一个递减的计数器就可以了.
  68. else tcnt+=reload-tnow+told;
  69. told=tnow;
  70. if(tcnt>=ticks)break; // 时间超过/等于要延迟的时间,则退出.
  71. }
  72. };
  73. delay_osschedunlock(); //恢复OS调度
  74. }
  75. //延时nms
  76. //nms:要延时的ms数
  77. void delay_ms(u16 nms)
  78. {
  79. if(delay_osrunning&&delay_osintnesting==0) //如果OS已经在跑了,并且不是在中断里面(中断里面不能任务调度)
  80. {
  81. if(nms>=fac_ms) //延时的时间大于OS的最少时间周期
  82. {
  83. delay_ostimedly(nms/fac_ms); //OS延时
  84. }
  85. nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时
  86. }
  87. delay_us((u32)(nms*1000)); //普通方式延时
  88. }

总结

rt-thread移植到stm32的基本步骤。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/67471
推荐阅读
相关标签
  

闽ICP备14008679号