AT91SAM7S256 WinARM port almost working

nobody wrote on Tuesday, August 29, 2006:

Hello,

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.

Thanks,
Darrik

nobody wrote on Tuesday, August 29, 2006:

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 :confused:
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.).

Janusz

nobody wrote on Tuesday, August 29, 2006:

>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.

nobody wrote on Wednesday, August 30, 2006:

Also - REMEBER TO CALL MAIN() FROM SUPERVISOR MODE!  Otherwise starting the first task will not work.

nobody wrote on Thursday, August 31, 2006:

I’m finally getting back to this source code…

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…

Thanks,
Darrik

nobody wrote on Thursday, August 31, 2006:

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.

nobody wrote on Thursday, August 31, 2006:

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.

Thanks again,
Darrik

rtel wrote on Friday, September 01, 2006:

If you zip up your whole project and send it to me ( r _dot* barry AT_AT freertos.org ) I will take a look.

Regards.

nobody wrote on Saturday, September 02, 2006:

I can’t understand why, but trouble is here:

#define portRESTORE_CONTEXT()   
  …
  …

/* 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

nobody wrote on Saturday, September 02, 2006:

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.

nobody wrote on Saturday, September 02, 2006:

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.

Janusz

nobody wrote on Saturday, September 02, 2006:

Are you still using WinARM?  Try GNUARM using the preconfigured projects.  It works nicely :wink:

nobody wrote on Saturday, September 02, 2006:

yes, I am using. Is it really better?

nobody wrote on Saturday, September 02, 2006:

I have checked with GNUARM, all my problems are the same :confused: with WINARM -O0 crashes after 102 OS ticks and with GNUARM after 7 :confused:

Janusz

dspaude wrote on Friday, September 15, 2006:

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?

Thanks,
Darrik

nobody wrote on Friday, September 15, 2006:

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:

#define vPortYieldProcessor swi_handler

nobody wrote on Friday, September 15, 2006:

yes, the line in FreeRTOSConfig.h is responsible and .weak SWI_Handler line in startup.S

Janusz

dspaude wrote on Friday, September 15, 2006:

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.

nobody wrote on Saturday, September 16, 2006:

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.

Janusz

nobody wrote on Tuesday, September 19, 2006:

Janusz,

Yes, I had already added the .weak statement.

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.

Does this give anyone any clues?

Thanks again,
Darrik