I have adapted a port of ARM processor of Philips to ARM processor from ST on Keil IDE.
I’m using a Fast interrupt for OS tick, that works well. But I need interrupts for the RS232 and CAN communication, and there, each time an interrupt occurs that reset my processor.(I don’t get in my ISR, that’s happen before. Maybe during the header of interrupt ??)
I tried to reproduce the interrupt system on a small program (software, fast and normal interrupt). I didn’t get this problem.
First the fast interrupt uses a different stack. As downloaded the Keil demo only sets up a stack for the IRQ, system/user and SWI modes. Have you allocated a stack to the FIQ mode?
You may also get problems if the FIQ interrupts an IRQ. IRQ’s effectively run with the task context, if an FIQ causes a context switch within an IRQ then the IRQ may never complete. There are ways around this but it adds complication with minimal benefit.
Can you use an IRQ rather than the FIQ for your tick? - that way you should be able to use the standard code with minimal alteration.
It is odd that it does not occur when you run a small program. Maybe you could be running out of heap? Have you checked the setting of portTOTAL_HEAP_SIZE?
What actually happens when you say "reset". Normally under error you would go to one of the exception states (eg data abort or similar).
Can you get the error to occur using the Keil simulator? If so I will be able to give it a try here.
In simulation mode, when I make reset. I got a reset before…
I have checked my heap size. That’s not directly the problem. I have found a compiler optimization, and the #define prvHeapInit() is not compiled.
I think the problem comes from there…
I have tried many configurations :
* Config 1 :
- FIQ for OS tick
and
- IRQ for UART for example.
In this configuration, I got a correct a OS tick.
When a character is received, then my interrupt is processed
and at the next context switch (I suppose), the microprocessor resets itself ( or rather make a jump to @0x00000000).
* Config 2 :
- FIQ for OS tick
and
- IRQ for UART for example. (using only few register: R0, R1, R2. I need more !!!!)
In this configuration, the OS works.
* Config 3 :
- IRQ for OS tick and UART interrupt
In this configuration, the processor resets itself (or rather make a jump to @0x00000000) at the first timer interrupt
* Config 4 :
- FIQ for OS tick with mode change (I change mode (FIQ mode to System) to handle vPreeemptive, and come back Sys to FIQ)
and
- IRQ for UART for example. (using only few register: R0, R1, R2. I need more !!!!)
In this configuration, the OS works.
In this configuration, the processor resets itself (or rather make a jump to @0x00000000) when a character is received.
And " In simulation mode, when I make reset. I got a reset before…"
I mean that I can’t see in simulation mode any Abort Interrupt or Data prefetch error…
For the macro, I understood and I have seen. It’s every OK.
Can you zip up your project and send it to me? (including the keil project files, etc.). Use the email address from the FreeRTOS WEB site contacts page.
1) Check the version number of the Keil compiler being used. Version 1.5 of DK ARM or higher is required.
2) Each interrupt in your project has a wrapper that saves the link register on entering the interrupt, and restores it on leaving the interrupt. This is most likely the cause of your problem. When a task is initialised it’s initial stack is created but does not know about this wrapper macro.
When a task starts for the first time it’s registers are popped off the stack. One of these registers is the link register which holds the location of the start of the task code. Now when the RESTORE_CONTEXT() macro completes your ISR exit macro executes. This pop’s another value from the stack and places it in the link register, overwriting the true value with NULL - thus the code branches to 0 (reset) rather than the start of the task.
Fix’s -
1) Remove the wrapper, I don’t know why it is there but don’t think it is required.
or
2) Change the function pxPortInitialiseStack() in port.c to place the correct value of the link register onto the stack twice. This way when it is popped off for the second time it will overwrite the link register with exactly the same (and correct) value.
Wrappers aren’t use any more and Tick is generated by the Timer 3. I have always the problem when I have two interrupts (Timer + RS232 for example).
when a character is received, interrupt is proceeded … no problem
When a second character is received, interrupt is proceeded … then Os doesn’t switch context anymore…
it stays in the following endless loop in
portCHAR cTaskResumeAll
{
…
You can send it to me at the address from the Contacts page of the FreeRTOS.org WEB site.
Please zip up the entire project - including the Keil project files, etc - and provide some compilation instructions if it is not obvious (for example, which directory is the project file in).