I am new to FreeRTOS and I am trying to port it to an ARM9ES platform which is developed using rtl codes. so it's a actually a simulation.
I have 2 GPIO peripherals when I create different tasks to use them separately. the task with the highest priority starts but gets blocked whereas the task with low priority works fine.
not only this but also, the ticks delay of the first task interferes in the second task. this means that after two ticks I see an incrementation vLEDTASK1 that is not delayed followed by another incrementation.
GPIO 1 and 2 start with value 1
tick 1 --> GPIO1 incremented to value 2
tick 2 --> GPIO1 incremented to value 3(without delay) then 4
while GPIO 2 is blocked after starting the task so it has continuously value 1
I think that the second tick that is supposed to increment GPIO2 increments GPIO1 and then since it's the same tick that is suppose to increment GPIO1 in increments it a second time. thus 3 then 4.
while debugging I checked that the register R4 (led) and R5(address of GPIO set) are responsible for this. and at the second tick the register R5 contains only the value of GPIO1 set address (called two times) where it should be called one time for GPIO1 set and one time for GPIO2 set.
Any body has a clue on this?
May be there is an option in config that is activated or deactivated that is causing this ? I would like to mention that with only one task everything works fine.
int main( void )
IO0DIR = 0x00FF;
IO1DIR = 0x00FF;
xTaskCreate (vLEDTask, ( signed char * ) "LED", configMINIMALSTACKSIZE, NULL,5, NULL ); // Stack is 90
xTaskCreate (vLEDTask1, ( signed char * ) "LED1", configMINIMALSTACKSIZE, NULL,4, NULL );
static void vLEDTask( void ) //GPIO 2
IO0SET = led & 0xFF;
static void vLEDTask1( void ) //GPIO 1
IO1SET = led & 0xFF;
configUSE_PREEMPTION is defined as 1
just to make sure I got things rights these are the files I am including:
boot.s main.c tasks.c list.c queue.c heap_1.c port.c portISR.c ( I think they work fine since I could save and restore context correctly) but is there anything missing ? also portmacro.h contains save and restore context.
vPremptivetick does: add LR,LR,#4, save, switch, restore (address 0x8) SWI
vTickISR does: save, increment tick, switch, restore (address 0x18) IRQ
I'm not sure I fully understand what it is you are describing, but suggest taking a step back to try one thing at a time. Your current code is context switching from the tick interrupt and from a yield (vTaskDelay() calls yield). You can replace the vTaskDelay() calls with a taskYIELD() call to get the tasks switching back and forth without any reliance on the tick interrupt - then when you are sure that is working you can add back in the vTaskDelay() calls.
To do that change the task code to:
volatile unsigned long ul1 = 0, ul2 = 0;
void vTask1( void * pvParameters )
for( ;; )
void vTask2( void * pvParameters )
for( ;; )
Assuming the tasks are given the same priority then when you run the tasks you should see ul1 and ul2 increment at the same rate as each task yields to the other after each increment.
Thank you for the reply.
So I commented the SetupInterruptTimer function in order to make the recommended test.
if I don't ,it makes other glitches.
if I set same priority for both tasks I see only the incrementation of one task. the other task doesn't even start. and if I change priority settings incrementation occurs in the highest priority task and not the other.
I checked the LR register containing the return address it never has the address of the task that the simulation shows as blocked (no incrementation).
attached are the non standard files I am using.
Have you installed vPortYieldProcessor() as the SWI handler?
Have you defiend vPortYieldProcessor() as naked if you are using GCC, or equivalent if using any other compiler?
If there are no ARM9 GCC port layers in the FreeRTOS download then use a GCC ARM7 port layer as a reference instead - it is basically the same.
Thank you very much for the hint.
I am using GCC ARM7 port and GCC compiler. I have just fixed the definition of vPortYieldProcessor as naked. now it works fine with taskYIELD(). but when I give different priorities to the tasks only high priority task increments. Besides when I switch to using vTaskDelay I get back the same problem (one task is blocked and the other works).