ATmegaxxxx - refine RAMPZ configuration

This commit is contained in:
Phillip Stevens 2020-04-11 14:20:45 +10:00
parent 5052273cd7
commit fa8cde691f
2 changed files with 20 additions and 16 deletions

View file

@ -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();

View file

@ -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.
<h3>Interrupt Nesting</h3>
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.
<h3>Supported Devices</h3>
ATmega devices with __ENHANCED WDT__ Interrupt capability - will use WDT.