- 打卡等级:初来乍到
- 打卡总天数:5
- 最近打卡:2025-04-30 07:46:22
荣誉版主
- 积分
- 2319
|
发表于 2023-11-16 14:12:20
|
显示全部楼层
本帖最后由 tzz1983 于 2023-11-17 16:27 编辑
最新版本V1.05 已实现中断专用栈MSP+任务栈PSP模式. 大幅节省RAM使用量
代码已在1楼更新
251内核实现中断专用栈MSP介绍
实现原理: 首次进入中断时,如果当前是PSP,则保存PSP指针,并切换至MSP,退出中断时操作相反. 嵌套中断时,已使用MSP,不必切换栈.
性能提升:STC32G12K128 内含4K EDATA, 植入UCOSII后, 去掉1500字节左右固定开销外, 实际剩下2500字节可用.
在没有MSP功能前, 中断发生在哪个任务, 即沿用哪个任务的堆栈. 实际上中断用栈量很大. 举例说明: 如果中断内调用函数, 就是寄存器全入栈, 大约38字节, 4个优先级最多嵌套3次 38*3=114字节.
使用MSP(中断专用堆栈)后, 每个任务可节省 114字节, 假设8个任务+2个系统任务(空闲, 统计), 则节省114*10=1140字节, 这都差不多是2500总数的一半了, 说性能翻倍也不过份.
安全性提升: 不用再担心中断优先级设置变更后影响全局任务栈, 现在中断和任务, 任务和任务之间都做到了有效的隔离
如何使用:
每个中断可以单独设置是否使用MSP功能, 在头文件"os_isr_251.h"中用宏来开启. 如果设置了对应的宏, 则在"os_isr_251.c"中创建对应的中断汇编封皮函数
封皮函数已包含"堆栈切换" "OSIntNesting++" "OSIntExit()"功能, 剩下的事情,用户只需要在勾子函数中添加自己的中断代码即可. 实际用起来更简单了.
没有开启MSP功能的中断, 采取沿用的方式, 即当中断发生时, 不管当前是MSP还是PSP, 都沿用.
如果所有中断都不开启MSP功能, 则不会创建MAP_STK(中断专用堆栈). 用法不变, 仍是用关键字interrupt创建中断函数, 也就是说MSP功能是可选的. 兼容之前的用法
定时器3中断应用举例:
用法1. 中断使用MSP:
使能宏OS_ISR19_USE_MSP_EN 1u. 中断代码放在勾子函数中, 适用于有函数调用的中断代码.
说明; 使能宏"OS_ISR19_USE_MSP_EN"以后, 不要再用关键字 interrupt 创建中断函数Timer3_Handler(), 这个函数已在"os_isr_251.c"创建了.
void Timer3_ISR_Handler_Hook (void)
{
P27 = ~P27; //中断代码
abc(); //中断代码
}
用法2. 快速中断方式:
不使能宏OS_ISR19_USE_MSP_EN 0u. 适用于中断代码没有使用函数调用时(包括自编函数和OS服务函数). 利用编绎器智能减少寄存器入栈数量, 这样的中断没有多余的动作,效率是最高的.
void Timer3_ISR_Handler() interrupt 19
{
//利用编绎器智能减少寄存器入栈数量, 这样的中断没有多余的动作,效率是最高的. (前提是没有函数调用)
//不用OS服务时可以不用 OSIntNesting++;
P27 = ~P27; //中断代码
//同时也不需要 OSIntExit();
}
|
|