Skip to content

Commit 50f39cc

Browse files
committed
🚀 finish up AVR support
1 parent 33eaa51 commit 50f39cc

24 files changed

Lines changed: 825 additions & 211 deletions

Include/Platform/AVR/Chip/ATMEGA1284P/rmp_platform_atmega1284p.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Description: The configuration file for ATMEGA1284P.
2727
#define RMP_INT_MASK() RMP_Int_Disable()
2828
#define RMP_INT_UNMASK() RMP_Int_Enable()
2929

30-
/* What is the Systick value? */
30+
/* What is the Systick value? 50U = 12800 cycles = 0.8ms */
3131
#define RMP_AVR_TICK_VAL (50U)
3232
/* Does the chip have RAMP, EIND, and is it XMEGA? */
3333
#define RMP_AVR_COP_RAMP (1U)
@@ -41,18 +41,32 @@ Description: The configuration file for ATMEGA1284P.
4141
#define RMP_AVR_LOWLVL_INIT() \
4242
do \
4343
{ \
44-
/* No need to set clock because we have fuse bits */ \
45-
\
46-
/* Initialize serial */ \
44+
/* USART0 TX pin - PD1 */ \
45+
DDRD=0x02U; \
46+
/* USART0 - double speed, TX only, 115200-8-N-1 */ \
47+
UCSR0A=0x02U; \
48+
UCSR0B=0x08U; \
49+
UCSR0C=0x06U; \
50+
UBRR0=16U; \
51+
/* Timer 0 - CTC mode, UP counter, prescaler 256 */ \
52+
TCNT0=0x00U; \
53+
OCR0A=RMP_AVR_TICK_VAL; \
54+
TIFR0=0x00U; \
55+
TCCR0A=0x02U; \
56+
TCCR0B=0x04U; \
57+
TIMSK0=0x02U; \
4758
} \
4859
while(0)
4960

50-
#define RMP_AVR_TIM_CLR()
61+
#define RMP_AVR_TIM_CLR() (TIFR0=0x00U)
5162

5263
/* This is for debugging output */
5364
#define RMP_AVR_PUTCHAR(CHAR) \
5465
do \
5566
{ \
67+
/* Wait for transmit buffer to be empty */ \
68+
while((UCSR0A&0x20U)==0U); \
69+
UDR0=(CHAR); \
5670
} \
5771
while(0)
5872
/* End Define ****************************************************************/

Include/Platform/AVR/Chip/ATMEGA2560/rmp_platform_atmega2560.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Description: The configuration file for ATMEGA2560.
77
******************************************************************************/
88

99
/* Define ********************************************************************/
10-
/* The HAL library */
10+
/* The AVR I/O library */
1111
#include "avr/io.h"
1212

1313
/* Debugging */
@@ -27,8 +27,8 @@ Description: The configuration file for ATMEGA2560.
2727
#define RMP_INT_MASK() RMP_Int_Disable()
2828
#define RMP_INT_UNMASK() RMP_Int_Enable()
2929

30-
/* What is the Systick value? */
31-
#define RMP_AVR_TICK_VAL (2000U)
30+
/* What is the Systick value? 50U = 12800 cycles = 0.8ms */
31+
#define RMP_AVR_TICK_VAL (50U)
3232
/* Does the chip have RAMP, EIND, and is it XMEGA? */
3333
#define RMP_AVR_COP_RAMP (1U)
3434
#define RMP_AVR_COP_EIND (1U)
@@ -41,15 +41,32 @@ Description: The configuration file for ATMEGA2560.
4141
#define RMP_AVR_LOWLVL_INIT() \
4242
do \
4343
{ \
44+
/* USART0 TX pin - PE1 */ \
45+
DDRE=0x02U; \
46+
/* USART0 - double speed, TX only, 115200-8-N-1 */ \
47+
UCSR0A=0x02U; \
48+
UCSR0B=0x08U; \
49+
UCSR0C=0x06U; \
50+
UBRR0=16U; \
51+
/* Timer 0 - CTC mode, UP counter, prescaler 256 */ \
52+
TCNT0=0x00U; \
53+
OCR0A=RMP_AVR_TICK_VAL; \
54+
TIFR0=0x00U; \
55+
TCCR0A=0x02U; \
56+
TCCR0B=0x04U; \
57+
TIMSK0=0x02U; \
4458
} \
4559
while(0)
4660

