diff --git a/portable/GCC/ATmegaxxxx/port.c b/portable/GCC/ATmegaxxxx/port.c index 3885528b3..7889e68b1 100644 --- a/portable/GCC/ATmegaxxxx/port.c +++ b/portable/GCC/ATmegaxxxx/port.c @@ -216,14 +216,14 @@ void wdt_interrupt_reset_enable (const uint8_t value) * * r0 is set to __tmp_reg__ as the compiler expects it to be thus. * - * #if defined(__AVR_3_BYTE_PC__) - * #define __EIND__ 0x3C - * #endif - * * #if defined(__AVR_HAVE_RAMPZ__) * #define __RAMPZ__ 0x3B * #endif * + * #if defined(__AVR_3_BYTE_PC__) + * #define __EIND__ 0x3C + * #endif + * * The interrupts will have been disabled during the call to portSAVE_CONTEXT() * so we need not worry about reading/writing to the stack pointer. */ @@ -277,14 +277,14 @@ void wdt_interrupt_reset_enable (const uint8_t value) "in __tmp_reg__, __SP_H__ \n\t" \ "st x+, __tmp_reg__ \n\t" \ ); -#elif defined(__AVR_3_BYTE_PC__) -/* 3-Byte PC Save */ +#elif defined(__AVR_HAVE_RAMPZ__) +/* 2-Byte PC Save with RAMPZ */ #define portSAVE_CONTEXT() \ __asm__ __volatile__ ( "push __tmp_reg__ \n\t" \ "in __tmp_reg__, __SREG__ \n\t" \ "cli \n\t" \ "push __tmp_reg__ \n\t" \ - "in __tmp_reg__, 0x3C \n\t" \ + "in __tmp_reg__, 0x3B \n\t" \ "push __tmp_reg__ \n\t" \ "push __zero_reg__ \n\t" \ "clr __zero_reg__ \n\t" \ @@ -425,8 +425,8 @@ void wdt_interrupt_reset_enable (const uint8_t value) "out __SREG__, __tmp_reg__ \n\t" \ "pop __tmp_reg__ \n\t" \ ); -#elif defined(__AVR_3_BYTE_PC__) -/* 3-Byte PC Restore with RAMPZ */ +#elif defined(__AVR_HAVE_RAMPZ__) +/* 2-Byte PC Restore with RAMPZ */ #define portRESTORE_CONTEXT() \ __asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \ "lds r27, pxCurrentTCB + 1 \n\t" \ @@ -466,7 +466,7 @@ void wdt_interrupt_reset_enable (const uint8_t value) "pop r2 \n\t" \ "pop __zero_reg__ \n\t" \ "pop __tmp_reg__ \n\t" \ - "out 0x3C, __tmp_reg__ \n\t" \ + "out 0x3B, __tmp_reg__ \n\t" \ "pop __tmp_reg__ \n\t" \ "out __SREG__, __tmp_reg__ \n\t" \ "pop __tmp_reg__ \n\t" \ @@ -591,7 +591,7 @@ uint16_t usAddress; #endif #if defined(__AVR_HAVE_RAMPZ__) - /* If we have an ATmega2560, we are also saving the RAMPZ register. + /* We are saving the RAMPZ register. * We should default to 0. */ *pxTopOfStack = ( StackType_t ) 0x00; /* RAMPZ */ @@ -814,8 +814,8 @@ uint8_t ucLowByte; * */ ISR(portSCHEDULER_ISR, ISR_NAKED) __attribute__ ((hot, flatten)); -/* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten)); */ - +/* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten)); + */ ISR(portSCHEDULER_ISR) { vPortYieldFromTick(); @@ -831,8 +831,8 @@ uint8_t ucLowByte; * use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler. */ ISR(portSCHEDULER_ISR) __attribute__ ((hot, flatten)); -/* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten)); */ - +/* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten)); + */ ISR(portSCHEDULER_ISR) { xTaskIncrementTick(); diff --git a/portable/GCC/ATmegaxxxx/readme.md b/portable/GCC/ATmegaxxxx/readme.md index 1d502e890..22fd6e6c6 100644 --- a/portable/GCC/ATmegaxxxx/readme.md +++ b/portable/GCC/ATmegaxxxx/readme.md @@ -12,7 +12,7 @@ This initial commit contains the information required to build with System Tick Further commits can add support for 16-bit Timers available on many relevant devices. The availability of these 16-bit Timers is somewhat device specific, and these complex and highly configurable Timers are often used to generate phase correct PWM timing (for example) and they would be wasted as a simple System Tick. -The port also provides support for the 3 byte program counter devices __ATmega2560__ and __ATmega2561__. Specific to these two devices the `RAMPZ` and `EIND` registers need to be preserved during a context switch. Also, due to a limitation in GCC, the scheduler needs to reside in the lower 128kB of flash for both of these devices. This is achieved by adding the `.lowtext` section attribute to the function prototype. +The port also provides support for the 3 byte program counter devices __ATmega2560__ and __ATmega2561__. Specific to these two devices the `EIND` register need to be preserved during a context switch. Also, due to a limitation in GCC, the scheduler needs to reside in the lower 128kB of flash for both of these devices. This is achieved by adding the `.lowtext` section attribute to the function prototype. To build generic Microchip (AVR) ATmega support the similarities across the family must be considered, and differences respected. Some comments on the strategy follow. @@ -37,6 +37,8 @@ The ATtiny, ATmega, ATxmega families can optionally support both 3 byte PC and 3 - providing `portSAVE_CONTEXT()` and `portRESTORE_CONTEXT` saving both the __RAMPZ__ and __EIND__ registers. - providing a `portTASK_FUNCTION_PROTO()` with the linker attribute `.lowtext` which is used to ensure that the scheduler and relevant functions remain in the lower 128kB of Flash. +For devices which can support __XRAM__ and have the __RAMPZ__ register, this register is also preserved during the context switch. +

Interrupt Nesting

The ATmega family does not support interrupt nesting, having only one interrupt priority. This means that when the Scheduler is running, interrupts are normally disabled. @@ -61,6 +63,8 @@ if( __malloc_heap_end == 0 ) ``` Unfortunately in the repository there is nowhere sensible to include this statement as it should be included early in the `main()` function. +For devices which can support __XRAM__ the user will need to tune the location of stack and heap according to their own requirements. +

Supported Devices

ATmega devices with __ENHANCED WDT__ Interrupt capability - will use WDT.