01_rtthread_startup_log

RT-Thread启动涉及硬件初始化、内核对象设置、main线程创建及调度器启动。在调度器启动前,线程处于就绪状态,启动后运行优先级最高的线程。rt_hw_board_init()负责时钟设置、串口初始化等。

// 测试使用的工程文件目录:Z:\2022-YS\YS-F4-Pro_HAL_RT-Thread-Demo

RT-Thread的启动流程如下图所示:

RT-Thread 支持多种平台和多种编译器,而 rtthread_startup() 函数是 RT-Thread 规定的统一启动入口。一般执行顺序是:系统先从启动文件开始运行,然后进入 RT-Thread 的启动函数 rtthread_startup() ,最后进入用户入口函数 main(),如上图所示。

 

 

 这部分启动代码,大致可以分为四个部分:

(1)初始化与系统相关的硬件;

(2)初始化系统内核对象,例如定时器、调度器、信号;

(3)创建 main 线程,在 main 线程中对各类模块依次进行初始化;

(4)初始化定时器线程、空闲线程,并启动调度器。

启动调度器之前,系统所创建的线程在执行 rt_thread_startup() 后并不会立马运行,它们会处于就绪状态等待系统调度;待启动调度器之后,系统才转入第一个线程开始运行,根据调度规则,选择的是就绪队列中优先级最高的线程。

rt_hw_board_init() 中完成系统时钟设置,为系统提供心跳、串口初始化,将系统输入输出终端绑定到这个串口,后续系统运行信息就会从串口打印出来。

 

 

 

 

 

 

 

 

 

你提供的代码是 RT-Thread 操作系统中创建多个线程的标准写法,用于启动如串口接收、连接云平台、获取空气质量数据、URC 监听和按键检测等任务。整体结构合理,但存在 **一处明显的拼写错误** 和一些潜在的可改进点。 --- ### ✅ 问题分析与修复 #### 🔴 主要问题:线程句柄变量名拼写错误 ```c Keycheckthrea = rt_thread_create("Keycheckthrea", KeycheckthreadHanld, RT_NULL, 128, 2, 10); ``` - 变量名为 `Keycheckthrea`(少了一个 `d`),而函数名是 `KeycheckthreadHanld`。 - 这可能导致后续无法正确操作该线程(比如删除或控制),虽然编译不会报错,但属于低级命名错误,容易引发维护问题。 应改为: ```c Keycheckthread = rt_thread_create("Keycheckthread", KeycheckthreadHanld, RT_NULL, 128, 2, 10); ``` > 建议统一命名风格:函数名、线程名、句柄变量名尽量一致且语义清晰。 --- ### ✅ 正确并格式化后的完整代码: ```c uartReceivethread = rt_thread_create("uartReceive", uartReceivethreadHanld, RT_NULL, 128, 4, 10); // if (uartReceivethread != RT_NULL) // rt_thread_startup(uartReceivethread); ConnetCloudthread = rt_thread_create("ConnetCloud", ConnetcloudthreadHanld, RT_NULL, 2048, 3, 10); if (ConnetCloudthread != RT_NULL) rt_thread_startup(ConnetCloudthread); getairthread = rt_thread_create("getair", getairthreadHanld, RT_NULL, 128, 2, 10); if (getairthread != RT_NULL) rt_thread_startup(getairthread); urcMonitorthread = rt_thread_create("urcMonitor", urcMonitorthreadHanld, RT_NULL, 128, 3, 10); if (urcMonitorthread != RT_NULL) rt_thread_startup(urcMonitorthread); Keycheckthread = rt_thread_create("Keycheckthread", KeycheckthreadHanld, RT_NULL, 128, 2, 10); if (Keycheckthread != RT_NULL) rt_thread_startup(Keycheckthread); ``` --- ### 📌 参数说明:`rt_thread_create(name, entry, arg, stack_size, priority, tick)` | 参数 | 含义 | |--------------|------| | `name` | 线程名称(字符串标识) | | `entry` | 线程入口函数(必须是 `void (*)(void *)` 类型) | | `arg` | 传给线程函数的参数(这里用 `RT_NULL` 表示无参数) | | `stack_size` | 栈空间大小(单位:字节)。注意:太小会栈溢出,太大浪费内存 | | `priority` | 优先级(数值越小优先级越高,0 是最高优先级) | | `tick` | 时间片长度(单位:系统节拍 tick),当同优先级多线程时使用 | --- ### ⚠️ 潜在问题与建议 1. **注释掉的 uart 接收线程未启动** ```c // if (uartReceivethread != RT_NULL) // rt_thread_startup(uartReceivethread); ``` - 如果你不打算启用 UART 接收线程,请移除创建代码或加上明确注释。 - 否则这是个遗漏,会导致串口功能不工作。 2. **栈大小设置不合理** - `uartReceivethread`, `getairthread`, `urcMonitorthread`, `Keycheckthread` 都只分配了 `128` 字节栈空间。 - 在某些架构(如 ARM Cortex-M)上,128 字节可能不足,尤其函数调用层次深或局部变量多时会导致 **栈溢出**。 - 建议: - 最小设为 `256` 或 `512` 字节; - 使用 `rt_thread_self()->stack_addr` 和 `rt_thread_stack_info()` 查看是否溢出。 3. **优先级分配需谨慎** - `uartReceivethread`: 优先级 4(较高) - `ConnetCloudthread`: 3(更高) - `getairthread` / `Keycheckthread`: 2(高) - 若 `getairthread` 优先级高于通信线程,可能阻塞关键任务。 - 建议根据实时性需求重新评估优先级,避免优先级反转或饥饿。 4. **线程创建失败处理不足** - 虽然每个都判断了是否为 `RT_NULL`,但没有错误日志输出。 - 建议添加 `rt_kprintf()` 或 `LOG_E()` 输出警告信息。 示例增强版: ```c Keycheckthread = rt_thread_create("Keycheckthread", KeycheckthreadHanld, RT_NULL, 512, 2, 10); if (Keycheckthread != RT_NULL) { rt_thread_startup(Keycheckthread); } else { rt_kprintf("Failed to create Keycheckthread!\n"); } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值