47-
#define RMP_AVR_TIM_CLR()
61+
#define RMP_AVR_TIM_CLR() (TIFR0=0x00U)
4862

4963
/* This is for debugging output */
5064
#define RMP_AVR_PUTCHAR(CHAR) \
5165
do \
5266
{ \
67+
/* Wait for transmit buffer to be empty */ \
68+
while((UCSR0A&0x20U)==0U); \
69+
UDR0=(CHAR); \
5370
} \
5471
while(0)
5572
/* End Define ****************************************************************/

Include/Platform/AVR/rmp_platform_avr.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,23 @@ Date : 01/04/2017
55
Licence : The Unlicense; see LICENSE for details.
66
Description : The header of "rmp_platform_avr.c".
77
This port supports both MegaAVR and XMegaAVR but not TinyAVR.
8+
Supported cores include AVRe, AVRe+, AVRxm and AVRxt.
89
Please refrain from trying to use this port on chips that has
910
less than 32kB of Flash, because the kernel uses about 16kB.
1011
In contrast, the IAR compiler is expected to generate less code
1112
through the extensive use of static overlay (rather than the GCC
1213
software stack as most 8-bitters lack SP-relative addressing),
1314
however this scheme precludes the porting of the kernel.
1415
This port is supplied as a proof of existence of RMP on even
15-
8-bit devices rather than to be used in a production setting.
16+
8-bit devices rather than to be used in a production setting;
17+
AVR is not particularly great in term of code density when
18+
compared with other 8-bitters such as PIC, STM8, and even 8051.
19+
All kernel functions assume zero for all RAMP/EIND segment
20+
registers; still, they are saved and restored as a part of the
21+
context switch, and are cleared before calling any ISR written
22+
in C. This is in accordance with the GCC's use of these registers,
23+
and the user is responsible for clearing them when they are
24+
changed before calling the kernel APIs.
1625
******************************************************************************/
1726

1827
/* Define ********************************************************************/
@@ -151,11 +160,12 @@ struct RMP_AVR_Stack
151160
rmp_u8_t R29_YH;
152161
rmp_u8_t R30_ZL;
153162
rmp_u8_t R31_ZH;
154-
rmp_u8_t PCL;
155-
rmp_u8_t PCH;
163+
/* Big-endian for CALL and interrupt entry PC */
156164
#if(RMP_AVR_COP_EIND!=0U)
157165
rmp_u8_t PCU;
158166
#endif
167+
rmp_u8_t PCH;
168+
rmp_u8_t PCL;
159169
};
160170
/*****************************************************************************/
161171
/* __RMP_PLATFORM_AVR_STRUCT__ */

Include/Platform/AVR/rmp_platform_avr_gcc.inc

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and
2828
.extern _RMP_AVR_SP_Kern
2929
/* The current thread stack */
3030
.extern RMP_SP_Cur
31-
;The interrupt active flag
31+
/* The interrupt active flag */
3232
.extern RMP_AVR_Int_Act
33-
;The yield pending flag
33+
/* The yield pending flag */
3434
.extern _RMP_AVR_Yield_Pend
35-
;Extract highest priority running thread
35+
/* Extract highest priority running thread */
3636
.extern _RMP_Run_High
37-
;Handler for DSPIC timer interrupt
37+
/* Handler for DSPIC timer interrupt */
3838
.extern _RMP_AVR_Tim_Handler
3939
/* End Import ****************************************************************/
4040

