I have been creating an AT91SAM7S256 port using WinARM (GCC) and I have it running to the point where it gets to vPortISRStartFirstTask() in portISR.c which executes the macro portRESTORE_CONTEXT(). However, once it gets to this point I don’t know where it goes. It doesn’t appear to be executing any of the tasks that have been created (basically the IAR SAM7S demo application). I haven’t seen it get to any of the tasks (I have been using the LEDs to show me where it is since I don’t know how to use the debugger yet). I’ve tested the WinARM Hello example source within this port and that works fine (LEDs flash, timers run, UART0 works). I figure that this must be close to working, but maybe it is jumping to a wrong address? I tried disabling all tasks except the IDLE task that gets created in vTaskStartScheduler() in tasks.c, but it still won’t jump to prvIdleTask().
Any suggestions? Any ideas on how to use a SAM-ICE/J-LINK (Segger) with the AT91SAM7S-EK board to debug? Once I’ve got this code working I will submit it back to FreeRTOS and WinARM for assimilation.
IDLE tasks will work if you compile tasks.c in thumb mode - I had the problem (please look the archive some days ago)
You have to remember about startup.s and swi handler - you can use .weak function to link the handler with vportYieldProcessor.
J-LINK is cooperate with IAR environment but with other tool there is very poor support. GDB insight works with jlinkserver but it crashes very often
For Keil support you need RMI licence form Segger. Rowley is not special. I tried it but I was not happy.
JLINK is good to debug using command line of jlink but it is not convenient… I had a lot of problems because I use GCC with SAM-BA boot loader cooperation (sometimes you are in ARM mode, sometimes in Thumb - dual reset etc.).
>I tried disabling all tasks except the IDLE task that gets created in vTaskStartScheduler() in tasks.c, but it still won’t jump to prvIdleTask().
If you do not create any own task the scheduler will not run! Then it will return to continue your main function… Please look tasks.c source wheere idle task is created.
I’ve been compiling with -DTHUMB_INTERWORK per one of Janusz’s threads (because I also had the problem where the linker gave all kinds of errors). So, tasks.c is being compiled in thumb mode.
Even with “user” tasks created, nothing happens. It gets to vPortISRStartFirstTask() and then I don’t know what happens. Since I am a newbie to ARM, I am using example code to determine how others got their stuff to work, but of course many are using IAR and not GCC. From what I can tell in the startup_SAM7S.S assembly, the processor is getting set to SVC mode. If some other C function is later setting the mode otherwise, then I haven’t figured that out yet.
I will try to determine via JLink commander where this code might be sitting. If anyone has a GCC example startup file for the AT91SAM7S256, then that would be helpful to me…
Can you not use the SAM7X256 GCC startup file that is already in the zip file. I don’t think there would be anything different between the S and X as far as this file goes.
I think you are right, stepping into the start first task code will show you right away what the problem is.
From what I have found so far, the code (when running with only the vErrorCheck() and prvIdleTask() tasks) sits/loops in vTaskSwitchContext().
When I have the demo tasks enabled, then it gets to address 0x00200044 which appears to be within the interrupt vector area:
.data 0x00200000 0x140 load address 0x00104244
0x00200000 _data = .
*(.vectram)
.vectram 0x00200000 0x58 startup_SAM7S.o
*(.data)
.data 0x00200058 0x0 startup_SAM7S.o
I will need to wait for over a week before I get back to this, but it appears that maybe not jumping to an interrupt is what is holding me up. If anyone has a page number in some ARM manual I can look at so that I know how the vector memory is mapped out, then that would be helpful.
/* Restore all system mode registers for the task. */
"LDMFD LR, {R0-R14}^ \n\t"
when compiled with IAR this insruction will leave LR unchanged, but in case of gas lr is changed to 0xaaaaaaaa
I tried to restore registers without LR (R14), but my task is failed in taskYIELD
i don’t know why, but it will go into IRQ handler, which isn’t defined because configUSE_PREEMPTION is 0
This instruction should be called in Supervisor mode, and set the System mode LR to 0xaaaaaaaa.
This instruction will NOT work in the IAR simulator due to a bug in the simulator - but will work using IAR on the target hardware - PROVIDED the CPU is in Supervisor mode when it is executed.
What is your compiler flag for optimalization? I have problem with GCC and -O0. Then I have not stable platform which crash because of stack for example.
From what I can tell so far, when the code taskYIELD() (a macro for portYIELD() which is a macro for "SWI") from vTaskDelay() in tasks.c, the code never returns. This seems to be consistent with what I am seeing–the code seems to be stuck at some interrupt (I guess in this case it would be "SWI").
What SWI handler is being used? in the startup code it initializes SWI_Handler but it appears to just branch to itself. In Janusz’s example code (which works) it does the same thing, so what should I be looking into to make my version work?
swi_handler is a weak symbol. It should be overwritten to jump to vPortYieldProcessor. Look at the lwIP SAM7X port demo application, in FreeRTOSConfig.h you will see the line:
I added both of these lines (and changed SWI_HandlerR to SWI_Handler in startup like Janusz’s example), but it still won’t return from taskYIELD(). I see that it is going through the vPortYieldProcessor() routine, but I don’t know what happens to it after that. I assume it should have switched tasks and started running in that task until it yielded again.
have you add the .weak in startup? It is very important to add that. Then the linker removed the old symbol and linking with new from C.
If you write the device enter into vPortYiledProcessor so it is ok. Now it is something other. Check all your port files especially assembler fragments. My advice is to add LED blinking to OS interrupt. It is very useful.
It appears that all of the tasks run once. If there is some special circumstance, then sometimes the prvIdleTask() will keep running (resumes every 1 microsecond). However, if I disconnect power to the board, then each task will run only once and then everything is dead. The "special circumstance" seems to be after flash updating the code (via JTAG interface) then if I press the reset button prvIdleTask() will keep running (no other tasks run more than once). Again, unplugging power will then put the board in a state where it will run the tasks only once.