I mentioned that i’d like to see the FreeRTOS uIP demo for at91sam7x (directory Demo/uIP_Demo_IAR_ARM7) work with plain gcc instead of iar.
So after some fumbling and googling around, i got all issues about the SAM7 uIP demo with gcc cleared out but one (with the emac isr, see below).
- About the headers: My preference was to get things to build with unified unaltered Atmel headers (I assume that’s what the IAR version uses anywas). As it turns out, the headers work fine with gcc: after running indeed into a couple problems myself with the inline functions instead of macros in lib_AT91SAM7X256.h and quite some googling, i found that the following does the trick:
- in order to avoid double defs errors, i added this line in FreeRTOSConfig.h: #define __inline inline static
- no such things as -Wstrict-prototypes, -Wmissing-prototypes and -Wmissing-declarations in the CFLAGS. Indeed, the first hates function pointers as arguments (lots! of warnings), the other two fill screens! of stupid warnings because lib_AT91SAM7X256.h has thousands of lines of inline functions without prototypes. I left a -Wextra in there though, although this gives lots of “unused parameter ‘null’” warnings becaused of unfinished macros/inlines in lib_AT91SAM7X256.h, but i felt that this option covers so many different warning types that i’d be hesitant about taking it out.
- I did put back the first argument to AT91F_AIC_ConfigureIt in the calls (even though Richard pointed out it’s redundant), so as to stick with unified atmel headers.
- include lib_AT91SAM7X256 in Board.h as in the uIP/IAR demo, not ioat91sam7x256.h as in the lwIP/Rowley demo
- no intrinsic.h in FreeRTOSConfig.h line 33 for gcc
With that, the stock Atmel/IAR headers work with plain gcc just fine
- a couple typo/letter case stuff i ran into: i already mentioned “Board.h” in FreeRTOSConfig.h line 34 and “Emac.h” in EMAC/SAM7_EMAC.h line 74. Here are a couple new ones I ran into since: “Board.h” (should be upper case) line 35 of ParTest/ParTest.c, “uIP_Task.h” line 69 of main.c, and another one (though not directly related to the build process) on http://www.freertos.org/portsam7xiar.html, where it speaks of Demo/uIP_Demo_IAR_ARM7/uIP/uipopts.h. The actual name of the directory is ‘uip’ (all lowercase) and the filename uipopt.h (not uipopts.h). Still about that web page: it says something about how to use rmii (rather than mii). I remember reading in the at91.com forum that as per the atmel errata, rmii has bugs in the at91sam7 emac and is thus no longer supported. Still a possible typo, although this time an absolutely harmless one: in the Makefile of the lwip/rowley demo, theres many times “DEMO_APP_THMUB_xyz” (with THMUB instead of THUMB). i took the liberty to change that to DEMO_APP_THUMB_xyz
- by the way, i noticed that in the lwip demo, there’s a “static xSemaphoreHandle xSemaphore = NULL;” defined both in SAM7_EMAC.c and SAM7_EMAC_ISR.c, which thus will probably be a different variable in both files. Dunno if that’s a problem, just thought i should point it out.
- also, in uip/uipopt.h, there’s an U behind every octet for UIP_IPADDR[0…3], but not for UIP_NETMASK[0…3] or UIP_DRIPADDR[0…3] - strange?
- The Makefile is based on that from the Rowley/lwIP demo. I renamed it from ‘makefile’ to ‘Makefile’ though, as it’s the usual notation and there’s a line “touch Makefile” in the “clean” target. Note that this typo doesn’t even throw an error on posix systems (as make also accepts makefile and the touch command will touch or create an empty Makefile file), but I guess ‘Makefile’ was what’s intended (and windows just makes no difference and no empty Makefile but touches makefile). Actually, I like “clean” to remove all built objects rather than just touching the Makefile, but i guess under windows without cygwin, the ‘rm’ command might not be known by the system, so throw that line (and the editor bkpfile cleaning find/rm *~ line) out if you have troubles with it
anyways, back to the build and source:
- i took the boot.s, atmel-rom.ld and Cstartup_SAM7.c from the FreeRTOS lwIP/Rowley demo.
- in port.c (which i copied from …/…/Source/portable/GCC/ARM7_AT91SAM7S/port.c), i put AT91C_BASE_AIC as a first argument to AT91F_AIC_ConfigureIt (as in the iar version)
- i commented out the vEMACISR function from SAM7_EMAC.c since it’s arm code and won’t compile with the thumb rest in gcc. I’m no expert at that, but afaik, gcc has no such __arm thing and wants those things compiled separately and then linked together with thumb interwork options (correct me?). anyways, i believe that’s also how the rowley/lwip demo does it.
- by the way, in …/…/Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h, there might be a braces issue around lines 196 to 198 (i moved that opening brace from 196 to below 198). Depending on the choice of emac code, we don’t need that file. but please have a look at that brace anyways.
Ok. now we are at a point where the only thing that’s still missing or quirking is the emac isr code.
I tried 3 options (i made different Makefiles, just softlink or copy your choice to Makefile), but unfortunately all 3 options lead to the same problem: it builds fine, it runs fine after flashing it to the board as long as no ethernet packet comes, but when a packet comes, it freezes hard (probably not just the ip stack but the whole FreeRTOS, since the leds freeze in their current state and stop blinking)
Before laying out what these options were, i’d like to point out that obviously precautions about emac isr and context switching are obviously done differently between the iar and gcc versions. the IAR version has an assembler wrapper, while the gcc version has a call to portENTER_SWITCHING_ISR. i tried it in that way (portENTER_SWITCHING_ISR instead of assembler wrapper, but i might have done something wrong here) and defined vEMACISREntry as vEMACISR in FreeRTOSConfig.h. also, the two versions differ in names such as portEXIT_SWITCHING_ISR vs portEND_SWITCHING_ISR (what’s the difference between those two?) for some options i had to define (copy/paste) portEND_SWITCHING_ISR. i did that in FreeRTOSConfig.h for now (though i’m aware that this is certainly not the right place to leave it)
So anyways, i temporarily renamed the EMAC dir from the uip/IAR demo to EMAC_uip_iar_modified and copied the EMAC dir from the lwip/rowley demo as EMAC_lwip_rowley_modified, so you can easily see which options takes which files from what code.
So here for Option 1:
- i took the vEMACISR code had thrown out of the iar version of SAM7_EMAC.c and put it into a file SAM7_EMAC_ISR_alt.c. i added the portENTER_SWITCHING_ISR() call at the beginning of that function in hope that this would take care of the isr context switching precaution stuff. Nice try, builds fine, runs fine, freezes on ethernet packages.
Option 2: i took just the SAM7_EMAC_ISR.c from the lwip/rowley demo and kept the SAM7_EMAC.c from the uip/iar demo. a couple smaller adjustments, and i had to add vClearEMACTxBuffer from the lwip/rowley demo. i did that at the end of SAM7_EMAC.c same thing: builds fine, runs fine, freezes on ethernet packages
Option 3: stop using the EMAC code from the uip/iar demo and copy the whole EMAC directory from the lwip/rowley demo. I had to throw out anything lwip-specific and to replace it with the uip specific stuff (buffers and buffer sizes/nums as seen in the uip/iar code.). also i added the function lEMACSend and ulEMACPoll from the uip/iar demo emac code. The former had different prototypes between versions, the latter didn’t exist in the lwip/rowley code but is needed by uIP_Task.c. Nice try, but same problem as with options 1 and 2.
Anyways to sum up on the status (same for all 3 options): everything builds fine, but there’s a freeze problem probably with the emac isr code (maybe because of the difference in the content switching precautions and wrappers between the uip/iar and lwip/rowley code.
my guess is that someone who knows the emac isr code might see the problem quite quickly.
would you by any chance be willing have a look at it?
it’s a neatly packed archive file, about 120kB as .tar.bz2 (which should also be readable under windows i believe, with any halfway recent winzip or so) or 200kB in legacy .zip format (maximum compression, ouch)
i built it with gnu make and arm-elf-gcc 4.0.3, but i guess any arm-elf-gcc or compiler based thereon should do, so winarm should probably work for those who run windows.
i can mail it to you if you want or tell me how else to send you the archive