@@ -79,45 +79,34 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and
7979

8080
/* Actual context switch *****************************************************/
8181
.macro RMP_AVR_SWITCH_PRE
82-
IN R18,RMP_SPL /* Save the SP to control block */
83-
IN R19,RMP_SPH
84-
LDI R28,lo8(RMP_SP_Cur) /* Y[29:28] is Callee-save */
85-
LDI R29,hi8(RMP_SP_Cur)
86-
ST Y,R18
87-
STD Y+1,R19
88-
LDI R30,lo8(_RMP_AVR_SP_Kern) /* Load SP for kernel */
89-
LDI R31,hi8(_RMP_AVR_SP_Kern)
90-
LD R18,Z
91-
LDD R19,Z+1
92-
OUT RMP_SPL,R18
82+
IN R19,RMP_SPH /* Save the SP to control block */
83+
IN R18,RMP_SPL
84+
STS RMP_SP_Cur+1,R19
85+
STS RMP_SP_Cur,R18
86+
LDS R19,_RMP_AVR_SP_Kern+1 /* Load SP for kernel */
87+
LDS R18,_RMP_AVR_SP_Kern
9388
OUT RMP_SPH,R19
94-
LDI R30,lo8(RMP_AVR_Int_Act) /* Indicate interrupt active */
95-
LDI R31,hi8(RMP_AVR_Int_Act)
96-
LDI R18,1
97-
ST Z,R18
89+
OUT RMP_SPL,R18
90+
LDI R18,1 /* Indicate interrupt active */
91+
STS RMP_AVR_Int_Act,R18
92+
EOR R1,R1 /* Clear implicit zero register */
9893
.endm
9994

10095
/* Actual context switch *****************************************************/
10196
.macro RMP_AVR_SWITCH_POST
102-
LDI R30,lo8(_RMP_AVR_Yield_Pend)
103-
LDI R31,hi8(_RMP_AVR_Yield_Pend)
104-
LD R18,Z
97+
LDS R18,_RMP_AVR_Yield_Pend
10598
CPI R18,0
10699
BREQ 1f
107-
LDI R18,0
108-
ST Z,R18
109-
LDI R30,lo8(_RMP_Run_High)
110-
LDI R31,hi8(_RMP_Run_High)
111-
ICALL
100+
EOR R18,R18
101+
STS _RMP_AVR_Yield_Pend,R18
102+
CALL _RMP_Run_High /* No need to clean R1 again */
112103
1:
113-
LDI R30,lo8(RMP_AVR_Int_Act)
114-
LDI R31,hi8(RMP_AVR_Int_Act)
115-
LDI R18,0
116-
ST Z,R18
117-
LD R18,Y /* Load the SP from control block */
118-
LDD R19,Y+1 /* Y[29:28] is Callee-save */
119-
OUT RMP_SPL,R18
104+
EOR R18,R18
105+
STS RMP_AVR_Int_Act,R18
106+
LDS R19,RMP_SP_Cur+1 /* Load the SP from control block */
107+
LDS R18,RMP_SP_Cur
120108
OUT RMP_SPH,R19
109+
OUT RMP_SPL,R18
121110
.endm
122111

123112
/* Restore all GP regs *******************************************************/
@@ -169,7 +158,7 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and
169158
PUSH R20
170159
PUSH R19
171160
PUSH R18
172-
LDI R18,0x00
161+
EOR R18,R18
173162
OUT RMP_RAMPD,R18
174163
OUT RMP_RAMPX,R18
175164
OUT RMP_RAMPY,R18
@@ -192,7 +181,7 @@ Description : The assembly part of the RMP RTOS. This is for AVR, and
192181
.macro RMP_AVR_EIND_SAVE
193182
IN R18,RMP_EIND
194183
PUSH R18
195-
LDI R18,0x00
184+
EOR R18,R18
196185
OUT RMP_EIND,R18
197186
.endm
198187

