Skip to content

Commit 64da512

Browse files
committed
align with ATmegaxxxx PR#48
1 parent 373a099 commit 64da512

File tree

4 files changed

+149
-54
lines changed

4 files changed

+149
-54
lines changed

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=FreeRTOS
2-
version=10.3.0-5
2+
version=10.3.0-6
33
author=Richard Barry <info@freertos.org>
44
maintainer=Phillip Stevens <phillip.stevens@gmail.com>
55
sentence=<h3>FreeRTOS Real Time Operating System implemented for AVR (Uno, Leonardo, Mega) </h3>

src/mpu_wrappers.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,22 +176,10 @@ only for ports that are using the MPU. */
176176

177177
#else /* portUSING_MPU_WRAPPERS */
178178

179-
#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) // Mega with 2560
180179
#define PRIVILEGED_FUNCTION __attribute__ ((hot))
181180
#define PRIVILEGED_DATA
182181
#define FREERTOS_SYSTEM_CALL __attribute__ ((hot))
183182
#define portUSING_MPU_WRAPPERS 0
184-
#elif defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega664P__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284PA__) // Goldilocks with 1284p
185-
#define PRIVILEGED_FUNCTION __attribute__ ((hot))
186-
#define PRIVILEGED_DATA
187-
#define FREERTOS_SYSTEM_CALL __attribute__ ((hot))
188-
#define portUSING_MPU_WRAPPERS 0
189-
#else // Uno with 328p or Leonardo with 32u4
190-
#define PRIVILEGED_FUNCTION __attribute__ ((hot))
191-
#define PRIVILEGED_DATA
192-
#define FREERTOS_SYSTEM_CALL __attribute__ ((hot))
193-
#define portUSING_MPU_WRAPPERS 0
194-
#endif
195183

196184
#endif /* portUSING_MPU_WRAPPERS */
197185

src/port.c

Lines changed: 125 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
/* Start tasks with interrupts enabled. */
4242
#define portFLAGS_INT_ENABLED ( (StackType_t) 0x80 )
4343

44-
#define portSCHEDULER_ISR WDT_vect
44+
#define portSCHEDULER_ISR WDT_vect
4545

4646
/*-----------------------------------------------------------*/
4747

