问题1可重入函数与不可重入函数
1. 不可重入函数
1.1. 概念
不可重入函数,即不能重复进入的函数,不能被中断的函数。在多个任务调度这个函数时可能修改其他任务调用这个函数的数据,从而导致不可预料的后果。不可重入函数在实时熊设计中被视为不安全函数。
1.2 特点
有以下条件都属于不可重入函数
函数体内使用了静态的数据结构;(static)
函数体内调用了malloc()或者free()函数;
函数体内调用了标准I/O函数。
函数体内访问了全局变量
1.3 其他
在许多的处理器/编译器中,浮点一般都是不可重入的。因为浮点运算的汇编指令是多条,浮点数运算的过程中也可能被打断,导致数据异常。
printf()经常有重入和性能上的问题。
2. 可重入函数
2.1 概念
可重入函数,即可以重复进入的函数,能被中断的函数。可以在这个函数执行的任何时候中断他的运行,在任务调度下去执行另外一段代码而不会出现什么错误。
2.2 实现
在函数体内不访问那些全局变量,不使用静态局部变量,坚持只使用缺省态(auto)局部变量。
如果使用全局变量(包括static),则应通过关中断、信号量(即P、V操作)等互斥方法对其加以保护。
否则此函数就不具有可重入性,即当多个进程调用此函数时,很有可能使有关全局变量变为不可知状态。
在和硬件发生交互的时候,关闭硬件中断。完成交互打开中断。
不能调用其它不可重入的函数。
3. 内核操作模式和特权级别
-
两种操作模式
-
处理者模式 handler mode
-
异常服务例程的代码,包括终端服务例程的代码
-
-
线程模式
-
普通应用程序的代码
-
-
-
特权分级
-
特权级 privileged
-
特权级别下程序可以访问所有的存储器,并且可以执行所有的指令。
-
-
用户级 unprivileged
-
不能访问如果有 MPU 规定的禁地,否则将触发MemManage fault中断
-
-
3.1 通过MPU设置实施存储器保护
-
阻止用户应用程序破坏操作系统使用的数据
-
阻止一个任务访问其它任务的数据区,从而把任务隔开。
-
可以把关键数据区设置为只读,从根本上消除了被破坏的可能。
-
检测意外的存储访问,如,堆栈溢出,数组越界。
-
此外,还可以通过MPU设置存储器regions的其它访问属性,比如,是否缓区,是否缓冲等。
4. 系统中断
使用中断之前,需要做好初始化工作:
-
建立堆栈
-
建立向量表
-
分配各中断的优先级
-
使能中断