First of all, I am a newbie. I thought it was important for you to know.
I have just started reading the FreeRTOS manual where it states to start with a Demo project which should run immediately without issues.
I selected the demo project CORTEX_M4F_STM32F407ZG-SK from the FreeRTOS folder and opened it in IAR Workbench.
I adjusted one setting in the project options, i.e. i am using the simulator instead of a real board. I can build the code. However, if i run the code, the code gets stuck inside the function xPortStartScheduler, more specially at the line
I have seen that others also have stumbled on similar issues
Therefore I tried to change the following line in the FreeRTOSconfig.h file: #define configPRIO_BITS 4
changed into: #define configPRIO_BITS 8
With this setting the demo project runs further but now gets stuck at line
svc 0
in the portasm.s file.
My goal is just to make the demo code running and gradually learn my way into FreeRTOS. WOuld be pleased if you could assist in finding a possible cause.
You don’t mention which simulator you are using, but if it is QEMU as per the link below then we have found the simulator does not model the interrupt controller accurately. For example, the device being modelled in this project has three priority bits, but when run under QEMU we have to set the configuration to say it has 8 priority bits: https://github.com/FreeRTOS/FreeRTOS/blob/master/FreeRTOS/Demo/CORTEX_LM3S6965_GCC_QEMU/FreeRTOSConfig.h#L96
Thank you for the hint. I looked up how I can monitor the SVC interrupts. It looks like the interrupts are being triggered continuously as the program counter is stuck. It seems like it can not enter the SVC handler as the breakpoint is never reached. Do you maybe have any idea why?
Have you installed the SVC handler? See the FAQ “my application compiles but does not run” on this page of the FAQ https://www.freertos.org/FAQHelp.html
If you have installed the handler then my next port of call would be the IAR manual.
Yes, the SVC Handler is installed by default in the DEMO project. Unfortunately i can not step into the svc instruction to see which handler is triggered. I must conclude that there is an issue in the simulator
Can i maybe ask one more question before we close this topic?
I noticed that the SVC interrupt is triggered but the interrupts are not serviced, i.e. they are pending. I tried to analyse the code and traced the function call chain which is like:
main function --> vTaskStartScheduler() --> xPortStartScheduler --> StartFirstTask --> svc
I noticed the following comment which disables interrupts in the vTaskStartScheduler. I am a little confused because of the comment. If interrupts are disabled, how can the SVC interrupt handling occur to start the first task?
I disabled the demo functionalities inside the main function and triggered an external SVC interrupt through the simulator. I was able to enter the SVC_Handler. So I think there is actually something wrong in the code that disables interrupts?
At least we can assume that the simulator is working correctly and the SVC_Handler is installed correctly. I just don’t know why the svc 0 instruction in the startFirstTask does not have the same effect?
Finally I put an portEnable_Interrupts(); instruction in the port.c file just before the StartFirstTask call and now the scheduler is starting and my tasks are executing.
Maybe somebody from your side can look into this topic further?
What is portEnable_Interrupts() doing? Globally enabling interrupts or updating the BASEPRI register? If the former then you should probably get a fault if you execute and SVC instruction with interrupts disabled - the kernel code doesn’t disable interrupts it only manipulates BASEPRI so if you disable interrupts then you should enable again before starting the scheduler. BASEPRI on the other hand is deliberately set when the scheduler is started, and then reset to zero inside the SVC handler.
Sorry, the naming is indeed a bit confusing.
I am using the macro form the portmacro.h file
portENABLE_INTERRUPTS() __set_BASEPRI( 0 )
But then I do not understand why I need to add this line to make it running. As I understand, when the scheduler is started, the interrupts are disabled/masked through the macro
portDISABLE_INTERRUPTS() which basically masks/disables all interrupts with priority <= configMAX_SYSCALL_INTERRUPT_PRIORITY through the call
__set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY );
And with the instruction I set the basepri back to 0.
I assume there must be something wrong with the priorities then? I can not seem to find the location where the interrupt priorities have been set in the DEMO projects?
As mentioned above, I was forced to set the following macro to 8 instead of the default 4. #define configPRIO_BITS 8
However, doing this messes up the interrupt priorities as i see there are interdependencies e.g. #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
So changing the nr of bits to 8 leads to getting stuck at the SVC 0 call. Therefore I changed the nr of prio bits back to 4 and commented out the following check
#ifdef configPRIO_BITS
{
/* Check the FreeRTOS configuration that defines the number of
* priority bits matches the number of priority bits actually queried
* from the hardware. */
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
} #endif
In that case, the scheduler is able to start again with the SVC call. Does that seem feasible to you?
I just started reading the FreeRTOS guide and hope that everything will get clearer as I progress through he guide. It was important for me to start with something that i can run without errors. This will allow me to experiment and change things and see what happens.
I achieved that with your help. Thank you very much.