在最近几天,跟着B站上的RT_thread官方教程把RT_Thread的基础教程给看完了。对于RT_thread的学习也告一段落了,
接着总结有关RTT的内容。
优先级:在RTT中最大优先级为256级,而在STM32操作系统中一般设置对大优先级为32级。高优先级率先占用CPU,同等优先级的线程按照时间片的长短轮流占用CPU。
钩子函数:RTT中的钩子函数分为空闲钩子函数程调度钩子函数。分别通过rt_thread_idle_sethook()函数和tr_scheduler_sethook()函数进行设定,其中空闲钩子函数的参数是一个函数,意味着在CPU没有线程执行的时候对于该空闲函数进行循环执行。线程调度钩子函数的参数也是一个函数,但是该函数需要有两个形参 为两个进程控制块的指针,用于在这两个线程间切换时进行调度。
保护临界区,使用rt_enter_critical()函数和rt_exit_critical()函数关闭和开启进程调度,防止在对于变量进行赋值的过程中被中断函数打断。相同rt_hw_interrupt_disable()和rt_hw_interrupt_enable()分别为关闭和开启系统中断。
信号量:信号量一般用于进行同步通讯。两个信号量full设置为0和empty设置为临界资源数量。占用临界资源时需要用rt_sem_take()函数对于信号量的value值做减1操作。在归还信号量时需要调用rt_sem_release()函数。
与信号量相似,互斥量mutex用于保证互斥量每次只能被一个线程所访问,在访问互斥资源之前需要rt_mutex_take操作,并在访问互斥资源结束之后rt_mutex_release操作。值得注意的是,对于信号量的使用,有可能导致优先级反转的问题,而互斥量不会发生优先级反转的问题,低优先级的优先级会提升到等待访问该互斥资源的最高优先级的进程的优先级等级,释放完互斥资源之后优先级恢复初始化的等级。且不像semaphore信号量,对于信号量的release操作可以在中断函数中完成,而对于mutex互斥量,只有take到的线程才能对互斥量做release操作。
事件集:event,事件集可以当作多个信号量,当一个进程的进行需要同时两个不同进程的完成,或者需要两个不同的临街资源的时候,可以使用事件集。事件集的原理和信号量的原理相同,一个事件集中可以有32个事件(由于RTT操作系统为32位操作系统,指针一般都是32位)。线程1可以发送事件集中多个事件集的|或操作,同样,进程2可以拿走事件集中的一个或多个事件,并清除该事件集中被拿走的事件。
邮箱:互斥量,信号量,事件集都只能传送一个信号,进行线程间通信,而不能进行数据交换。一封邮件固定为4个字节的内容,对于32位处理系统,一个指针的大小即为4字节。线程可以使用send函数把4字节的邮件发送到邮箱里,其他线程可以从邮箱的链表头来接受这些邮件进行处理。
消息队列:用来接收线程和中断服务程序中发出的不固定长度的消息。并把消息缓存在自己的内存空间中。其他线程能从消息队列中读取相应的消息进行对应的处理。消息列表有空闲列表,消息链表头,消息链表尾。从空闲列表中取出空间写入数据后存放于消息列表尾。RTT消息队列支持金鸡消息,urgent不同于send,是直接把写入的消息框放在消息链表头第一个被取走。消息队列的最小消息框为4B,可以是4字节的倍数,在计算空间时,总占用空间 = n*(消息框大小+4B) 这个 4B指的是指针的大小,每个消息框会有一个指针
软件定时器:软件定时器在硬件定时器的基础上进行定时,时间到了之后对调用用户设置的timeout回调函数。定时器分为hardtimer和softtimer模式,硬件定时器的超时函数在中断上下文中执行,要求快进快出,hardtimer为默认模式。sfottimer的超时函数在系统的timer线程的上下文中进行,通过宏定义RT_USING_TIMER_SOFT来决定是否使用该模式。开启SFOTTIMER模式之后,需要在定时器初始化中指定一下该模式才能开启该模式。 flag有 one shut ,超时函数只运行一次,。periodic 定时事件到达后周期性的调用超时函数,hardtimer工作在hard模式下, softtimer同。
内存池:内存池和动态内存堆都是内存管理。内存对可以分配任意大小的内存块,但是分配效率不高,内次都要进行空闲内存的查找,且容易产生内存碎片。内存池用来分配大量大小相同的小内存块。使用内存池可以极大的加快动态内存的分配和释放的速度,且尽可能避免内存的碎片化。RTT的内存池支持挂起,没有空闲内存块时,申请内存的线程会被挂起,因此内存池非常适合用于内存资源同步的情景。对于内存池的使用和堆的使用相似,都需要alloc和free进行申请和释放。每个小内存块的大小最小为4个字节,且以4字节为计数单位。在计算空间时,总占用空间 = n*(消息框大小+4B) 这个 4B指的是指针的大小,每个小内存块会有一个指针。
另外,今天学习到了一些关于C语言指针的内容,算是唤醒了一些早前学习C语言的记忆.
一级指针:int * p定义了可以指向int类型数据的指针变量,占4个字节,p所存放的地址指向的是值, 一级指针指向的是值存放的地址
二级指针:int **p定义了一个指针*p,p所存放的地址是值的地址,及p所存放的地址是一个指向int类型变量的指针。 二级指针指向的是指针存放的 地址
一级指针能通过形参修改实参中指针所指向地址的值
二级指针能修改实参中指针所指向的地址
指针数组: int* p[3] 一共有 三个int类型指针 的数组
数组指针:int (*p) [2] 表明该指针指向了一个数组。
野指针是指指向不存在存储空间的指针,在定义指针的时候记得的初始化