嵌入式、C语言、autosar、OS、BSW
项目 | Value |
---|---|
OS | autosar OS |
autosar厂商 | vector ,ETAS |
芯片厂商 | TI |
编程语言 | C,C++ |
编译器 | HighTec (GCC) |
??为了节约RAM 的使用,TASK间可以共享使用stack,但是要满足以下条件:
1.task 类型必须为basic task。
2.task 的优先级必须相同。
3.task必须配置为非抢占式的且勾选上OsTaskStackSharing
4.task不能调用OS service Schedule()。
5.共享stack 的task必须在同一个核内。
??vector 工具链中,一般每个task单独使用一个stack。在task 从run进入ready或者waiting的时候,任务的等待事件栈上下文,包括操作系统上下文,本地数据,函数调用的堆栈帧等,被保存到内部操作系统缓冲区中,他们的总大小就是task stack 的实际使用大小。
??为了节约RAM 的使用,ISR间可以共享使用stack,但是要满足以下条件:
1.ISR必须为2类中断
2.ISR必须在同一个核内。
3.OsIsrEnableNesting必须配置为FALSE。
4.ISR必须为同一优先级。
??此策略出现在ETAS 的实现方式中,Vector没有此策略。
??所谓的单一栈指的是所有的TASK都使用了同一个栈,当task被抢占的时候栈是被叠加的,栈的实际大小会被一直增加。所以在配置stack大小的时候需要考虑到低优先级被抢占的情况避免栈的上溢,OS会以最糟糕的抢占情况下去计算stack。下图为抢占式的task。
而非抢占式的task的栈大小仅为当前task’的栈大小。如下图所示。
??多栈模式指的是每一个task有单独的stack。即使使用多个物理堆栈,RTA-OS仍然提供单堆栈体系结构的好处——当任务和/或isr共享一个优先级时,每个物理堆栈上所需的堆栈空间可以被覆盖。但是,要使堆栈分配正常工作,您需要指定每个堆栈上所需的空间。如果您配置的目标需要此信息,RTA-OS将要求您提供多个堆栈值。如下图所示:
??不管是何种OS,都应该检测和保护stack避免其溢出。在MICROSAR OS中提供了如下策略:
Scalability Class | Stack check strategy |
---|---|
SC1 / SC2 | Software stack check |
SC3 / SC4 | Stack supervision by memory protection unit (MPU) |
什么是Scalability Class 见 [AutoSar]BSW_OS 01 Autosar OS入门第四节。
??初始化的时候在每一个stack 的最后填充0xAAAAAAAA(以32位单片机为例),当stack切换的时候检测最后这个elment是否被改变来判定stack的溢出。
1.适用于SC1 SC2,如果禁用了MPU,SC3和SC4也能用Software Stack Check。
2.无法检测到所有的 栈溢出,因为有的时候相邻的stack已经被覆写了,但是刚好上一个stack 的最后一个element
没被改变。
3.如果内存已经被破坏,Software Stack Check 无法检测stack 溢出。
??在SC1 SC2 scalability模式下 OsStackMonitoring = true。
?? 如4.1.2所述,一旦激活了该检查机制,OS会自动的检查每个stack,一旦发现溢出则会转入shutdown,如果用户配置了ShutdownHook,在系统关闭前会调用此hook。
?? 在OS运行的整个过程中,活动的stack都会交由MPU监控,因此OS会保留一个专用的MPU区域用于在OS切换的时候进行覆写。由于MPU的机制stack不会越界访问,所以stack溢出的情况不会发生,但是内存冲突的情况是可能发生的,一旦检测到内存冲突,会立即调用ProtectionHook(),用户可以在ProtectionHook()中决定如何进行下一步处理。
?? 仅仅适用于SC3 SC4.
?? OS会自动初始化一个MPU专有区域来监督stack。如何配置额外的MPU区域和区段链接将在 MPU章节详细讲解。
?? 我们可以在OS启动后的任一地方调用API来获取当前stack的占用大小。
OsStackUsageMeasurement = true