Sounds like the tick interrupt is not running. Try getting the timer interrupt working by itself to prove to your self that it is working before attempting to add tasks. If they only run once then they are probably blocked on a time that never occurs as the tick is not incrementing.
It appears that the PIT is not running. I had tested the code without the OS a few weeks ago and the PIT was working (a WinARM serial "Hello" example), but now that code also is not working. The PIT is being configured and enabled, but it is like the main interrupt register (? is there one and what is it?) is being blocked. USART0 interrupts work and IRQ0 interrupts work, but the PIT is blocked…
So far it appears that all interrupts are disabled. In startup_SAM7.S the processor gets put in SVC mode with IRQ and FIQ disabled. When I enable IRQ and FIQ for SVC then the interrupts work (as long as I don’t allow the RTOS to start!!!). Now I need to find out why the RTOS isn’t enabling the interrupts.
As a note, Janusz’s hello3_2dmini2 code keeps SVC IRQ and FIQ interrupts disabled and yet that code works just fine. Is there a function that is being called that enables the SVC interrupts that I am missing???
Each task maintains its own interrupt status that is stored as part of the task context. When the task context is initially set up (when the task is created) it is configured to have interrupts enabled. It should therefore not matter if main() is called with interrupts enabled or disabled, as when a task starts executing it will have interrupts enabled.
Place a break point at the start of the first task that executes - when the break point is hit check the interrupt bit in the status register - also check the uxCriticalNesting value (variable found in port.c), it should be 0 when the task starts.
I’m at a loss as to why it is not working. This is my current output:
main: starting task scheduler
xPortStartScheduler: started timer
vPreemptiveTick: AIC_ISR=1, AIC_IPR=2, AIC_IMR=42, ulCriticalNesting=0
The vPreemptiveTick output above is right after vTaskSwitchContext() in vPreemptiveTick().
I get 1 interrupt (tick) and then no more. I am going to modify some working code that is almost identical to mine to make it like my code until the working code stops working. Hopefully I’ll have an update on this tomorrow morning.
The joys of the learning curve on new processors and new code…
Yes, I do:
/* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = AT91C_BASE_PITC->PITC_PIVR;
portISR.c is almost identical to your hello3_2dmini2 code. I notice that you have a conditional statement around the interrupt code (between the portSAVE_CONTECT() and portRESTORE_CONTEXT() macros):
if (AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS) {
So far, converting Janusz’s hello3 code toward my implementation has not caused a failure in hello3. The PIT and OS are still running. The main differences left are in main.c and syscalls.c (which makes use of comm.c and commd.c whereas my code follows the serial.c and serialISR.c source from one of the FreeRTOS SAM7S examples). My code also (like the FreeRTOS SAM7S example) compiles and uses the following whereas hello3 does not:
$(RTOS_APP_DIR)/Common/Minimal/integer.c
$(RTOS_APP_DIR)/Common/Minimal/flash.c
$(RTOS_APP_DIR)/Common/Minimal/PollQ.c
$(RTOS_APP_DIR)/Common/Minimal/comtest.c
$(RTOS_APP_DIR)/Common/Minimal/flop.c
$(RTOS_APP_DIR)/Common/Minimal/semtest.c
$(RTOS_APP_DIR)/Common/Minimal/dynamic.c
$(RTOS_APP_DIR)/Common/Minimal/BlockQ.c \
Files that I have converted to be identical to mine include:
* makefile
* tasks.c
* task.h
* port.c
* portISR.c
* portmacro.h
* FreeRTOSConfig.h
* Board.h
* startup_SAM7S.S
I’ve converted most of main.c in hello3 (Janusz’s code) toward my code (which is basically one of the SAM7S FreeRTOS examples). When I add the following task in main(), then the board fails to continue running:
I have found the bug! The queue handles in serialISR.c were never initialized (but the serial.c versions of those same variables were initialized). Thus when the COM interrupt would happen it would attempt to do a memcpy() to the Tx queue handle but alas it was attempting to write to unknown memory and thus locked up. I added the following to xSerialPortInitMinimal() and all is mostly happy:
/* The queues are used in the serial ISR routine, so are created from
serialISR.c (which is always compiled to ARM mode. */
vSerialISRCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx );
Now the question is why there is an indication (via LED4) that there was a task check error (it is the serial task again causing a problem). Function xAreComTestTasksStillRunning() gets called and returns an error and thus the LED’s timing is adjusted to indicate an error.