RT-thread是一款嵌入式实时多线程操作系统,rt thread操作系统的基本特点就是支持多任务,值得一提的是,允许多个任务同时进行并不是意味着处理器能够同时处理多个任务。处理器同一时间只能处理一个任务,但处理一个任务的所需的时间非常短,任务和任务之间由任务调度器非常快速的进行切换,才会给人一种过个任务同时进行的假象。RTthreadOS中任务通过线程进行实现,rt thread的线程调度器也就是上面所说的任务调度器。
首先了解了一些关于系统初始化的知识。rtos 通过keil的功能,使用$sub$$ 和$super$$使得该工程具有两个main函数,将rtos系统的初始化和用户代码分割开来,使得系统的初始化内容对于用户代码透明。
并且了解了一些关于堆栈的区别。
1申请方式 栈:一般定义变量均存放在栈空间中,右边一起自动分配和释放。堆: 由用户使用p=(char*)malloc(20)这样的方法自行定义和使用free(p)释放的变量存放于堆空间中。
2.空间大小 栈空间一般用于自动分配较小的空间,而对于较大的空间则需要使用堆空间来进行分配。栈的可用空间较小,堆的可用空间比较大
3.申请效率 栈的申请速度比较慢,堆的申请速度比较快
4.调用速率 栈属于一级缓存,通常被调用都是处于存储空间,调用完毕立即释放。堆是存放在二级缓存,回收通常由用户来完成,调用堆的速度也相对来的较慢
5.数据结构 栈的数据结构是先进后出的。堆的数据结构是一种常用的树形结构,一种特殊的完全二叉树(网上搜集的我也不太了解)当且仅当所有节点的值总是不大于或者不小于其父节点的值的完全二叉树被称之为堆。如果根节点最小叫小顶堆,反之成为大顶堆。
在rtos中,宏定义了&Image$4RW_IRAM1$$ZI$$Limit 作为未使用的RAM的首地址(即除了RAM被RW区和ZI区占用了的空间,剩余空闲空间的首地址),一般用于初始化分配RAM剩余的空间作为动态分配的堆空间来进行使用,动态分配函数如下
rt-system-heap+init(heap_begin,heap_end)
heap_begin=&Image$4RW_IRAM1$$ZI$$Limit
heap_end=0x2000 0000+STM32_SRAM_SIZE*1024
另外,在使用malloc申请完成内存块之后,最好对申请的内存块进行清0操作,以免该空间残余上次使用时的值而非0,使用函数rt_mem_set( p, 0 ,size)来进行清0。
进行也是初学,学习了一些rt thread 的接口,首先rt thread的一切任务都是通过线程进行实现,因此在完成一项任务或者说调用一个功能函数的时候,需要为其创建线程,并将其加入就绪队列开始运行。对于创建线程,RT thread提供了两种方式
1.静态线程创建。顾名思义,该创建线程的方式需要用户对于分配给线程的栈空间,以及线程初始化结构体自行进行定义,并且在rt_err_t rt_thread_init()函数中进行初始化,初始化好了的结构体,将结构体的地址传给 rt_thread_startup(&rt_thread)函数,将该线程挂载在就绪队列进行执行。rt_err_t rt_thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
静态线程初始化的过程如下:
static char thread1_stack[1024];
static struct rt_thread thread1;
rt_thread_init(&thread2,
"thread2",
rt_thread2_entry,
RT_NULL,
&thread2_stack[0],
sizeof(thread2_stack),
THREAD_PRIORITY-1, THREAD_TIMESLICE);
rt_thread_startup(&thread2);
2.动态线程创建。rt thread 操作系统中很多地方都分了动态和静态两种方式,对于动态线程创建,线程结构体和栈空间的分配都由 rt_thread_create()函数来完成,因此只需要定义一个rt_thread_t的变量用于存放 rt_thread_create()的返回值,即线程结构体的首地址。再进行后续的线程startup操作
rt_thread_t rt_thread_create(const char *name,
void (*entry)(void *parameter),
void *parameter,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick)
动态线程初始化的过程如下:
rt_thread_t tid;
tid = rt_thread_create("thread1",
thread_entry, (void*)1,
THREAD_STACK_SIZE,
THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid != RT_NULL)
rt_thread_startup(tid);
rtos的线程状态有 初始,就绪,运行,挂起,终止五种状态,和常规操作系统的进城状态切换基本相似。rt_thread_delay ,rt_thread_mdelay ,rt_thread_sleep 等函数能够使运行态的线程进行挂起,延迟结束后在进入就绪态。可以使用命令行list_thread命令来查看线程对于分配的栈空间的使用情况,一班将线程栈的大小设置为最大使用值MAXsize的70%。