From 784519278c7323e43503061979c98f61aa4081ae Mon Sep 17 00:00:00 2001 From: Nicolas Sanz Date: Thu, 4 Apr 2013 15:09:44 -0300 Subject: [PATCH 1/3] Back to FreeRTOS definition of push and save context macros --- arduino.DuinOS/DuinOS/port.c | 289 ++++++++++++++++++++++------------- 1 file changed, 182 insertions(+), 107 deletions(-) diff --git a/arduino.DuinOS/DuinOS/port.c b/arduino.DuinOS/DuinOS/port.c index b98da00..e4a9e3a 100644 --- a/arduino.DuinOS/DuinOS/port.c +++ b/arduino.DuinOS/DuinOS/port.c @@ -125,130 +125,205 @@ extern volatile tskTCB * volatile pxCurrentTCB; * The interrupts will have been disabled during the call to portSAVE_CONTEXT() * so we need not worry about reading/writing to the stack pointer. */ -inline void portSAVE_CONTEXT() __attribute__((__always_inline__)); -inline void portSAVE_CONTEXT(){ - asm volatile ( "push r0 \n\t" - "in r0, __SREG__ \n\t" - "cli \n\t" - "push r0 \n\t" - ); #if defined(__AVR_HAVE_RAMPZ__) - /* +/* * have RAMPZ Extended Z-pointer Register for ELPM/SPM * the uC have extend program memory * 0x3b --> RAMPZ * 0x3c --> EIND */ - asm volatile ( "in r0, 0x3b \n\t" - "push r0 \n\t" - "in r0, 0x3c \n\t" - "push r0 \n\t" +#define portSAVE_CONTEXT() \ + asm volatile ( "push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t" \ + "in r0, 0x3b \n\t" \ + "push r0 \n\t" \ + "in r0, 0x3c \n\t" \ + "push r0 \n\t" \ + "push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, 0x3d \n\t" \ + "st x+, r0 \n\t" \ + "in r0, 0x3e \n\t" \ + "st x+, r0 \n\t" \ ); -#endif - asm volatile ( "push r1 \n\t" - "clr r1 \n\t" - "push r2 \n\t" - "push r3 \n\t" - "push r4 \n\t" - "push r5 \n\t" - "push r6 \n\t" - "push r7 \n\t" - "push r8 \n\t" - "push r9 \n\t" - "push r10 \n\t" - "push r11 \n\t" - "push r12 \n\t" - "push r13 \n\t" - "push r14 \n\t" - "push r15 \n\t" - "push r16 \n\t" - "push r17 \n\t" - "push r18 \n\t" - "push r19 \n\t" - "push r20 \n\t" - "push r21 \n\t" - "push r22 \n\t" - "push r23 \n\t" - "push r24 \n\t" - "push r25 \n\t" - "push r26 \n\t" - "push r27 \n\t" - "push r28 \n\t" - "push r29 \n\t" - "push r30 \n\t" - "push r31 \n\t" - "lds r26, pxCurrentTCB \n\t" - "lds r27, pxCurrentTCB + 1 \n\t" - "in r0, 0x3d \n\t" - "st x+, r0 \n\t" - "in r0, 0x3e \n\t" - "st x+, r0 \n\t" +#else +#define portSAVE_CONTEXT() \ + asm volatile ( "push r0 \n\t" \ + "in r0, __SREG__ \n\t" \ + "cli \n\t" \ + "push r0 \n\t" \ + "push r1 \n\t" \ + "clr r1 \n\t" \ + "push r2 \n\t" \ + "push r3 \n\t" \ + "push r4 \n\t" \ + "push r5 \n\t" \ + "push r6 \n\t" \ + "push r7 \n\t" \ + "push r8 \n\t" \ + "push r9 \n\t" \ + "push r10 \n\t" \ + "push r11 \n\t" \ + "push r12 \n\t" \ + "push r13 \n\t" \ + "push r14 \n\t" \ + "push r15 \n\t" \ + "push r16 \n\t" \ + "push r17 \n\t" \ + "push r18 \n\t" \ + "push r19 \n\t" \ + "push r20 \n\t" \ + "push r21 \n\t" \ + "push r22 \n\t" \ + "push r23 \n\t" \ + "push r24 \n\t" \ + "push r25 \n\t" \ + "push r26 \n\t" \ + "push r27 \n\t" \ + "push r28 \n\t" \ + "push r29 \n\t" \ + "push r30 \n\t" \ + "push r31 \n\t" \ + "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "in r0, 0x3d \n\t" \ + "st x+, r0 \n\t" \ + "in r0, 0x3e \n\t" \ + "st x+, r0 \n\t" \ ); -} +#endif /* * Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during * the context save so we can write to the stack pointer. */ -inline void portRESTORE_CONTEXT() __attribute__((__always_inline__)); -inline void portRESTORE_CONTEXT(){ - asm volatile ( "lds r26, pxCurrentTCB \n\t" - "lds r27, pxCurrentTCB + 1 \n\t" - "ld r28, x+ \n\t" - "out __SP_L__, r28 \n\t" - "ld r29, x+ \n\t" - "out __SP_H__, r29 \n\t" - "pop r31 \n\t" - "pop r30 \n\t" - "pop r29 \n\t" - "pop r28 \n\t" - "pop r27 \n\t" - "pop r26 \n\t" - "pop r25 \n\t" - "pop r24 \n\t" - "pop r23 \n\t" - "pop r22 \n\t" - "pop r21 \n\t" - "pop r20 \n\t" - "pop r19 \n\t" - "pop r18 \n\t" - "pop r17 \n\t" - "pop r16 \n\t" - "pop r15 \n\t" - "pop r14 \n\t" - "pop r13 \n\t" - "pop r12 \n\t" - "pop r11 \n\t" - "pop r10 \n\t" - "pop r9 \n\t" - "pop r8 \n\t" - "pop r7 \n\t" - "pop r6 \n\t" - "pop r5 \n\t" - "pop r4 \n\t" - "pop r3 \n\t" - "pop r2 \n\t" - "pop r1 \n\t" - "pop r0 \n\t" - ); + #if defined(__AVR_HAVE_RAMPZ__) - /* - * have RAMPZ Extended Z-pointer Register for ELPM/SPM - * the uC have extend program memory - * 0x3b --> RAMPZ - * 0x3c --> EIND - */ - asm volatile ( "out 0x3c, r0 \n\t" - "pop r0 \n\t" - "out 0x3b, r0 \n\t" - "pop r0 \n\t" +#define portRESTORE_CONTEXT() \ + asm volatile ( "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t" \ + "pop r0 \n\t" \ + "out 0x3c, r0 \n\t" \ + "pop r0 \n\t" \ + "out 0x3b, r0 \n\t" \ + "pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t" \ + ); +#else +#define portRESTORE_CONTEXT() \ + asm volatile ( "lds r26, pxCurrentTCB \n\t" \ + "lds r27, pxCurrentTCB + 1 \n\t" \ + "ld r28, x+ \n\t" \ + "out __SP_L__, r28 \n\t" \ + "ld r29, x+ \n\t" \ + "out __SP_H__, r29 \n\t" \ + "pop r31 \n\t" \ + "pop r30 \n\t" \ + "pop r29 \n\t" \ + "pop r28 \n\t" \ + "pop r27 \n\t" \ + "pop r26 \n\t" \ + "pop r25 \n\t" \ + "pop r24 \n\t" \ + "pop r23 \n\t" \ + "pop r22 \n\t" \ + "pop r21 \n\t" \ + "pop r20 \n\t" \ + "pop r19 \n\t" \ + "pop r18 \n\t" \ + "pop r17 \n\t" \ + "pop r16 \n\t" \ + "pop r15 \n\t" \ + "pop r14 \n\t" \ + "pop r13 \n\t" \ + "pop r12 \n\t" \ + "pop r11 \n\t" \ + "pop r10 \n\t" \ + "pop r9 \n\t" \ + "pop r8 \n\t" \ + "pop r7 \n\t" \ + "pop r6 \n\t" \ + "pop r5 \n\t" \ + "pop r4 \n\t" \ + "pop r3 \n\t" \ + "pop r2 \n\t" \ + "pop r1 \n\t" \ + "pop r0 \n\t" \ + "out __SREG__, r0 \n\t" \ + "pop r0 \n\t" \ ); #endif -asm volatile ( "out __SREG__, r0 \n\t" - "pop r0 \n\t" - ); -} /*-----------------------------------------------------------*/ /* From 8a146714b1e81577339481a0d50a2a1afa057d2f Mon Sep 17 00:00:00 2001 From: Nicolas Sanz Date: Thu, 4 Apr 2013 16:59:51 -0300 Subject: [PATCH 2/3] Proposing to clean the file DuinOS.h 'cause the lowtext attribute is in macro definition from FreeRTOS on file portmacro.h and here is duplicated --- arduino.DuinOS/DuinOS.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arduino.DuinOS/DuinOS.h b/arduino.DuinOS/DuinOS.h index f717e14..95dccfc 100644 --- a/arduino.DuinOS/DuinOS.h +++ b/arduino.DuinOS/DuinOS.h @@ -35,8 +35,8 @@ extern unsigned portBASE_TYPE mainLoopStackSize; #define HIGH_PRIORITY (tskIDLE_PRIORITY + 2) #define taskLoop(name) \ -static inline void name##Function() __attribute__((__section__(".lowtext"),__naked__,__always_inline__)); \ -void name##_Task(void *) __attribute__((__section__(".lowtext"))); \ +static inline void name##Function() __attribute__((__section__(".text.lowtext"),__naked__,__always_inline__)); \ +void name##_Task(void *) __attribute__((__section__(".text.lowtext"))); \ xTaskHandle name; \ void name##_Task(void *pvParameters)\ {\ @@ -49,7 +49,7 @@ static inline void name##Function() //taskLoop()macro use and reference them: #define declareTaskLoop(name)\ extern xTaskHandle name;\ - void name##_Task(void *) __attribute__((__section__(".lowtext"))) + void name##_Task(void *) __attribute__((__section__(".text.lowtext"))) #define createTaskLoop(name, priority)\ From 42927e157a94e3c294379dca86ec045f33637b4c Mon Sep 17 00:00:00 2001 From: Nicolas Sanz Date: Thu, 4 Apr 2013 15:21:06 -0300 Subject: [PATCH 3/3] Initialize the SP with the upper part to 0, cause gcc problem to get 3byte PC --- arduino.DuinOS/DuinOS/port.c | 54 ++++++++++++++---------------------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/arduino.DuinOS/DuinOS/port.c b/arduino.DuinOS/DuinOS/port.c index b98da00..3835396 100644 --- a/arduino.DuinOS/DuinOS/port.c +++ b/arduino.DuinOS/DuinOS/port.c @@ -262,16 +262,11 @@ static void prvSetupTimerInterrupt( void ); */ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) { -/* CDCP - * __AVR_3_BYTE_PC__ is not official, and only exist after version 4.1 of GCC - */ -#if defined(__AVR_HAVE_RAMPZ__) || defined(__AVR_3_BYTE_PC__) - unsigned portLONG usAddress; // ATMega2560 have 17bit Program Counter register - // Other future uControler can have up 22, or 24 bits. -#else - unsigned portSHORT usAddress; // over ATmega have 16bit Program Counter register -#endif - + /* ATmega2560 DuinOS port by SkyWodd + * Corrected by NiesteSzeck + * Edited defines evaluation as proposed by CDCP + * */ + unsigned portSHORT usAddress; // over ATmega have 16bit Program Counter register /* Place a few bytes of known values on the bottom of the stack. This is just useful for debugging. */ @@ -288,26 +283,6 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */ -/* CDCP - * __AVR_3_BYTE_PC__ is not official - */ -#if defined(__AVR_HAVE_RAMPZ__) || defined(__AVR_3_BYTE_PC__) - // Implement normal stack initialisation but with portLONG instead of portSHORT - usAddress = ( unsigned portLONG ) pxCode; - *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff ); - pxTopOfStack--; - - usAddress >>= 8; - *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff ); - pxTopOfStack--; - - // Implemented the 3byte addressing - usAddress >>= 8; - *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portLONG ) 0x000000ff ); - pxTopOfStack--; - -// Normal initialisation for over ATmega -#else /* The start of the task code will be popped off the stack last, so place it on first. */ usAddress = ( unsigned portSHORT ) pxCode; @@ -317,6 +292,19 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE usAddress >>= 8; *pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff ); pxTopOfStack--; +#if defined(__AVR_HAVE_RAMPZ__) || defined(__AVR_3_BYTE_PC__) + /* + ***** __AVR_3_BYTE_PC__ is not official, and only exist after version 4.1 of GCC + Implemented the 3byte addressing, it will be 0 'cause avr gcc dosn't return a 3 byte PC + It only return as 2 byte PC. 'cause of this problem with gcc we should put all the task functions + declarations in the above 64K word memory (128KBi) + Based work at + http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=70387 + http://feilipu.posterous.com/ethermega-arduino-mega-2560-and-freertos + Refer to SiezeofPC example to check the size of the function pointer + */ + *pxTopOfStack = ( portSTACK_TYPE ) ( 0x0000 ); + pxTopOfStack--; #endif /* Next simulate the stack as if after a call to portSAVE_CONTEXT(). @@ -328,14 +316,14 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE *pxTopOfStack = portFLAGS_INT_ENABLED; pxTopOfStack--; - /* CDCP - begin*/ #if defined(__AVR_HAVE_RAMPZ__) - /* + /* CDCP: * have RAMPZ Extended Z-pointer Register for ELPM/SPM * the uC have extend program memory */ - /* The Atmega2560 has two more register that we are saving + /* Niesteszeck: + * The Atmega2560 has two more register that we are saving * The EIND and RAMPZ and we are going to initialize * this registers to 0 (default initial values) */