目录
5.RT-Thread运行逻辑与裸机开发运行逻辑(Mermaid实现系统框图,附代码块)
2.RT-Thread中,线程由三部分组成:线程代码(入口函数)、线程控制块、线程堆栈
前言
之前听过有关RT-Thread,RTOS的一些操作系统的内容,但都没有去深入了解,本次借由开放原子训练营希望能够对RT-thread 有一些了解,便于之后相关的开发工作。
一、初识RT-Thread
1.嵌入式系统
-
嵌入式系统是一种完全嵌入在装置或设备内部、为满足特定需求而设计的计算机系统,譬如生活中常见的嵌入式系统就有:电视机顶盒、路由器、电冰箱、微波炉与移动电话等等。
-
嵌入式操作系统是应用于嵌入式系统的软件,它用来对接嵌入式底层硬件与上层应用。
-
嵌入武操作系统在多任务管理、任务间通信、内存管理、定时器管理、设备管理等方面,提供给了用户一套完整的机制,极大程度上便利了嵌入式应用程序的开发,管理和维护。
2. RT-Thread发展历程
- RT-Thread诞生于2006年,经过十多年的积淀,RT-Thread已经 成为一款知名度较高、口碑极佳、高度稳定可靠的实时操作系统;
- RT-Thread以开源、免费的方式进行发布,许可证类似FreeRTOS;
- RT-Thread作为一款国产嵌入式操作系统,与其他RTOS (FreeRTOS、uC/OS)的主要区别是:
- RT-Thread自创建之初的定位就不仅是一个RTOS内核,而是包含网络、文件系统、GUI界面等组件的中间件平台,具有极强的扩展性!
- RT-Thread支持市面所有的主流编译工具,如IAR、GCC、Keil等;
- 在硬件支持方面,它完成了在超过50款MCU芯片上和所有主流CPU架构上的移植工作;
- 因为RT-Thread的高可靠性和组件丰富等特点,它被广泛应用于安防、医疗、新能源、车载、导航以及消费电子等众多行业;
3.示例代码结构 (3.1版本内核)
1)工程源码结构
applications | 用户应用 |
---|---|
driver | RT-Thread内核 |
kernel-sample | 内核例程 |
Libraries | STM32固件库 |
rt-thread | RT-thread源码 |
2)RT-Thread源码结构
src | RT-Thread内核代码文件 |
---|---|
libcpu | 各类芯片/内核移植代码 |
include | RT-Thread内核头文件 |
components | RT-Thread外部组件代码 |
dirvers | 设备驱动 |
finsh | RT-Thread命令行 |
3)Keil工程源码结构
Applicaations | 用户代码 |
---|---|
Driver | 存放RT-Thread底层的驱动代码 |
STM32_HAL | STM32的固件库 |
Kernel | RT-Thread内核核心代码 |
COREX-M3 | ARM Coreax-M3移植代码 |
DeviceDrivers | RT-Thread驱动框架源码 |
finsh | RT-Thread命令行finsh命令行组件 |
kernel-sample | RT-Thread的内核例程 |
4.工程测试
1)在调试运行代码后会出现如下效果
\|/
-RT-Thread Operating System
/|\ 3.1.0 bu11d Apr 10 2023
2006 -2018 Copyright by rt-thread team
msh>
2)键入help,或者直接按tab即可得到
RT-Thread shell commands:
led -RT-Thread first led sample
version -show RT-Thread version information
list thread -list thread
list sem -list semaphore in system
list event -list event in system
list mutex -list mutex in system
list mailbox -list mail box in system
list msgqueue -list message queue in system
list memheap -list memory heap in system
list mempool -list memory pool in system
list timer -list timer in system
list device -list device in system
help -RT-Thread shell help.
ps -List threads in the system.
time -Execute command with time.
free -Show the memory usage in the system.
dynmem sample -dynmem sample
event sample -event sample
idle hook sample -idle hook sample
interrupt sample -interrupt sample
mailbox sample-mailbox sample
mempool sample-mempool sample
msga sample-msga sample
mutex sample-mutex sample
pri inversion-pri inversion sample
producer consumer -producer consumer sample
scheduler hook-scheduler hook sample
semaphore sample -semaphore sample
signal sample-signal sample
thread sample-thread sample
timer samp1e -timer sample
timeslice sampletimeslice sample
5.RT-Thread运行逻辑与裸机开发运行逻辑(Mermaid实现系统框图,附代码块)
flowchart TB
subgraph 裸机代码运行逻辑
direction TB
A([systemInit])-->B[用户主程序]
end
subgraph RT-Thread运行逻辑
direction TB
C([systemInit])-->D[$Sub$$main]
D-->E[rtthread_startup]
E-->F([rt_application_init])
F--调用参数-->G(main_thread_entry)
G--调用main.c-->H($$Super$$main用户主函数)
end
二、线程的创建
1.堆与栈
栈(stack):由编译器自动分配释放
堆(heap):一般由程序员分配和释放
2.RTT的动态内存分配
Stack_size
Heap_size
1)分配动态内存
提取部分RAM空间用作动态内存
rt_system_heap_init((void *)HEAP_BEGIN,(void *)HEAP_END)
2)rt_malloc 内存分配
ptr =RT_NULL(分配失败)
rt_free() 内存释放
//内存复位
P=rt_malloc(10)
if(P !=RT_NULL)
{
rt_memset(P,0,10);//内存块清零
}
//内存泄漏
rt_malloc();
rt_free();//配套使用
void*rt_realloc(void *rmem,rt_size_t newsize);
//对已分配块的基础上重新分配内存块的大小,保持原有数据不变
//缩小的情况下(后边的数据自动截断)
void *rt_calloc(rt_size_t count,rt_size_t size);
//从内存堆中分配连续地址的多个内存块
三、线程的创建
1.R-Thread名为实时线程RTOS,那么什么叫线程?
- 人们在生活中处理复杂问题时,惯用的方法就是“分而治之”,即把一个大问题分解成多个相对简单、比较容易解决的小问题,小问题逐个被解决了,大问题也就随之解决了。
- 同样,在设计一个较为复杂的应用程序时,也通常把一个太型任务分解成多个小任务,然后通过运行这些小在务,最终达到完成大任务的目的。
- 在RT-Thread中,与上述小任务对应的程序实体就叫做“线程”(或任务) RT-Thread就是一个能对这些小“线程”进行管理和调度的多“线程”操作系统。
- 线程是实现任务的载体,它是RT-Thread中最基本的调度单位,它描述了一个任务执行的运行环境,也描述了这个任务所处的优先等级。
2.RT-Thread中,线程由三部分组成:
线程代码(入口函数)、线程控制块、线程堆栈
1)无限循环结构
void thread entry(void *parameter)
{
while(1)
{
/*等待事件的发生*/
/*处理事件*/
}
}
2)顺序执行结构
void thread_entry(void *parameter)
{
/*事务1处理*/
/*事务2处理*/
/*事务N处理*/
}
3)线程控制块
- 线程控制块是操作系统用于管理线程的一个数据结构,它会存放线程的一些信息,
- 例如优先级、线程名称、线程状态等,也包线程与线程之间连接用的链表结构,线程等待事件集合等。
4)线程栈
- RT-Thread每个线程都具有独立的栈空间,当进行线程切换时,系统会将当前线程的上下文保存在线程栈中,当线程要恢复运行时,再从线程栈中读取上下文信息,恢复线程的运行。
- 线程上下文是指线程执行时的环境,具体来说就是各个变量和数据包括所有寄存器变量、堆栈信息、内存信息等。
- 线程栈在形式上是一段连续的内存空间,我们可以通过定义一个数组或者申请一段动态内存来作为线程的栈。
- 创建静态线程
rt_err_t rt_thread_init(struct rt_thread *thread,//线程控制块
const char *name,//线程控制块名称
void (*entry)(void *parameter),//指针指向线程控制块代码
void *parameter,//向线程控制块中传入的参数,若无参数则可以设置为0
void *stack start,//线程栈空间的起始地址
rt_uint32_t stack_size,//栈空间大小
rt_uint8_t priority,//设置优先级大小
rt_uint32_t tick)//线程的时间片参数
- 创建动态线程
rt_thread_t rt_thread_create(const char *name,//线程名称
void (*entry)(void *parameter),//线程入口
void *parameter,//向线程控制块中传入的参数,若无参数则可以设置为0
rt_uint32_t stack_size,栈空间大小
rt_uint8_t priority,//设置优先级大小
rt_uint32_t tick)//线程的时间片参数
- 启动线程
rt_err_t rt_thread_startup(rt_thread_t thread)
调用此函数后创建的线程会被加入到线程的就绪列表,执行调度
-
静态线程与动态线程
-
静态线程需要静态先定义
-
动态线程自动分配
-