update 说明文档/CosyOS原理与应用.md.

Signed-off-by: 零中断延迟的RTOS <cosyos@139.com>
This commit is contained in:
零中断延迟的RTOS
2024-01-06 17:01:22 +00:00
committed by Gitee
parent 2a53553326
commit a8c029fec0

View File

@@ -121,121 +121,6 @@ CosyOS的任务调度时机分为 **定时调度** 与 **临时调度**。<br>
CosyOS的任务调度策略可最大程度的实现尽可能实时高效的任务切换使CosyOS的实时性更为优异。<br>
### 任务栈模式
CosyOS把任务栈的处理方式称之为任务栈模式共包括三种类型**MSP模式**、**PSP模式**、**MSP+PSP模式**。<br>
* **MSP模式** 任务切换时,先拷贝主栈内容至当前任务栈(保存现场);再拷贝新任务栈内容至主栈(恢复现场)。<br>
* **PSP模式** 每个任务的任务栈都是主栈,哪个任务运行时,哪个任务的任务栈(当前任务栈)就是当前主栈。<br>
* **MSP+PSP模式** 中断时为Handler模式入栈入的是主栈任务时为Thread模式入栈入的是当前任务栈。<br>
对于51来说CosyOS采用了搬栈这一传统方案也就是MSP模式<br>
对于Arm来说CosyOS所采用的方法当然是主流的双栈指针了也就是MSP+PSP模式<br>
对于251来说CosyOS支持MSP模式、PSP模式这两种栈模式供用户选择。<br>
* **PSP模式与MSP+PSP模式的异同** <br>
PSP模式中断入栈也入任务栈相比MSP+PSP模式需要更大的任务栈也就是需要更大的edata内存。<br>
* **MSP模式的优势** <br>
凡事都是辩证的,有一利必有一弊。<br>
MSP模式虽然在任务切换时会保存并恢复现场导致效率较低但只要主栈和内存池足够大就可确保所有任务栈永不溢出。<br>
当然前提是任务栈得是动态的CosyOS将自动启用任务栈重分配机制可有效抵御任务栈溢出的风险。<br>
这一点是PSP模式、MSP+PSP模式所不具备的。PSP模式、MSP+PSP模式一旦任务栈溢出既成事实数据覆盖可能已经发生无法挽回。<br>
* **任务栈重分配机制** <br>
任务栈重分配机制,被设计用来在正式的产品中抵御任务栈溢出的风险。<br>
在概率上,也许测试一年也不会碰到一次任务栈溢出,但大批量产品投入使用后不一定哪天就会溢出。<br>
如果内存足够大问题也好解决但51/251的内存有限既要节约着用还不要栈溢出就得用点策略了。<br>
任务栈重分配机制的意义正在于此。<br>
重点是,任务栈重分配机制是做为一种补救手段,不建议用户过分依赖。<br>
开发调试时,还是要配置够用的任务栈,保证测试阶段不会溢出(不会发生重分配)。<br>
任务栈重分配次数多了会导致内存碎片,如果过分依赖的话,反而会导致内存更加不够用。<br>
任务栈重分配机制,就是为了当万一哪一天任务栈溢出了呢?能够满血复活。<br>
* **任务栈重分配机制的启用条件** <br>
1、对于8051当任务创建模式非静态创建时CosyOS将自动启用任务栈重分配机制。<br>
2、对于80251当任务栈模式为MSP模式、任务创建模式非静态创建时CosyOS将自动启用任务栈重分配机制。<br>
### 任务管理器
可在系统配置文件中配置任务管理器的相关选项。<br>
可使用超级终端或串口调试助手,作为任务管理器的输出窗口。<br>
![任务管理器](../images/taskmgr.png "任务管理器")<br>
—————————— CosyOS-任务管理器 ——————————
* **Name**:任务名称 <br>
* **TID**任务ID <br>
* **PRI**:任务优先级 <br>
* **STA**:任务状态 <br>
* **CPU**CPU使用率 <br>
* **RAM**:任务栈大小(字节数),下面进行详细说明:<br>
32B/s64B系统采用每调度监控计算出的在概率上必然存在的最大任务栈占用为32Bytes任务栈已 **静态创建** 了64Bytes。<br>
32B/m64B系统采用每调度监控计算出的在概率上必然存在的最大任务栈占用为32Bytes任务栈已 **malloc** 分配了64Bytes。<br>
32B/r40B系统采用每调度监控计算出的在概率上必然存在的最大任务栈占用为32Bytes任务栈已 **realloc** 分配了40Bytes。<br>
**每调度监控:** <br>
每次任务调度时都会监控,并假定本次会切换任务、需要现场保护,计算当前任务需要多大的任务栈。<br>
这种假定在概率上必然早晚都会发生,但不一定是什么时候(也许是即将发生、也许是一万年以后、也许是时间的尽头),从而提前预判任务栈溢出的风险。<br>
**每调度监控应用技巧:** <br>
任务调度包括定时调度与临时调度,对于定时调度来说,就是系统滴答中断触发的,所以,用户在开发测试阶段可适当定义一个较小的 **系统滴答周期**,可提升“每调度监控”提前预判任务栈溢出风险的机率。<br>
**任务栈调整:** <br>
1、当任务栈重分配发生时就需要重新调整任务栈的size了。<br>
32B/r40B此时就需要重新调整任务栈的大小为至少32个字节。<br>
当这种情况发生时还会有相应的报警提示用户rts任务栈重分配发生虽然成功了但仍要提醒用户任务栈定义小了。<br>
2、当 “前面的字节数” 大于 “后面的字节数” 时就需要重新调整任务栈的size了。<br>
56B/m32B此时就需要重新调整任务栈的大小为至少56个字节。<br>
当这种情况发生时还会有相应的报警提示用户ots在概率上、在未来必然会发生的任务栈溢出虽然现在可能并未发生。<br>
**任务栈初定义:** <br>
1、对于51及251的MSP模式当任务创建模式非静态创建时任务栈的初始定义可以小因为有重分配机制而后根据监控及报警情况再增大。<br>
2、对于251的PSP模式及Arm的MSP+PSP模式任务栈的初始定义一定要够大否则可能会运行不起来或死机而后再根据测试情况重新调整任务栈。<br>
3、对于251的PSP模式由于中断入栈也入任务栈所以需要用户自己根据中断的使用情况来计算一个中断嵌套入栈的最大size不必包括最低优先级的中断入栈累加到“前面的字节数”中看是否会大于 “后面的字节数”,再行调整。<br>
**任务栈重定义(任务栈补偿):** <br>
1、在开发测试阶段用户应尽量设法模拟各种情况的发生最好是频繁发生包括中断的发生。只要你的产品支持的功能、情况都要设法模拟到。<br>
2、通过足够时间的测试统计出各任务在任务管理器当中的“RAM”项中系统采用每调度监控假定入栈计算出的在概率上必然存在的最大任务栈占用而后在此值的基础上再累加一个补偿增量再重新定义任务栈size。<br>
示例经过长期的测试以后某任务的任务栈为56B/m64B可重新定义任务栈的size为56 + XX为补偿增量。<br>
原因是无论 每调度监控 如何的假定入栈,也可能会存在着更大的任务栈需求,只是未能测试到,所以必须增加一定的补偿。<br>
而这个补偿量的大小,每个任务都可根据剩余内存的大小而灵活配置,最好能尽量大一些,尤其是对于没有任务栈重分配机制的情况来说。<br>
没有任务栈重分配机制的情况:<br>
1、任务创建模式为静态创建<br>
2、251的PSP模式<br>
3、ARM。<br>
这个补偿增量对于51来说可描述为2的整数倍2 x NN为每调度监控未能监测到的N次的函数嵌套调用。<br>
对于251、ARM来说则无法描述。<br>
**每调度监控的启用条件:** <br>
CosyOS启用“每调度监控”的充分必要条件是启用任务管理器即系统配置中“DEBUG接口设置”必须打勾。<br>
* **PSVFIFO**中断挂起服务缓存PendSV_FIFO的深度如果您已开启PendSV_FIFO监控会显示此项历史最大值/设置值。<br>
* **Task-PC**任务PC监控如果您已开启任务PC监控会显示此项。<br>
当任务管理器被调度运行时上一个被切换的任务入栈的PC值。<br>
当有任务出现代码运行卡死或死循环时此功能可用来帮助用户锁定具体位置以便查找BUG。注意PC值为下一条汇编指令的地址。<br>
某任务出现代码运行卡死或死循环的表现任务始终为就绪状态且占用较高的CPU使用率比它优先级低的任务一直都没有机会运行。<br>
* **SysTick**:系统滴答时间统计,如果您已开启系统滴答时间统计,会显示此项。<br>
注意:系统滴答时间是系统滴答中断运行的平均时间,并非是任务切换时间。
* **Alarm**:报警信息,如果有报警,会显示此项。<br>
omq消息队列溢出。<br>
otq任务队列溢出<br>
osr安全运行时超时。<br>
otp任务优先级超出范围。<br>
rts任务栈重分配发生虽然成功了但仍要提醒用户任务栈定义小了。<br>
任务栈重分配机制被设计用来在正式的产品中抵御任务栈溢出的风险,用户在开发测试阶段应避免这种情况的发生。<br>
ots在概率上、在未来必然会发生的任务栈溢出虽然现在可能并未发生。<br>
* **Fault**:故障信息,如果有故障,会显示此项。<br>
mmn消息节点内存分配失败<br>
mtn任务节点内存分配失败<br>
mts任务栈内存分配失败<br>
rts任务栈内存重分配失败<br>
ots任务栈溢出<br>
fst启动任务失败<br>
erm中断中接收消息错误中断中不可接收来自动态消息队列的消息。<br>
opd中断挂起服务缓存溢出。<br>
* **任务管理器相关命令** <br>
1、taskmgr启动任务管理器。<br>
2、exit退出任务管理器。<br>
3、taskmgr /s=...,任务管理器更新速度,取值范围:[50~5000]ms。<br>
注意:命令仅支持小写字母,结尾必须加回车换行(\r\n。<br>
## 第二章、中断篇
### 什么是零中断延迟?
@@ -463,6 +348,124 @@ CosyOS则分为两种情况<br>
调试任务 Debugger为定时中断任务\System\debug.c<br>
调试钩子 debug_hook为定时查询钩子\System\debug.c。<br>
## 第七章、任务管理器
可在系统配置文件中配置任务管理器的相关选项。<br>
可使用超级终端或串口调试助手,作为任务管理器的输出窗口。<br>
![任务管理器](../images/taskmgr.png "任务管理器")<br>
—————————— CosyOS-任务管理器 ——————————
* **Name**:任务名称 <br>
* **TID**任务ID <br>
* **PRI**:任务优先级 <br>
* **STA**:任务状态 <br>
* **CPU**CPU使用率 <br>
* **RAM**:任务栈大小(字节数),下面进行详细说明:<br>
32B/s64B系统采用每调度监控计算出的在概率上必然存在的最大任务栈占用为32Bytes任务栈已 **静态创建** 了64Bytes。<br>
32B/m64B系统采用每调度监控计算出的在概率上必然存在的最大任务栈占用为32Bytes任务栈已 **malloc** 分配了64Bytes。<br>
32B/r40B系统采用每调度监控计算出的在概率上必然存在的最大任务栈占用为32Bytes任务栈已 **realloc** 分配了40Bytes。<br>
**每调度监控:** <br>
每次任务调度时都会监控,并假定本次会切换任务、需要现场保护,计算当前任务需要多大的任务栈。<br>
这种假定在概率上必然早晚都会发生,但不一定是什么时候(也许是即将发生、也许是一万年以后、也许是时间的尽头),从而提前预判任务栈溢出的风险。<br>
**每调度监控应用技巧:** <br>
任务调度包括定时调度与临时调度,对于定时调度来说,就是系统滴答中断触发的,所以,用户在开发测试阶段可适当定义一个较小的 **系统滴答周期**,可提升“每调度监控”提前预判任务栈溢出风险的机率。<br>
**任务栈调整:** <br>
1、当任务栈重分配发生时就需要重新调整任务栈的size了。<br>
32B/r40B此时就需要重新调整任务栈的大小为至少32个字节。<br>
当这种情况发生时还会有相应的报警提示用户rts任务栈重分配发生虽然成功了但仍要提醒用户任务栈定义小了。<br>
2、当 “前面的字节数” 大于 “后面的字节数” 时就需要重新调整任务栈的size了。<br>
56B/m32B此时就需要重新调整任务栈的大小为至少56个字节。<br>
当这种情况发生时还会有相应的报警提示用户ots在概率上、在未来必然会发生的任务栈溢出虽然现在可能并未发生。<br>
**任务栈初定义:** <br>
1、对于51及251的MSP模式当任务创建模式非静态创建时任务栈的初始定义可以小因为有重分配机制而后根据监控及报警情况再增大。<br>
2、对于251的PSP模式及Arm的MSP+PSP模式任务栈的初始定义一定要够大否则可能会运行不起来或死机而后再根据测试情况重新调整任务栈。<br>
3、对于251的PSP模式由于中断入栈也入任务栈所以需要用户自己根据中断的使用情况来计算一个中断嵌套入栈的最大size不必包括最低优先级的中断入栈累加到“前面的字节数”中看是否会大于 “后面的字节数”,再行调整。<br>
**任务栈重定义(任务栈补偿):** <br>
1、在开发测试阶段用户应尽量设法模拟各种情况的发生最好是频繁发生包括中断的发生。只要你的产品支持的功能、情况都要设法模拟到。<br>
2、通过足够时间的测试统计出各任务在任务管理器当中的“RAM”项中系统采用每调度监控假定入栈计算出的在概率上必然存在的最大任务栈占用而后在此值的基础上再累加一个补偿增量再重新定义任务栈size。<br>
示例经过长期的测试以后某任务的任务栈为56B/m64B可重新定义任务栈的size为56 + XX为补偿增量。<br>
原因是无论 每调度监控 如何的假定入栈,也可能会存在着更大的任务栈需求,只是未能测试到,所以必须增加一定的补偿。<br>
而这个补偿量的大小,每个任务都可根据剩余内存的大小而灵活配置,最好能尽量大一些,尤其是对于没有任务栈重分配机制的情况来说。<br>
没有任务栈重分配机制的情况:<br>
1、任务创建模式为静态创建<br>
2、251的PSP模式<br>
3、ARM。<br>
这个补偿增量对于51来说可描述为2的整数倍2 x NN为每调度监控未能监测到的N次的函数嵌套调用。<br>
对于251、ARM来说则无法描述。<br>
**每调度监控的启用条件:** <br>
CosyOS启用“每调度监控”的充分必要条件是启用任务管理器即系统配置中“DEBUG接口设置”必须打勾。<br>
* **PSVFIFO**中断挂起服务缓存PendSV_FIFO的深度如果您已开启PendSV_FIFO监控会显示此项历史最大值/设置值。<br>
* **Task-PC**任务PC监控如果您已开启任务PC监控会显示此项。<br>
当任务管理器被调度运行时上一个被切换的任务入栈的PC值。<br>
当有任务出现代码运行卡死或死循环时此功能可用来帮助用户锁定具体位置以便查找BUG。注意PC值为下一条汇编指令的地址。<br>
某任务出现代码运行卡死或死循环的表现任务始终为就绪状态且占用较高的CPU使用率比它优先级低的任务一直都没有机会运行。<br>
* **SysTick**:系统滴答时间统计,如果您已开启系统滴答时间统计,会显示此项。<br>
注意:系统滴答时间是系统滴答中断运行的平均时间,并非是任务切换时间。
* **Alarm**:报警信息,如果有报警,会显示此项。<br>
omq消息队列溢出。<br>
otq任务队列溢出<br>
osr安全运行时超时。<br>
otp任务优先级超出范围。<br>
rts任务栈重分配发生虽然成功了但仍要提醒用户任务栈定义小了。<br>
任务栈重分配机制被设计用来在正式的产品中抵御任务栈溢出的风险,用户在开发测试阶段应避免这种情况的发生。<br>
ots在概率上、在未来必然会发生的任务栈溢出虽然现在可能并未发生。<br>
* **Fault**:故障信息,如果有故障,会显示此项。<br>
mmn消息节点内存分配失败<br>
mtn任务节点内存分配失败<br>
mts任务栈内存分配失败<br>
rts任务栈内存重分配失败<br>
ots任务栈溢出<br>
fst启动任务失败<br>
erm中断中接收消息错误中断中不可接收来自动态消息队列的消息。<br>
opd中断挂起服务缓存溢出。<br>
* **任务管理器相关命令** <br>
1、taskmgr启动任务管理器。<br>
2、exit退出任务管理器。<br>
3、taskmgr /s=...,任务管理器更新速度,取值范围:[50~5000]ms。<br>
注意:命令仅支持小写字母,结尾必须加回车换行(\r\n。<br>
## 第八章、任务栈
### 任务栈模式
CosyOS把任务栈的处理方式称之为任务栈模式共包括三种类型**MSP模式**、**PSP模式**、**MSP+PSP模式**。<br>
* **MSP模式** 任务切换时,先拷贝主栈内容至当前任务栈(保存现场);再拷贝新任务栈内容至主栈(恢复现场)。<br>
* **PSP模式** 每个任务的任务栈都是主栈,哪个任务运行时,哪个任务的任务栈(当前任务栈)就是当前主栈。<br>
* **MSP+PSP模式** 中断时为Handler模式入栈入的是主栈任务时为Thread模式入栈入的是当前任务栈。<br>
对于51来说CosyOS采用了搬栈这一传统方案也就是MSP模式<br>
对于Arm来说CosyOS所采用的方法当然是主流的双栈指针了也就是MSP+PSP模式<br>
对于251来说CosyOS支持MSP模式、PSP模式这两种栈模式供用户选择。<br>
* **PSP模式与MSP+PSP模式的异同** <br>
PSP模式中断入栈也入任务栈相比MSP+PSP模式需要更大的任务栈也就是需要更大的edata内存。<br>
* **MSP模式的优势** <br>
凡事都是辩证的,有一利必有一弊。<br>
MSP模式虽然在任务切换时会保存并恢复现场导致效率较低但只要主栈和内存池足够大就可确保所有任务栈永不溢出。<br>
当然前提是任务栈得是动态的CosyOS将自动启用任务栈重分配机制可有效抵御任务栈溢出的风险。<br>
这一点是PSP模式、MSP+PSP模式所不具备的。PSP模式、MSP+PSP模式一旦任务栈溢出既成事实数据覆盖可能已经发生无法挽回。<br>
* **任务栈重分配机制** <br>
任务栈重分配机制,被设计用来在正式的产品中抵御任务栈溢出的风险。<br>
在概率上,也许测试一年也不会碰到一次任务栈溢出,但大批量产品投入使用后不一定哪天就会溢出。<br>
如果内存足够大问题也好解决但51/251的内存有限既要节约着用还不要栈溢出就得用点策略了。<br>
任务栈重分配机制的意义正在于此。<br>
重点是,任务栈重分配机制是做为一种补救手段,不建议用户过分依赖。<br>
开发调试时,还是要配置够用的任务栈,保证测试阶段不会溢出(不会发生重分配)。<br>
任务栈重分配次数多了会导致内存碎片,如果过分依赖的话,反而会导致内存更加不够用。<br>
任务栈重分配机制,就是为了当万一哪一天任务栈溢出了呢?能够满血复活。<br>
* **任务栈重分配机制的启用条件** <br>
1、对于8051当任务创建模式非静态创建时CosyOS将自动启用任务栈重分配机制。<br>
2、对于80251当任务栈模式为MSP模式、任务创建模式非静态创建时CosyOS将自动启用任务栈重分配机制。<br>
## 附 录、调用服务注意事项
### CosyOS-II 在临界区中或关闭总中断时调用服务注意事项