we use Keil RTX on a M4 core (XMC 4500) which contains a memory protection unit. We want to run some parts of the software in its own memory space. I have found the description about CMSIS-Zone (CMSIS-Zone) which should provide MPU support. In the thread mode multiple processes should be possible.
- Does anybody know if this feature is planned for Keil RTX.
- Are there other RTOSs which support this kind of features already?
Thanks a lot for any hint
Thanks for getting in touch with us.
We have just started to discuss MPU extension for CMSIS/RTX5. Some low level MPU APIs are already in place as part of CMSIS-Core(M) for a while. On the development branch we added a first draft implementation for an MPU callback to RTX5, see commit 0e45768. Please be aware that at the current stage its only an experimental API and it will change as we move on.
Our current idea is to let the user provide the MPU regions used per thread. The current stage needs you to place the thread stack manually to a region accessible by the thread. We think about moving this responsibility to RTX5 scheduler, soon.
With CMSIS-Zone we want to create a common basis for graphical design tools for system partitioning, i.e. creating adequate MPU regions.
FreeRTOS has some kind of MPU support as well.
Please let us know about your opinion about MPU enhancement for RTX5.
How is the status of the MPU support in RTX5?
You told me that you will have a released version at the end of Q3/2018.
Can you provide any preliminary documentation to get an understanding of the usage and the features?
Best regards, Jussy
Unfortunately we have no further progress compared to the draft stated earlier. We are focused on getting the non-MPU version of RTX5 ready for functional safety, first.
The usage/features we have in mind is sketched as part of CMSIS-Zone. We intend to introduce the concept of processes for RTX5, which is an arbitrary grouping of threads with shared memory access privileges. This concept is very similar what is used on Windows/Linux when talking about processes and threads. The scheduler of RTX5 shall provide a mechanism to change the MPU configuration whenever a thread switch (from one process to another) occurs. With a proper memory layout (partitioning) a segregation between processes can be achieved.
The latest release of CMSIS already contains the basic functionality to put all this together on your own. RTX5 (compiled with the define MPU_LOAD) calls the scheduler hook osRtxMpuLoad. Core(M) contains a couple of functions to load MPU configurations from a predefined table. I expect the final solution to be basically implemented that way.
Of course there are many issues we need to solve in order to make the MPU protection applicable to a wide range of requirements. We need to further discuss how to handle privilege escalation for instance.
I am trying to use the osRtxMpuLoad hook as a proof of concept. It seems the hook body is not defined anywhere, just the symbol name is kept as a placeholder in the irq_armv8mbl.s file. Since I can't find any documentation, I have a few basic questions:
1) Will simply adding a .c file with the function definition to the non-secure project be enough? Also, adding
to the preprocessor symbol defines in the C/C++ dialog box under options for target work to ensure that the code works?
2) It seems that the osRtxMpuLoad takes in one parameter. From the assembly file, I think the parameter is a pointer to the next thread to run's info correct? (osRtxThread_t * type). So would that allow me to use the thread ID as the offset to the MPU configuration table and load the correct MPU configuration (using ARM_MPU_Load_NS)?
I apologize the if the questions are too basic but I don't have any other resource to figure this out.
I apologize that this MPU feature in RTX5 is not yet finally documented. We decided not to add it to the official documentation as long as its in beta stage. Please be aware that the hook might change in a future release of RTX5.
In the current implementation is a simply function you can implement anywhere in your use code. This function, as you already mentioned correctly, is called in RTX5 scheduler context right before jumping back to thread mode and executing the next threads code. The parameter given to that hook function is the thread id aka osRtxThread_t* (pointer to the next threads control block). You can use it to identify the thread that will be executed. Its up to you to configure the MPU accordingly.
Please be aware that in Armv8-M devices you have two separate MPUs, one for secure and one for non-secure mode. Typically I expect you to run RTX5 for non-secure mode. Hence you should implement the hook to reconfigure the non-secure MPU using ARM_MPU_Load function for instance. The ARM_MPU_Load_NS function can only be used in secure mode to reconfigure the non-secure MPU.
Does this make sense to you?
Thank you. I figured that out and it seems to work. The current issue I am facing is that I get a hard fault while enabling the MPU (I think at __ISB()) if I don't set the PRIVDEFENA bit. I noticed the FreeRTOS implementation seems to always set it when enabling the MPU. Is their any reason why this needs to be done?
that depends on your MPU configuration. The PRIVDEFENA allows privileged access to all memory without specific region definition. If you don't enable that bit you would need to add specific region configuration for all your (privileged) code/data, explicitly. In CMSIS this decision is not made implicitly like it might be done in FreeRTOS. You rather need to set this bis explicitly during MPU enable if you want to.
View all questions in Keil forum