RTT之内存管理及异常中断
内存管理分静态内存管理和动态内存管理(根据大小又分2种)
静态内存管理:创建、删除、初始化、解绑、申请和释放。初始化内存池是属于静态内存管理,与创建内存池不同的是,此处内存池对象所使用的内存空间是由用户指定的一个缓冲区空间,用户把缓冲区的指针传递给内存池对象控制块,其余的初始化工作与创建内存池相同。
动态内存:在堆heap上分配。
小堆内存管理模块主要针对系统资源比较少(小于2M内存空间的系统):内存池中有不同的内存块,申请时先查找找到符合要求的(拆分),释放时如果紧邻的空闲则合并成一个。
而SLAB内存管理模块则主要是在系统资源比较丰富时。这两种管理模块提供的API接口完全相同。分配、重新调整分配、释放,以及分配和释放的钩子函数。
警告:因为动态内存管理器要满足多线程情况下的安全分配,会考虑多线程间的互斥问题,所以请不要在中断服务例程中分配或释放动态内存块。因为它可能会引起当前上下文被挂起等待。
RTT对中断管理:专门为中断设置中断栈空间,在进入和退出时实现切换。中断的前半段(取得数据和状态并给线程同步信息)和后半段(线程对数据的进一步处理)
相关的中断操作函数:中断挂载、某个中断源的屏蔽和解开屏蔽,总中断的打开和关闭,此外进入和退出中断有专门的2个函数提示系统进入和退出了中断:
void rt_interrupt_enter(void);//如果中断服务程序不会调用内核相关的函数(释放信号量等操作)则不调用;否则调用的作用是 void rt_interrupt_leave(void);//推出时告诉内核该采取中断中线程切换的策略,而不是立即进行切换
rt_uint8_t rt_interrupt_get_nest(void)//是否发生了中断嵌套。
ARM Cortex-M系列处理器在从线程发生中断或者在中断时发生更高级级别的中断嵌套,PSR R0~R3,R12的现场保护都是由硬件自动完成的。每个中断都直接有一个确定的入口而不像ARM7/9先从统一的入口进去后在查找具体中断口。
中断方式还是轮询:比如串口发送,如果每次发送的量比较少(或波特率很高)此时轮询效率最高,中断时因为有任务切换开销效率不高,在OS下用中断方式要么将每次发送的数据量尽可能大,线程的优先级设置为最低(防止一直运行其它低优先级线程得不到运行机会)
一般在中断中发送信号量或者消息队列给线程。线程收到信号量或消息队列时进行处理。
中断处理:
中断的栈采用独立于线程栈的方式,和主堆栈MSP(第一个线程或中断、异常时用)、线程栈LSP(线程切换时)对应。
低半步处理:中断应该短小精悍,在获得必要的异步硬件信号之后通过信号量、邮箱、队列等形式通知等待的线程做后半段处理、
RT-Thread 中断管理接口
如果中断服务程序不会调用内核相关的函数(释放信号量等操作),这个时候,也可以不调用 rt_interrupt_enter/leave() 函数
轮询还是中断:
1 优先中断:对于DMA/FIFI,存在高低速度问题时采用中断模式;
2轮询模式:但当数据传输速度非常快,传输数据量非常小时应采用轮询方式,(不然协通切换损耗比较大),但为了避免轮询导致长时间其它线程得不到运行,可以考虑将本线程的优先级降低一些。