@@ -72,16 +72,19 @@ static void prvSetupTimerInterrupt( void );
7272
*
7373
* r0 is set to __tmp_reg__ as the compiler expects it to be thus.
7474
*
75-
* #if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
75+
* #if defined(__AVR_HAVE_RAMPZ__)
7676
* #define __RAMPZ__ 0x3B
77+
* #endif
78+
*
79+
* #if defined(__AVR_3_BYTE_PC__)
7780
* #define __EIND__ 0x3C
7881
* #endif
7982
*
8083
* The interrupts will have been disabled during the call to portSAVE_CONTEXT()
8184
* so we need not worry about reading/writing to the stack pointer.
8285
*/
83-
#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
84-
/* 3-Byte PC Save */
86+
#if defined(__AVR_3_BYTE_PC__) && defined(__AVR_HAVE_RAMPZ__)
87+
/* 3-Byte PC Save with RAMPZ */
8588
#define portSAVE_CONTEXT() \
8689
__asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
8790
"in __tmp_reg__, __SREG__ \n\t" \
@@ -130,6 +133,54 @@ static void prvSetupTimerInterrupt( void );
130133
"in __tmp_reg__, __SP_H__ \n\t" \
131134
"st x+, __tmp_reg__ \n\t" \
132135
);
136+
#elif defined(__AVR_HAVE_RAMPZ__)
137+
/* 2-Byte PC Save with RAMPZ */
138+
#define portSAVE_CONTEXT() \
139+
__asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
140+
"in __tmp_reg__, __SREG__ \n\t" \
141+
"cli \n\t" \
142+
"push __tmp_reg__ \n\t" \
143+
"in __tmp_reg__, 0x3B \n\t" \
144+
"push __tmp_reg__ \n\t" \
145+
"push __zero_reg__ \n\t" \
146+
"clr __zero_reg__ \n\t" \
147+
"push r2 \n\t" \
148+
"push r3 \n\t" \
149+
"push r4 \n\t" \
150+
"push r5 \n\t" \
151+
"push r6 \n\t" \
152+
"push r7 \n\t" \
153+
"push r8 \n\t" \
154+
"push r9 \n\t" \
155+
"push r10 \n\t" \
156+
"push r11 \n\t" \
157+
"push r12 \n\t" \
158+
"push r13 \n\t" \
159+
"push r14 \n\t" \
160+
"push r15 \n\t" \
161+
"push r16 \n\t" \
162+
"push r17 \n\t" \
163+
"push r18 \n\t" \
164+
"push r19 \n\t" \
165+
"push r20 \n\t" \
166+
"push r21 \n\t" \
167+
"push r22 \n\t" \
168+
"push r23 \n\t" \
169+
"push r24 \n\t" \
170+
"push r25 \n\t" \
171+
"push r26 \n\t" \
172+
"push r27 \n\t" \
173+
"push r28 \n\t" \
174+
"push r29 \n\t" \
175+
"push r30 \n\t" \
176+
"push r31 \n\t" \
177+
"lds r26, pxCurrentTCB \n\t" \
178+
"lds r27, pxCurrentTCB + 1 \n\t" \
179+
"in __tmp_reg__, __SP_L__ \n\t" \
180+
"st x+, __tmp_reg__ \n\t" \
181+
"in __tmp_reg__, __SP_H__ \n\t" \
182+
"st x+, __tmp_reg__ \n\t" \
183+
);
133184
#else
134185
/* 2-Byte PC Save */
135186
#define portSAVE_CONTEXT() \
@@ -182,8 +233,8 @@ static void prvSetupTimerInterrupt( void );
182233
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
183234
* the context save so we can write to the stack pointer.
184235
*/
185-
#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
186-
/* 3-Byte PC Restore */
236+
#if defined(__AVR_3_BYTE_PC__) && defined(__AVR_HAVE_RAMPZ__)
237+
/* 3-Byte PC Restore with RAMPZ */
187238
#define portRESTORE_CONTEXT() \
188239
__asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
189240
"lds r27, pxCurrentTCB + 1 \n\t" \
@@ -230,6 +281,52 @@ static void prvSetupTimerInterrupt( void );
230281
"out __SREG__, __tmp_reg__ \n\t" \
231282
"pop __tmp_reg__ \n\t" \
232283
);
284+
#elif defined(__AVR_HAVE_RAMPZ__)
285+
/* 2-Byte PC Restore with RAMPZ */
286+
#define portRESTORE_CONTEXT() \
287+
__asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
288+
"lds r27, pxCurrentTCB + 1 \n\t" \
289+
"ld r28, x+ \n\t" \
290+
"out __SP_L__, r28 \n\t" \
291+
"ld r29, x+ \n\t" \
292+
"out __SP_H__, r29 \n\t" \
293+
"pop r31 \n\t" \
294+
"pop r30 \n\t" \
295+
"pop r29 \n\t" \
296+
"pop r28 \n\t" \
297+
"pop r27 \n\t" \
298+
"pop r26 \n\t" \
299+
"pop r25 \n\t" \
300+
"pop r24 \n\t" \
301+
"pop r23 \n\t" \
302+
"pop r22 \n\t" \
303+
"pop r21 \n\t" \
304+
"pop r20 \n\t" \
305+
"pop r19 \n\t" \
306+
"pop r18 \n\t" \
307+
"pop r17 \n\t" \
308+
"pop r16 \n\t" \
309+
"pop r15 \n\t" \
310+
"pop r14 \n\t" \
311+
"pop r13 \n\t" \
312+
"pop r12 \n\t" \
313+
"pop r11 \n\t" \
314+
"pop r10 \n\t" \
315+
"pop r9 \n\t" \
316+
"pop r8 \n\t" \
317+
"pop r7 \n\t" \
318+
"pop r6 \n\t" \
319+
"pop r5 \n\t" \
320+
"pop r4 \n\t" \
321+
"pop r3 \n\t" \
322+
"pop r2 \n\t" \
323+
"pop __zero_reg__ \n\t" \
324+
"pop __tmp_reg__ \n\t" \
325+
"out 0x3B, __tmp_reg__ \n\t" \
326+
"pop __tmp_reg__ \n\t" \
327+
"out __SREG__, __tmp_reg__ \n\t" \
328+
"pop __tmp_reg__ \n\t" \
329+
);
233330
#else
234331
/* 2-Byte PC Restore */
235332
#define portRESTORE_CONTEXT() \
@@ -301,7 +398,7 @@ uint16_t usAddress;
301398
/* The start of the task code will be popped off the stack last, so place
302399
it on first. */
303400

