dspaude wrote on Tuesday, October 16, 2007:
This all could possibly be related to my thread where I described task/semaphore problems (). Details: FreeRTOS 4.5.0 running on Atmel AT91SAM7SE512, code compiled by GCC 4.2.1 (YAGARTO).
What I am seeing is my IRQ1 interrupt (XHFC) is being interrupted by FreeRTOS where FreeRTOS resumes some task which ends up signaling the semaphore for the task for which the ISR is handling and will signal (confused?). Take a look at a normal sequence of events:
[00, 00:00:29.690] xhfc_ISR 1
[00, 00:00:29.690] xhfc_ISR +
(XHFC task semaphore signaled here using xTaskResumeFromISR())
[00, 00:00:29.690] xhfc_ISR -
[00, 00:00:29.690] xhfc_ISR 2
(XHFC task receives semaphore and resumes)
[00, 00:00:29.690] ** ENTER XHFC **
[00, 00:00:29.690] ** EXIT XHFC **
(XHFC task suspends with xSemaphoreTake())
However, after some time (and this is under load similar to my other thread) and then I see an interruption and then an Undefined Instruction Exception:
[00, 00:00:29.705] xhfc_ISR 1
[00, 00:00:29.705] xhfc_XmtStart(1)=3
[00, 00:00:29.705] ** ENTER XHFC **
[00, 00:00:29.705] ** EXIT XHFC **
[00, 00:00:29.705] xhfc_ISR +
(XHFC task semaphore signaled here using xTaskResumeFromISR())
[00, 00:00:29.705] xhfc_ISR -
[00, 00:00:29.705] xhfc_ISR 2
(XHFC task receives semaphore and resumes)
[00, 00:00:29.710] ** ENTER XHFC **
[00, 00:00:29.710] ** EXIT XHFC **
(XHFC task suspends with xSemaphoreTake())
[00, 00:00:29.710] main_HandleFatalError:
[00, 00:00:29.710] Undef: 20006D6A 60000012
R14=0x20006D6A which translates to an address within xQueueGenericReceive() which is what is called by xSemaphoreTake() and SPSR_und=0x60000012 indicates the failure occurred while in the ARM’s IRQ mode (which is the mode I would expect for the XHFC interrupt as it is connected to IRQ1):
.text 0x20006b3c 0x3ec appbuild/FreeRTOS/Source/queue.o
0x20006c34 xQueueGenericSendFromISR
0x20006ec0 xQueueCreate
0x20006b3c vQueueDelete
0x20006dd8 xQueueGenericSend
0x20006b98 xQueueReceiveFromISR
0x20006b54 uxQueueMessagesWaiting
0x20006ce0 xQueueGenericReceive
So, I am guessing that during the IRQ1 interrupt (XHFC set to Level 7 in Atmel’s PRIOR bits) I get a PIT interrupt which would actually be a higher priority interrupt than IRQ1. I am then guessing that the PIT starts executing and in the PIT ISR FreeRTOS decides to switch to a different task (since I am using preemptive mode). The task then resumes executing and happens to be a task that sends data to my XHFC task and signals the XHFC task to resume (xhfc_XmtStart(1)=3). The XHFC task then resumes since it is the highest priority task. When it finishes it waits for a semaphore. The RTOS then switches back to the IRQ1 (XHFC) ISR which then signals the XHFC task semaphore and the ISR exits. The ISR then allows the task switch to the XHFC task which resumes. However, when the XHFC task finishes and then goes to wait on the semaphore I get the Undefined exception.
So, should FreeRTOS be allowed to switch to a task while it is executing??? I don’t think this should be allowed, but I don’t see anything that prevents FreeRTOS from doing so. In my ISR I use portENTER_SWITCHING_ISR() and its associated portEXIT_SWITCHING_ISR( xTaskWokenByPost ). However, in this case it is true that the ISR never had anything woken by itself (it doesn’t loop nor signal the semaphore more than once), but since a task executed that signaled the same semaphore then xTaskWokenByPost should be pdTRUE, but how is the ISR supposed to know it got interrupted by something unrelated?
Anyway, how can I resolve this problem? How can I make FreeRTOS smart and not resume tasks during interrupts?
Thanks for your help,
Darrik