How can I access UART peripheral in unprivileged task?

Hello everyone,

“I am currently working on a Cortex-M4 microcontroller with FreeRTOS v10.5.1, leveraging MPU support."
I have two tasks out of which one is privileged and I am able to access I2C peripheral using HAL library in order to read sensor data and the other task is unprivileged task and I want to use UART peripheral using HAL library but it generates MPU fault since UART_HandleTypeDef huart1; variable is outside of its defined memory access.
Is it possible to access UART peripherals with HAL library (e.g HAL_UART_Transmit_IT) from unprivileged task?

unprivileged tasks should not be doing direct I/O, but should be accessing the I/O through FreeRTOS primitives (like a Queue or StreamBuffer) to something that is privileged.

If you REALLY need the task to do the I/O, you need to use one of your MPU segments to allow the address range of the peripheral to be accessed by the task.

So, I already passed one queue item as a parameter to unprivileged function in order to read temperature value from temperature(privileged) task. And if I want to access UART transmit and receive functionality then I will need two different queues for each one. Even, I need to add these two separate queues to the MPU region. In total there are only three user defined MPU regions. Is this the correct way to approach the problem?
Even I wanted to know in FreeRTOS, portGENERAL_PERIPHERALS_REGION is one of the MPU regions defined and by default everything is allowed to access the general peripherals. Still we need to define the address range of the peripheral that we want to access or is it possible to write bare metal code to access its registers and program them if HAL library usage is not possible?

If the issue is the software control blocks not being accessible, just put all of those HAL control blocks in one area of RAM and make it accessible with one block.

Note, FreeRTOS queues do NOT use up a MPU region to access, as the reads and write use privileged code to copy from the restricted space into the Queue. I think the V2 wrappers need the task to be marked as able to access the Queue, but that is a different operation.

Thank you for the answer. Then, I would need to assign a privileged task that will control UART peripheral and data will be passed through queues from unprivileged task in order to access the UART peripheral. Is this what you wanted to propose and I understood things correctly? Further I need to use mutex, if many tasks are accessing the UART peripheral to avoid data corruption.

There are two options, one is that unprivileged tasks don’t do direct I/O but communicate to privileged tasks to do the I/O. That is more in keeping with the concept that you want to put minimal trust to unprivileged tasks.

The second option is to move ALL the data structures used by the I/O library into a common memory block that the unprivileged tasks have access to, so they can use the library. This means that unprivileged tasks can mess up that I/O system if they don’t behave.

One big thing to note, most “HAL” libraries from venders are not designed to operate in that sort of environment, but are generally designed for “bare-metal” designs, so the problems with trying to use them there are expected. I almost always create a FreeRTOS specific version of the library which is designed from the ground up to behave properly, and it might (or might not) use parts of the HAL library within it, sometimes it needs to copy the code chuncks that are needed. The biggest issue is most HAL libraries are based on busy-waiting or call back notification, while tasks tend to want to do “blocking” I/O or fully asynchronous requests (fire and forget).

1 Like

Thank you for the solution.