304-
#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
401+
#if defined(__AVR_3_BYTE_PC__)
305402
/* The AVR ATmega2560/ATmega2561 have 256KBytes of program memory and a 17-bit
306403
* program counter. When a code address is stored on the stack, it takes 3 bytes
307404
* instead of 2 for the other ATmega* chips.
@@ -341,16 +438,20 @@ uint16_t usAddress;
341438
*pxTopOfStack = portFLAGS_INT_ENABLED;
342439
pxTopOfStack--;
343440

344-
#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
345-
346-
/* If we have an ATmega256x, we are also saving the RAMPZ and EIND registers.
347-
* We should default those to 0.
441+
#if defined(__AVR_3_BYTE_PC__)
442+
/* If we have an ATmega256x, we are also saving the EIND register.
443+
* We should default to 0.
348444
*/
349445
*pxTopOfStack = ( StackType_t ) 0x00; /* EIND */
350446
pxTopOfStack--;
447+
#endif
448+
449+
#if defined(__AVR_HAVE_RAMPZ__)
450+
/* We are saving the RAMPZ register.
451+
* We should default to 0.
452+
*/
351453
*pxTopOfStack = ( StackType_t ) 0x00; /* RAMPZ */
352454
pxTopOfStack--;
353-
354455
#endif
355456

356457
/* Now the remaining registers. The compiler expects R1 to be 0. */
@@ -479,7 +580,7 @@ void vPortYieldFromTick( void )
479580
{
480581
portSAVE_CONTEXT();
481582

482-
sleep_reset(); // reset the sleep_mode() faster than sleep_disable();
583+
sleep_reset(); // reset the sleep_mode() faster than sleep_disable();
483584

484585
if( xTaskIncrementTick() != pdFALSE )
485586
{
@@ -492,13 +593,15 @@ void vPortYieldFromTick( void )
492593
}
493594
/*-----------------------------------------------------------*/
494595

495-
//initialize watchdog
596+
/*
597+
* Setup WDT to generate a tick interrupt.
598+
*/
496599
void prvSetupTimerInterrupt( void )
497600
{
498-
//reset watchdog
601+
/* reset watchdog */
499602
wdt_reset();
500603

501-
//set up WDT Interrupt (rather than the WDT Reset).
604+
/* set up WDT Interrupt (rather than the WDT Reset). */
502605
wdt_interrupt_enable( portUSE_WDTO );
503606
}
504607

@@ -515,14 +618,15 @@ void prvSetupTimerInterrupt( void )
515618
*
516619
*/
517620
ISR(portSCHEDULER_ISR, ISR_NAKED) __attribute__ ((hot, flatten));
518-
// ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
621+
/* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
622+
*/
519623
ISR(portSCHEDULER_ISR)
520624
{
521625
vPortYieldFromTick();
522626
__asm__ __volatile__ ( "reti" );
523627
}
524-
525628
#else
629+
526630
/*
527631
* Tick ISR for the cooperative scheduler. All this does is increment the
528632
* tick count. We don't need to switch context, this can only be done by
@@ -531,10 +635,10 @@ void prvSetupTimerInterrupt( void )
531635
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
532636
*/
533637
ISR(portSCHEDULER_ISR) __attribute__ ((hot, flatten));
534-
// ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
638+
/* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
639+
*/
535640
ISR(portSCHEDULER_ISR)
536641
{
537642
xTaskIncrementTick();
538643
}
539-
540-
#endif // configUSE_PREEMPTION
644+
#endif

src/portmacro.h

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,66 +44,69 @@ extern "C" {
4444

4545
/* Type definitions. */
4646

47-
typedef uint8_t StackType_t;
48-
typedef int8_t BaseType_t;
49-
typedef uint8_t UBaseType_t;
47+
typedef uint8_t StackType_t;
48+
typedef int8_t BaseType_t;
49+
typedef uint8_t UBaseType_t;
5050

5151
#if configUSE_16_BIT_TICKS == 1
52-
typedef uint16_t TickType_t;
53-
#define portMAX_DELAY ( TickType_t ) 0xffff
52+
typedef uint16_t TickType_t;
53+
#define portMAX_DELAY ( TickType_t ) 0xffff
5454
#else
55-
typedef uint32_t TickType_t;
56-
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
55+
typedef uint32_t TickType_t;
56+
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
5757
#endif
5858
/*-----------------------------------------------------------*/
5959

6060
/* Critical section management. */
6161

62-
#define portENTER_CRITICAL() __asm__ __volatile__ ( \
62+
#define portENTER_CRITICAL() __asm__ __volatile__ ( \
6363
"in __tmp_reg__, __SREG__" "\n\t" \
6464
"cli" "\n\t" \
6565
"push __tmp_reg__" "\n\t" \
6666
::: "memory" \
6767
)
6868

6969

70-
#define portEXIT_CRITICAL() __asm__ __volatile__ ( \
70+
#define portEXIT_CRITICAL() __asm__ __volatile__ ( \
7171
"pop __tmp_reg__" "\n\t" \
7272
"out __SREG__, __tmp_reg__" "\n\t" \
7373
::: "memory" \
7474
)
7575

