SAM7 CDC example

[moved from private email thread] Rumor has it that there is a different version of the AT91SAM7S port and USB example that has some bug fixes and uses the USB differently, however I don’t see anything like this listed on your site.  Is there any chance that you could forward me the project?  I’m working with USB on the AT91SAM7S and would love to play with FreeRTOS as well.

SAM7 CDC example

[moved from private email thread] Attached find two zip files.  USB.zip contains the original serial port emulation USB files, USBCDC.zip contains a modification there of for later versions of FreeRTOS. These files were not written by me so I cannot directly support them, although they are heavily based on the file included in the FreeRTOS download.

SAM7 CDC example

[moved from private email thread] Thanks!  I’m actually using different headers as well that are dated 3/2005 and have quite a few definition changes from the headers you’ve included. Since you’re running these files, I had a question for you about a possible bug.  I’ve tried to port over the USB-CDC project using these files and I get compiler errors at the call to portEXIT_SWITCH_ISR() and upon looking at portmacro.h this code looks a bit peculiar.  The compiler barfs from what looks like a second #define in the middle of the curly braced expression.  I could modify the placement of the braces to get it to compile, but I don’t want to change the functionality from what it was intended.  The code section is below.  Comments? Thanks! /*———————————————————– * ISR entry and exit macros.  These are only required if a task switch * is required from the ISR. *———————————————————-*/ #define portENTER_SWITCHING_ISR() /* Save the context of the interrupted task. */ portSAVE_CONTEXT(); /* We don’t know the stack requirements for the ISR, so the frame */ /* pointer will be set to the top of the task stack, and the stack*/ /* pointer left where it is.  The IRQ stack will get used for any */ /* functions calls made by this ISR. */ asm volatile ( "MOV R11, LR" ); { #define portEXIT_SWITCHING_ISR( SwitchRequired ) /* If a switch is required then we just need to call */ /* vTaskSwitchContext() as the context has already been */ /* saved. */ if( SwitchRequired ) { vTaskSwitchContext(); } } /* Restore the context of which ever task is now the highest */ /* priority that is ready to run. */ portRESTORE_CONTEXT(); #define portYIELD() asm volatile ( "SWI" ); /*———————————————————–*/

SAM7 CDC example

I can’t really see from email as the formatting is all screwy, however I assume you are referring to the positioning of the ‘{’ and ‘}’ in the macro? The two macros ENTER_SWITCHING and EXIT_SWITCHING have to be used in pairs. The ENTER macro opens a {, the closing macro closes with a }, so the { and } match up in a pair. The ENTER macro MUST be the FIRST line in the ISR code, the EXIT macro must be the last line in the ISR. The reason for this is stack usage.  If your ISR uses any local stack variables then the compiler will add function prologue code to allocate space on the stack for the variables – and this must NOT happen prior to the context being saved.  Therefore the inner block ({}) is used to allow local variables to be declared later. Therefore the ISR looks like this: void vAnISR( void ) { ____portENTER_SWITCHING_ISR(); ____/* Macro places an opening { here. Therefore the variable below is not ____allocated until after the macro has completed. */ ____int iAVariableCanBeDeclaredHere; ____/* ISR code can go here. */ ____/* Macro places a closing } here to close the block. */ ____portEXIT_SWITCHING_ISR(); } Making sense?

SAM7 CDC example

Ah that is very clear, thanks much for the explanation.  My confusion originated from the USB-CDC.c file you sent, where the vUSB_ISR makes the following call before the end of the ISR: portEND_SWITCHING_ISR( cTaskWokenByPost ); This macro was undefined in the port files you sent, so I did some searching in the FreeRTOS distribution and found it in SourceportableIARAtmelSAM7S64portmacro.h with the following definition (sorry for the formatting problems): /* Task utilities. */ #define portEND_SWITCHING_ISR( xSwitchRequired ) { extern void vTaskSwitchContext( void ); if( xSwitchRequired ) { vTaskSwitchContext(); } } /*———————————————————–*/ I looked in the portmacro.h that you had sent and there was something that looked similar (the portEXIT_SWITCHING_ISR) with almost identical format except for its necessary coupling to the portENTER_SWITCHING_ISR, so I assumed that there was just a bug in the define for the portENTER and portEXIT macros. Should the portEND_SWITCHING_ISR in USB-CDC.c be removed and instead the whole ISR surrounded by portENTER_SWITCHING_ISR and portEXIT_SWITCHING_ISR? Since space needs to be allocated on the stack for a switching ISR, I don’t see how a lone portEND_SWITCHING_ISR worked before.

SAM7 CDC example

[moved from private email thread] Ok I see, IAR Vs GCC differences.  Yes you need to use the macros, in a pair, from the GCC and discard the IAR equivalent. In the IAR version the context is saved from an ASM wrapper, before the C code is ever called.  This is necessary as IAR does not have the same inline assembler capabilities of GCC. Take a look at the SerialISR.c file in the GCC LPC2000 demo.  This shows how to use the GCC type macros.

SAM7 CDC example

The GCC USB CDC demo is now included in the FreeRTOS V3.2.1 download – see the SAM7X lwIP demo documentation page for more information.