使用的开发板:RTT&正点原子的潘多拉loT Board开发板。主控:STM32L475VET6
软件:CubeMX 6.7.0、Keil 5.38、Nano 3.1.5
第一部分:工程版本及移植 移植的方式有好多种(任选一种)
基于 Keil MDK 的移植;(最常用的工具)
基于 CubeMX 的移植;(最常用的工具)
基于官方软件 RT-Thread Studio;(自动创建工程,比较方便)
1. 使用 Keil MDK 移植 一共需要两步:
创建一份裸机代码;
在 Keil 软件中安装 RT-Thread Nano Pack;
在源工程中添加 RT-Thread Nano 源代码;
适配工作,主要从 中断、时钟、内存这几个方面进行适配,实现移植;
添加LED闪烁例程进行验证;
裁剪内核,通过配置文件 rtconfig.h 实现对系统的裁剪。
裸机代码获取:
这里可以直接使用 CubeMX 生成一份,配置上时钟、调试接口、LED的IO口之后,直接点击生成即可。下面的案例就是使用这种方式生成的。
也可以按照正点原子的教程,从固件包里面新建一个。
这两种方法在工程目录上有一点点差距,内容差不多,移植的时候找到对应的地方就可以了。
1.1 Nano Pack 安装 RT-Thread Master 的源码可以从 https://github.com/RT-Thread/rt-thread 下载。
Nano就是从里面扣出来的,去掉了一些组件和各种开发板的BSP,保留了OS的核心功能,但足够我们使用。
方式一:手动下载安装 RT-Thread 官方将抠出来的 Nano 作为一个Package放在了KEIL网站:http://www.keil.com/dd2/pack/
打开这条连接,然后拉到下面找到RealThread即可下载。
下载完成之后,直接双击安装即可,路径会自动选择Keil的安装路径。
安装完成之后,在:E:\Keil5 MDK\PACK\RealThread\RT-Thread\3.1.5 路径(Keil的安装路径)下,即可看到下载的源码。
方式二:在Keil中安装
打开Keil,点击包安装图标,点击右侧的 Pack,展开 Generic,可以找到 RealThread::RT-Thread;
点击 Action 栏对应的 Install ,就可以在线安装 Nano Pack 了。
另外,如果需要安装其他版本,则需要展开 RealThread::RT-Thread,进行选择。
图中 Remove 代表已经安装了。
1.2 Nano 版本移植 在 Manage Rum-Time Environment 里 “Software Component” 栏找到 RTOS,Variant 栏选择 RT-Thread,然后勾选 kernel,点击 “OK” 就添加 RT-Thread 内核到工程了。
然后在左侧工程栏就可以看到相关代码了。
其中的文件包含:
Cortex-M 芯片内核移植代码
1 2 context_rvds.s cpuport.c
Kernel 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 clock.c components.c device.c idle.c ipc.c irq.c kservice.c mem.c mempool.c object.c scheduler.c thread.c timer.c
配置文件
如果不想使用CMSIS添加源码,也可以直接把下载的源码复制到工程中,对照着上面的文件名添加进去即可。注意可能同一个文件所处的位置略微有些差异,其余的部分都是一样的。
在工程文件夹的 Middlewares 文件夹中创建一个 RT-Thread 文件夹。
Middlewares/RT-Thread
bsp
components
device(都要保留,后续可能用到)
finsh(都要保留,第四章用到)
include(都要保留)
libcpu
src(都要保留)
剩下的没提到的都删掉。
然后在 Keil MDK 内添加文件和头文件即可。后续学习内核的时候,这里用的就是这种方式移植的内核(因为与RTT无关的冗余文件少)。
1.3 适配工作 1.3.1 中断与异常处理
RT-Thread 会接管异常处理函数 HardFault_Handler() 和悬挂处理函数 PendSV_Handler(),这两个函数已由 RT-Thread 实现,所以需要删除工程里中断服务例程文件中的这两个函数,避免在编译时产生重复定义。如果此时对工程进行编译,没有出现函数重复定义的错误,则不用做修改。
在stm32l4xx_it.c文件中找到上述两个函数,直接注释掉即可(也可以在使用CubeMX生成代码的时候,直接不生成这部分中断代码)。
1.3.2 系统时钟配置
在 board.c 中实现 系统时钟配置(为 MCU、外设提供工作时钟)与 os tick 的配置 (为操作系统提供心跳 / 节拍)。
在board.c文件中修改如下函数,以完成系统初始化和 OS Tick 的配置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include "main.h" extern void SystemClock_Config (void ) ; void SysTick_Handler () { rt_interrupt_enter(); rt_tick_increase(); rt_interrupt_leave(); } void rt_hw_board_init (void ) { HAL_Init(); SystemClock_Config(); SystemCoreClockUpdate(); SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND); #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif #if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP) rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get()); #endif }
另外,SysTick_Handler()函数在裸机工程中应该也有,也需要去stm32l4xx_it.c文件中注释掉。
1.3.3 内存堆初始化
系统内存堆的初始化在 board.c 中的 rt_hw_board_init() 函数中完成
内存堆功能是否使用取决于宏 RT_USING_HEAP 是否开启(位于rtconfig.h中)
开启系统 heap 将可以使用动态内存功能,如使用 rt_malloc、rt_free 以及各种系统动态创建对象的 API。
若需要使用系统内存堆功能,则打开 RT_USING_HEAP 宏定义即可,此时内存堆初始化函数 rt_system_heap_init() 将被调用。
如果需要使用动态创建线程等对象,则需要配置。
1.4 LED闪烁 在main.c中添加如下代码(注意:LED引脚初始化的代码在源代码中已经配置过了)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <rtthread.h> int main (void ) { MX_GPIO_Init(); while (1 ) { HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_RESET); rt_thread_mdelay(500 ); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET); rt_thread_mdelay(500 ); } }
注意
这里使用的延时函数是由RTT提供的,此函数引起系统调度,切换到其他线程运行。
这里的main函数中不再执行初始化动作,RTT系统启动时已经做好了。
至此,将工程编译并下载,即可看到LED闪烁了。
1.5 裁剪内核 如果对内核的部分功能用不着,可以对其进行裁剪。
裁剪是通过rtconfig.h文件进行配置的。具体参照[内核裁剪](#5. 内核配置及裁剪)
先保持默认的,能用就行,后面分析阶段再说。
2. 使用 CubeMX 移植 其实和使用 Keil MDK 移植的步骤基本一样,只是添加源代码的过程不一样。
在 CubeMX 软件中安装 RT-Thread Nano pack 安装包;
在 CubeMX 配置界面添加 RT-Thread Nano 源码,然后生成工程;
适配工作,主要从 中断、时钟、内存这几个方面进行适配,实现移植;
添加LED闪烁例程进行验证;
裁剪,通过配置文件 rtconfig.h 实现对系统的裁剪。
2.1 Nano Pack 安装
在 CubeMX 中选择完芯片后,点击 Software Packs -> Manage Software Packs;
在弹出的界面下方,点击 From Url 后,弹出新的界面;
在弹出的界面下方。点击 New;
在弹出的输入框中输入:https://www.rt-thread.org/download/cube/RealThread.RT-Thread.pdsc
然后点击 Check,等待检查通过后安装即可。
2.2 Nano 版本移植 点击 Softwares Packages->Select Components,进入组件配置界面,选择 RealThread, 然后根据需求选择 RT-Thread 组件,然后点击 OK 按钮。
然后在左侧栏对组件和参数进行配置。
RT-Thread Nano 软件包中包含 kernel, shell 和 device 三个部分,仅选择 kernel 表示只使用 RT-Thread 内核,工程中会添加内核代码;选择 kernel 与 shell 表示在使用 RT-Thread Nano 的基础上使用 FinSH Shell 组件,工程中会添加内核代码与 FinSH 组件的代码,FinSH 的移植详见 《在 RT-Thread Nano 上添加控制台与 FinSH》 。再选择 device 表示使用 rt-thread 的 device 框架,用户基于此框架编写外设驱动并注册后,就可以使用 device 统一接口操作外设。
剩下的按照需要的功能进行配置即可(记得把串口加上,否则后面board.c中的串口初始化会报错,如果用不到串口可以不用配置,把其中串口初始化报错的部分注释掉就行,后面还会有用)。
2.3 适配工作 2.3.1 中断与异常处理 RT-Thread 操作系统重定义 HardFault_Handler、PendSV_Handler、SysTick_Handler 中断函数,为了避免重复定义的问题,在生成工程之前,需要在中断配置中,代码生成的选项中,取消选择三个中断函数(对应注释选项是 Hard fault interrupt, Pendable request, Time base :System tick timer),最后点击生成代码,具体操作如下图 所示:
和使用 Keil MDK 不同的是,这里直接不让生成就好了,而不是生成了重新注释。
当然,使用 Keil MDK 创建源工程的时候,也可以不生成,就不用再注释了。
2.3.2 系统时钟配置 使用 CubeMX的话,生成的代码其实已经配置好了。
可以对比 1.3.2 小节的代码看一看。
2.3.3 内存堆初始化 同 1.3.3 小节。
这里注意,生成的工程目录中有个:RT-Thread 文件夹。里面只有一个rtconfig.h文件。
但是生成的工程中,没有包含这个文件夹,所以会发现根本找不到配置文件。
因此需要在工程中对其进行添加,并添加头文件路径(如果有就算了),如下图所示。
2.4 LED闪烁 在main.c文件的while中添加如下代码(注意:LED引脚初始化的代码在源代码中已经配置过了)
1 2 3 4 5 6 7 8 9 10 11 12 while (1 ){ HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_RESET); rt_thread_mdelay(500 ); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET); rt_thread_mdelay(500 ); }
main函数中的HAL_Init()、SystemClock_Config();在我们配置系统时钟(2.3.2小节)时已经初始化过了,因此在main函数中其实不用初始化了,可以选择注释掉,但是每次生成工程都还要重新注释。
注意
这里使用的延时函数是由RTT提供的,此函数引起系统调度,切换到其他线程运行。
这里的main函数中不再执行初始化动作,RTT系统启动时已经做好了。
至此,将工程编译并下载,即可看到LED闪烁了。
2.5 裁剪内核 如果对内核的部分功能用不着,可以对其进行裁剪。
裁剪是通过rtconfig.h文件进行配置的。具体参照[内核裁剪](#5. 内核配置及裁剪)
先保持默认的,能用就行,后面分析阶段再说。
3. 使用 RT-Thread Studio 创建 直接创建 nano 工程即可。
4. 移植 FinSH 这里移植 FinSH 主要有两种目的。
基础功能:实现打印,用来向控制台对接的终端输出打印信息。
移植 FinSH 组件:命令输入,用以在控制台输入命令调试系统。
如果只需要第一个功能,则只需要实现两个函数,串口初始化和系统输出函数,即可完成 UART 控制台打印功能。
如果还需要第二个功能,则在上述基础上还需要添加 FinSH 组件源码,并再对接一个系统输入函数即可实现。
4.1 打印功能 如果使用的是 CubeMX 移植的代码,其实已经在board.c中默认配置好了(2.2小节的最后一段话有提到),如下图所示。
只需要确认这里使用的串口是不是自己实际对应的串口即可。
而如果使用的是 Keil 配置的 Nano,则如下图所示给预留了位置。
把上面的抄过来就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #ifdef RT_USING_CONSOLE static UART_HandleTypeDef UartHandle;static int uart_init (void ) { UartHandle.Instance = USART1; UartHandle.Init.BaudRate = 115200 ; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&UartHandle) != HAL_OK) { while (1 ); } return 0 ; } INIT_BOARD_EXPORT(uart_init); void rt_hw_console_output (const char *str) { rt_size_t i = 0 , size = 0 ; char a = '\r' ; __HAL_UNLOCK(&UartHandle); size = rt_strlen(str); for (i = 0 ; i < size; i++) { if (*(str + i) == '\n' ) { HAL_UART_Transmit(&UartHandle, (uint8_t *)&a, 1 , 1 ); } HAL_UART_Transmit(&UartHandle, (uint8_t *)(str + i), 1 , 1 ); } } #endif
初始化函数uart_init()的执行,是利用的INIT_BOARD_EXPORT(uart_init);语句。
可以查看官网对自动初始化机制的介绍。
然后,在main函数中添加使用到打印函数rt_kprintf()的语句。
1 2 3 4 5 6 7 rt_uint32_t count = 0 ;for (count = 0 ; count < 10 ; count++){ rt_kprintf("count: %d\n" , count); rt_thread_mdelay(500 ); }
编译并下载至开发板,打开串口调试工具并复位开发板,即可看到串口输出。
4.2 移植 FinSH 组件 如果需要移植 FinSH 组件,在完成打印功能之后,还需要:
在工程中添加 FinSH 源码。
实现函数对接。
添加 FinSH 源码的方式和 添加 Nano 的方式一样,只需要把 shell 也勾选上即可。
如果使用 CubeMX 添加 FinSH 源码,重新生成工程后,会在工程目录多出如下几个文件。
然后,在rtconfig.h中打开**#include “finsh_config.h”**。
注意:在finsh_port.c文件中,#error Please uncomment the line <#include “finsh_config.h”> in the rtconfig.h 这一行需要注释掉。
而在board.c中可以看到,相关函数已经默认写好了。
但是,这里的 DR 会报错,因为有些芯片这个寄存器的名字为DR,有的为RDR。这里将 DR 改为 RDR 即可。
而如果使用的是 Keil MDK 添加的源码。则会在工程目录多出几个文件。
同样的,添加之后,需要在rtconfig.h文件中打开**#include “finsh_config.h”**。
然后finsh_port.c文件中可以看到上面的接口,也是一样的,用这种方式的话,把上面的抄过来就好了。
这个是 RT-Thread 官网给的示例,直接抄上面的也行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #ifdef RT_USING_FINSH char rt_hw_console_getchar (void ) { int ch = -1 ; if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_RXNE) != RESET) { ch = UartHandle.Instance->RDR & 0xff ; } else { if (__HAL_UART_GET_FLAG(&UartHandle, UART_FLAG_ORE) != RESET) { __HAL_UART_CLEAR_OREFLAG(&UartHandle); } rt_thread_mdelay(10 ); } return ch; } #endif
可以发现,其实两种方法做的事情是一样的,最后除了rt_hw_console_getchar函数的位置不同,其他的基本都一样。
然后就可以测试了。使用串口助手。
不勾选发送新行,输入h,点击发送
不勾选发送新行,输入e,点击发送
不勾选发送新行,输入l,点击发送
不勾选发送新行,输入p,点击发送
什么也不输,勾选发送新行,点击发送。
显然,这种查询的方式很沙雕。
4.3 更改中断方式 这种查询的方式显然很不对,因此进一步将其更改为中断方式。
官网有所有需要添加的代码,按照自己的习惯放到某个位置就好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 #include <rtthread.h> #include <string.h> #define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - rt_ringbuffer_data_len(rb)) struct rt_ringbuffer { rt_uint8_t *buffer_ptr; rt_uint16_t read_mirror : 1 ; rt_uint16_t read_index : 15 ; rt_uint16_t write_mirror : 1 ; rt_uint16_t write_index : 15 ; rt_int16_t buffer_size; }; enum rt_ringbuffer_state { RT_RINGBUFFER_EMPTY, RT_RINGBUFFER_FULL, RT_RINGBUFFER_HALFFULL, }; rt_inline enum rt_ringbuffer_state rt_ringbuffer_status (struct rt_ringbuffer *rb) { if (rb->read_index == rb->write_index) { if (rb->read_mirror == rb->write_mirror) return RT_RINGBUFFER_EMPTY; else return RT_RINGBUFFER_FULL; } return RT_RINGBUFFER_HALFFULL; } rt_size_t rt_ringbuffer_data_len (struct rt_ringbuffer *rb) { switch (rt_ringbuffer_status(rb)) { case RT_RINGBUFFER_EMPTY: return 0 ; case RT_RINGBUFFER_FULL: return rb->buffer_size; case RT_RINGBUFFER_HALFFULL: default : if (rb->write_index > rb->read_index) return rb->write_index - rb->read_index; else return rb->buffer_size - (rb->read_index - rb->write_index); }; } void rt_ringbuffer_init (struct rt_ringbuffer *rb, rt_uint8_t *pool, rt_int16_t size) { RT_ASSERT(rb != RT_NULL); RT_ASSERT(size > 0 ); rb->read_mirror = rb->read_index = 0 ; rb->write_mirror = rb->write_index = 0 ; rb->buffer_ptr = pool; rb->buffer_size = RT_ALIGN_DOWN(size, RT_ALIGN_SIZE); } rt_size_t rt_ringbuffer_putchar (struct rt_ringbuffer *rb, const rt_uint8_t ch) { RT_ASSERT(rb != RT_NULL); if (!rt_ringbuffer_space_len(rb)) return 0 ; rb->buffer_ptr[rb->write_index] = ch; if (rb->write_index == rb->buffer_size-1 ) { rb->write_mirror = ~rb->write_mirror; rb->write_index = 0 ; } else { rb->write_index++; } return 1 ; } rt_size_t rt_ringbuffer_getchar (struct rt_ringbuffer *rb, rt_uint8_t *ch) { RT_ASSERT(rb != RT_NULL); if (!rt_ringbuffer_data_len(rb)) return 0 ; *ch = rb->buffer_ptr[rb->read_index]; if (rb->read_index == rb->buffer_size-1 ) { rb->read_mirror = ~rb->read_mirror; rb->read_index = 0 ; } else { rb->read_index++; } return 1 ; } #define UART_RX_BUF_LEN 16 rt_uint8_t uart_rx_buf[UART_RX_BUF_LEN] = {0 };struct rt_ringbuffer uart_rxcb ; static UART_HandleTypeDef UartHandle;static struct rt_semaphore shell_rx_sem ; static int uart_init (void ) { rt_ringbuffer_init(&uart_rxcb, uart_rx_buf, UART_RX_BUF_LEN); rt_sem_init(&(shell_rx_sem), "shell_rx" , 0 , 0 ); UartHandle.Instance = USART1; UartHandle.Init.BaudRate = 115200 ; UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; UartHandle.Init.WordLength = UART_WORDLENGTH_8B; UartHandle.Init.StopBits = UART_STOPBITS_1; UartHandle.Init.Parity = UART_PARITY_NONE; if (HAL_UART_Init(&UartHandle) != HAL_OK) { while (1 ); } HAL_NVIC_SetPriority(USART1_IRQn, 1 , 1 ); HAL_NVIC_EnableIRQ(USART1_IRQn); __HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE); return 0 ; } INIT_BOARD_EXPORT(uart_init); void rt_hw_console_output (const char *str) { rt_size_t i = 0 , size = 0 ; char a = '\r' ; __HAL_UNLOCK(&UartHandle); size = rt_strlen(str); for (i = 0 ; i < size; i++) { if (*(str + i) == '\n' ) { HAL_UART_Transmit(&UartHandle, (uint8_t *)&a, 1 , 1 ); } HAL_UART_Transmit(&UartHandle, (uint8_t *)(str + i), 1 , 1 ); } } char rt_hw_console_getchar (void ) { char ch = 0 ; while (rt_ringbuffer_getchar(&uart_rxcb, (rt_uint8_t *)&ch) != 1 ) { rt_sem_take(&shell_rx_sem, RT_WAITING_FOREVER); } return ch; } void USART1_IRQHandler (void ) { int ch = -1 ; rt_interrupt_enter(); if ((__HAL_UART_GET_FLAG(&(UartHandle), UART_FLAG_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&(UartHandle), UART_IT_RXNE) != RESET)) { while (1 ) { ch = -1 ; if (__HAL_UART_GET_FLAG(&(UartHandle), UART_FLAG_RXNE) != RESET) { ch = UartHandle.Instance->RDR & 0xff ; } if (ch == -1 ) { break ; } rt_ringbuffer_putchar(&uart_rxcb, ch); } rt_sem_release(&shell_rx_sem); } rt_interrupt_leave(); }
之后,再次测试时,直接输入 help 并发送即可有同样的效果。
CubeMX 生成的中断处理函数中的回调函数可以屏蔽掉。
5. 内核配置及裁剪 rtconfig.c文件内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 #ifndef __RTTHREAD_CFG_H__ #define __RTTHREAD_CFG_H__ #define RT_THREAD_PRIORITY_MAX 32 #define RT_TICK_PER_SECOND 1000 #define RT_ALIGN_SIZE 4 #define RT_NAME_MAX 8 #define RT_USING_COMPONENTS_INIT #define RT_USING_USER_MAIN #define RT_MAIN_THREAD_STACK_SIZE 1024 #define RT_DEBUG_INIT 0 #define RT_TIMER_THREAD_PRIO 4 #define RT_TIMER_THREAD_STACK_SIZE 512 #define RT_USING_SEMAPHORE #define RT_USING_HEAP #define RT_USING_SMALL_MEM #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 128 #include "finsh_config.h" #endif
finsh_config.h内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #ifndef __MSH_CFG_H__ #define __MSH_CFG_H__ #define RT_USING_FINSH #define FINSH_USING_MSH #define FINSH_USING_MSH_ONLY #define FINSH_THREAD_PRIORITY 21 #define FINSH_THREAD_STACK_SIZE 1024 #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION #endif