mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-12 00:57:44 -04:00
ATmegaxxxx - refine RAMPZ configuration
This commit is contained in:
parent
5052273cd7
commit
fa8cde691f
2 changed files with 20 additions and 16 deletions
|
@ -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.
|
* 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__)
|
* #if defined(__AVR_HAVE_RAMPZ__)
|
||||||
* #define __RAMPZ__ 0x3B
|
* #define __RAMPZ__ 0x3B
|
||||||
* #endif
|
* #endif
|
||||||
*
|
*
|
||||||
|
* #if defined(__AVR_3_BYTE_PC__)
|
||||||
|
* #define __EIND__ 0x3C
|
||||||
|
* #endif
|
||||||
|
*
|
||||||
* The interrupts will have been disabled during the call to portSAVE_CONTEXT()
|
* The interrupts will have been disabled during the call to portSAVE_CONTEXT()
|
||||||
* so we need not worry about reading/writing to the stack pointer.
|
* 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" \
|
"in __tmp_reg__, __SP_H__ \n\t" \
|
||||||
"st x+, __tmp_reg__ \n\t" \
|
"st x+, __tmp_reg__ \n\t" \
|
||||||
);
|
);
|
||||||
#elif defined(__AVR_3_BYTE_PC__)
|
#elif defined(__AVR_HAVE_RAMPZ__)
|
||||||
/* 3-Byte PC Save */
|
/* 2-Byte PC Save with RAMPZ */
|
||||||
#define portSAVE_CONTEXT() \
|
#define portSAVE_CONTEXT() \
|
||||||
__asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
|
__asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
|
||||||
"in __tmp_reg__, __SREG__ \n\t" \
|
"in __tmp_reg__, __SREG__ \n\t" \
|
||||||
"cli \n\t" \
|
"cli \n\t" \
|
||||||
"push __tmp_reg__ \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 __tmp_reg__ \n\t" \
|
||||||
"push __zero_reg__ \n\t" \
|
"push __zero_reg__ \n\t" \
|
||||||
"clr __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" \
|
"out __SREG__, __tmp_reg__ \n\t" \
|
||||||
"pop __tmp_reg__ \n\t" \
|
"pop __tmp_reg__ \n\t" \
|
||||||
);
|
);
|
||||||
#elif defined(__AVR_3_BYTE_PC__)
|
#elif defined(__AVR_HAVE_RAMPZ__)
|
||||||
/* 3-Byte PC Restore with RAMPZ */
|
/* 2-Byte PC Restore with RAMPZ */
|
||||||
#define portRESTORE_CONTEXT() \
|
#define portRESTORE_CONTEXT() \
|
||||||
__asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
|
__asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
|
||||||
"lds r27, pxCurrentTCB + 1 \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 r2 \n\t" \
|
||||||
"pop __zero_reg__ \n\t" \
|
"pop __zero_reg__ \n\t" \
|
||||||
"pop __tmp_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" \
|
"pop __tmp_reg__ \n\t" \
|
||||||
"out __SREG__, __tmp_reg__ \n\t" \
|
"out __SREG__, __tmp_reg__ \n\t" \
|
||||||
"pop __tmp_reg__ \n\t" \
|
"pop __tmp_reg__ \n\t" \
|
||||||
|
@ -591,7 +591,7 @@ uint16_t usAddress;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__AVR_HAVE_RAMPZ__)
|
#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.
|
* We should default to 0.
|
||||||
*/
|
*/
|
||||||
*pxTopOfStack = ( StackType_t ) 0x00; /* RAMPZ */
|
*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) __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)
|
ISR(portSCHEDULER_ISR)
|
||||||
{
|
{
|
||||||
vPortYieldFromTick();
|
vPortYieldFromTick();
|
||||||
|
@ -831,8 +831,8 @@ uint8_t ucLowByte;
|
||||||
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
|
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
|
||||||
*/
|
*/
|
||||||
ISR(portSCHEDULER_ISR) __attribute__ ((hot, flatten));
|
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)
|
ISR(portSCHEDULER_ISR)
|
||||||
{
|
{
|
||||||
xTaskIncrementTick();
|
xTaskIncrementTick();
|
||||||
|
|
|
@ -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.
|
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.
|
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 `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.
|
- 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>
|
<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.
|
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.
|
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>
|
<h3>Supported Devices</h3>
|
||||||
|
|
||||||
ATmega devices with __ENHANCED WDT__ Interrupt capability - will use WDT.
|
ATmega devices with __ENHANCED WDT__ Interrupt capability - will use WDT.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue