前言:
现在很多单片机有MPU。比如STM32F4 F7 H7等以ARM CM3 CM4 CM为架构的单片机。那么现在很多RTOS都支持MPU配置,利用MPU实现用户态程序和内核态程序隔离。
从用户产品经理角度出发,作为RTOS的使用者,以一个简单的商业例子来说明,RTOS关于用户态程序这一特性,应该具备的要点:我是设备制造商,设备采用单片机芯片,我是XXRTOS的使用者,我希望我的设备具有二次开发能力,也就是说我的客户Tom购买了我的设备后,他可以写一些简单的程序来操控我的设备,并且TOM无法读取我内核固件,且TOM的程序发生意外时,内核可以捕获错误,从而停止运行TOM的程序。这就好像为Windows开发一个程序一样。那么可以得出,我必须为我的客户TOM分配一部分空间:RAM+FLASH。TOM的程序可以随心所欲的访问这些区域,但是不能访问内核区域。如图所示:
显然,Windows上面开发程序,TOM可以,定义全局变量,也可以调用OS提供的服务,比如创建线程,创建队列,串口发送等等。
比如TOM创建了两个线程,一个全局变量GA,他可以随心所以的操作全局变量GA,并发送串口数据。
int GA=1;
Thread1()
{
GA=5;
CreateThread(Thread2);
UartSend("hello world!");
}
我们分析一下,XXRTOS应该具备:
1.TOM程序调用的OS的资源的句柄,应该都放到内核区域,也就是说Thread1/Thread2的任务控制块应该放到内核区域,因为如果放到了用户空间,自己就可以修改自己的TCB任务块,自己给自己的TCB任务快的Flag设置为特权模式,那么TOM程序就提权了。TOM可以随心所欲的读取内核固件。对比Windows linux,任务句柄就在内核区域。
2.TOM的线程任务栈应该放到用户态,如果放到内核态,然后Thread1Thread2又是用户模式,直接就会HardFault,原因很简单:Thread1随便执行一条指令:push r0.此时SP如果指向内核态空间,而内核态空间不能被用户态访问,就会hardfault,对比Windows linux,任务栈就在用户区域。
3.TOM的程序应该随便访问用户态所有的空间,因为这个GA变量可能被放到用户空间的任何位置。也就是说Thread1 Thread2之间不设防。对比Windows linux 用户可以访问他所以的全局变量.
4.TOM调用OS服务函数,该服务函数应该陷入内核,由内核态去执行,完事儿返回
接下来看
FREERTOS的安全模型:
显然不满足,非特权任务尽然不能访问应用程序数据!
再看Zephyr,几个点:
1.线程的栈要手动malloc或者需要调用Z_THREAD_STACK_DEFINE_IN,然后在调用k_thread_create。当然这问题不是很大,稍微麻烦一些而已
2.定义的全员变量需要放到指定的区域,对于TOM来说,他只需要int GA=1;其他不用管,至于Zephyr 我还需要继续挖掘。
再看NUTTX:
上述模型都满足,问题:
1.需要在linux下开发
2.开发用户程序需要带SDK,他们没考虑过IAT导入表?