7676

77-
#define portDISABLE_INTERRUPTS() __asm__ __volatile__ ( "cli" ::: "memory")
78-
#define portENABLE_INTERRUPTS() __asm__ __volatile__ ( "sei" ::: "memory")
77+
#define portDISABLE_INTERRUPTS() __asm__ __volatile__ ( "cli" ::: "memory")
78+
#define portENABLE_INTERRUPTS() __asm__ __volatile__ ( "sei" ::: "memory")
7979

8080
/*-----------------------------------------------------------*/
8181

8282
/* Architecture specifics. */
83-
#define portSTACK_GROWTH ( -1 )
84-
#define portBYTE_ALIGNMENT 1
85-
#define portNOP() __asm__ __volatile__ ( "nop" );
8683

8784
#define sleep_reset() do { _SLEEP_CONTROL_REG = 0; } while(0) // reset all sleep_mode() configurations.
8885

86+
#define portSTACK_GROWTH ( -1 )
87+
8988
/* Timing for the scheduler.
9089
* Watchdog Timer is 128kHz nominal,
9190
* but 120 kHz at 5V DC and 25 degrees is actually more accurate,
9291
* from data sheet.
9392
*/
94-
#define portTICK_PERIOD_MS ( (TickType_t) _BV( portUSE_WDTO + 4 ) ) // Inaccurately assuming 128 kHz Watchdog Timer.
93+
#define portTICK_PERIOD_MS ( (TickType_t) _BV( portUSE_WDTO + 4 ) )
9594

95+
#define portBYTE_ALIGNMENT 1
96+
#define portNOP() __asm__ __volatile__ ( "nop" );
9697
/*-----------------------------------------------------------*/
9798

9899
/* Kernel utilities. */
99-
extern void vPortYield( void ) __attribute__ ( ( naked ) );
100-
#define portYIELD() vPortYield()
101-
100+
extern void vPortYield( void ) __attribute__ ( ( naked ) );
101+
#define portYIELD() vPortYield()
102102
/*-----------------------------------------------------------*/
103103

104-
#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
104+
#if defined(__AVR_3_BYTE_PC__)
105105
/* Task function macros as described on the FreeRTOS.org WEB site. */
106-
// This changed to add .lowtext tag for the linker for ATmega2560 and ATmega2561. To make sure they are loaded in low memory.
106+
107+
/* Add .lowtext tag from the avr linker script avr6.x for ATmega2560 and ATmega2561
108+
* to make sure functions are loaded in low memory.
109+
*/
107110
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) __attribute__ ((section (".lowtext")))
108111
#else
109112
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )

0 commit comments

Comments
 (0)