Include/Test/Chip/rmp_test_atmega1284p.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,45 @@ Author : pry
44
Date : 22/07/2017
55
Licence : The Unlicense; see LICENSE for details.
66
Description : The testbench for ATMEGA1284P.
7+
This test takes 1 min @16 MHz. Just observe how slow the AVR is.
8+
9+
GCC 4.7.4 (Atmel Studio GNU 5.4.0) -O3
10+
___ __ ___ ___
11+
/ _ \ / |/ // _ \ Simple real-time kernel
12+
/ , _// /|_/ // ___/ Standard benchmark test
13+
/_/|_|/_/ /_//_/
14+
====================================================
15+
Test (number in CPU cycles) : AVG / MAX / MIN
16+
Yield : 437 / 739 / 437
17+
Mailbox : 751 / 1036 / 734
18+
Semaphore : 717 / 1003 / 701
19+
FIFO : 314 / 609 / 307
20+
Message queue : 1098 / 1375 / 1073
21+
Blocking message queue : 1352 / 1623 / 1321
22+
Memory allocation/free pair : 1680 / 1809 / 1558
23+
ISR Mailbox : 637 / 922 / 620
24+
ISR Semaphore : 639 / 924 / 622
25+
ISR Message queue : 921 / 1198 / 896
26+
ISR Blocking message queue : 1087 / 1361 / 1059
27+
28+
GCC 4.7.4 (Atmel Studio GNU 5.4.0) -Os -mcall-prologues
29+
___ __ ___ ___
30+
/ _ \ / |/ // _ \ Simple real-time kernel
31+
/ , _// /|_/ // ___/ Standard benchmark test
32+
/_/|_|/_/ /_//_/
33+
====================================================
34+
Test (number in CPU cycles) : AVG / MAX / MIN
35+
Yield : 428 / 705 / 428
36+
Mailbox : 793 / 1054 / 777
37+
Semaphore : 740 / 1002 / 725
38+
FIFO : 314 / 585 / 308
39+
Message queue : 1193 / 1445 / 1168
40+
Blocking message queue : 1522 / 1767 / 1490
41+
Memory allocation/free pair : 2220 / 2354 / 2097
42+
ISR Mailbox : 671 / 931 / 654
43+
ISR Semaphore : 634 / 895 / 618
44+
ISR Message queue : 944 / 1198 / 921
45+
ISR Blocking message queue : 1132 / 1382 / 1105
746
******************************************************************************/
847

948
/* Include *******************************************************************/
@@ -44,6 +83,10 @@ Return : None.
4483
void Timer_Init(void)
4584
{
4685
/* TIM1 clock = CPU clock */
86+
TCCR1A=0x00U;
87+
TCCR1B=0x01U;
88+
TCCR1C=0x00U;
89+
TCNT1=0x0000U;
4790
}
4891
/* End Function:Timer_Init ***************************************************/
4992

@@ -57,11 +100,18 @@ Return : None.
57100
void Int_Init(void)
58101
{
59102
/* TIM2 clock = 1/256 CPU clock */
103+
TCNT2=0x00U;
104+
OCR2A=100U;
105+
TIFR2=0x00U;
106+
TCCR2A=0x02U;
107+
TCCR2B=0x04U;
108+
TIMSK2=0x02U;
60109
}
61110

62111
/* The interrupt handler */
63112
void TIM2_Handler(void)
64113
{
114+
TIFR2=0x00U;
65115
Int_Handler();
66116
}
67117
/* End Function:Int_Init *****************************************************/
@@ -75,7 +125,7 @@ Return : None.
75125
******************************************************************************/
76126
void Int_Disable(void)
77127
{
78-
128+
TIMSK2=0x00U;
79129
}
80130
#endif
81131
/* End Function:Int_Disable **************************************************/

0 commit comments

Comments
 (0)