diff options
-rw-r--r-- | demos/ARM7-LPC214x-GCC/chcore.h | 73 | ||||
-rw-r--r-- | demos/ARM7-LPC214x-GCC/chcore2.s | 12 | ||||
-rw-r--r-- | demos/AVR-AT90CANx-GCC/chcore.c | 4 | ||||
-rw-r--r-- | demos/AVR-AT90CANx-GCC/chcore.h | 18 | ||||
-rw-r--r-- | demos/AVR-AT90CANx-GCC/main.c | 14 | ||||
-rw-r--r-- | demos/Win32-MSVS/chcore.c | 2 | ||||
-rw-r--r-- | demos/Win32-MSVS/chcore.h | 5 | ||||
-rw-r--r-- | demos/Win32-MSVS/demo.c | 39 | ||||
-rw-r--r-- | demos/Win32-MinGW/chcore.c | 4 | ||||
-rw-r--r-- | demos/Win32-MinGW/chcore.h | 5 | ||||
-rw-r--r-- | demos/Win32-MinGW/demo.c | 39 | ||||
-rw-r--r-- | readme.txt | 15 |
12 files changed, 103 insertions, 127 deletions
diff --git a/demos/ARM7-LPC214x-GCC/chcore.h b/demos/ARM7-LPC214x-GCC/chcore.h index 7aef95d12..268cae39b 100644 --- a/demos/ARM7-LPC214x-GCC/chcore.h +++ b/demos/ARM7-LPC214x-GCC/chcore.h @@ -31,9 +31,22 @@ typedef void *regarm;
/*
- * Stack saved context.
+ * Interrupt saved context.
*/
-struct stackregs {
+struct extctx {
+ regarm spsr_irq;
+ regarm lr_irq;
+ regarm r0;
+ regarm r1;
+ regarm r2;
+ regarm r3;
+ regarm r12;
+};
+
+/*
+ * System saved context.
+ */
+struct intctx {
regarm r4;
regarm r5;
regarm r6;
@@ -47,42 +60,25 @@ struct stackregs { regarm lr;
};
+/*
+ * Port dependent part of the Thread structure, you may add fields in
+ * this structure.
+ */
typedef struct {
- struct stackregs *r13;
+ struct intctx *r13;
} Context;
-#ifdef CH_CURRP_REGISTER_CACHE
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) \
-{ \
- tp->p_ctx.r13 = (struct stackregs *)((BYTE8 *)workspace + \
- wsize - \
- sizeof(struct stackregs)); \
- tp->p_ctx.r13->r4 = pf; \
- tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->r6 = 0; \
- tp->p_ctx.r13->r8 = 0; \
- tp->p_ctx.r13->r9 = 0; \
- tp->p_ctx.r13->r10 = 0; \
- tp->p_ctx.r13->r11 = 0; \
- tp->p_ctx.r13->lr = threadstart; \
-}
-#else
-#define SETUP_CONTEXT(workspace, wsize, pf, arg) \
-{ \
- tp->p_ctx.r13 = (struct stackregs *)((BYTE8 *)workspace + \
- wsize - \
- sizeof(struct stackregs)); \
+/*
+ * Platform dependent part of the \p chThdCreate() API.
+ */
+#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
+ tp->p_ctx.r13 = (struct intctx *)((BYTE8 *)workspace + \
+ wsize - \
+ sizeof(struct intctx)); \
tp->p_ctx.r13->r4 = pf; \
tp->p_ctx.r13->r5 = arg; \
- tp->p_ctx.r13->r6 = 0; \
- tp->p_ctx.r13->r7 = 0; \
- tp->p_ctx.r13->r8 = 0; \
- tp->p_ctx.r13->r9 = 0; \
- tp->p_ctx.r13->r10 = 0; \
- tp->p_ctx.r13->r11 = 0; \
tp->p_ctx.r13->lr = threadstart; \
}
-#endif
#ifdef THUMB
extern void chSysLock(void);
@@ -94,16 +90,21 @@ extern void chSysUnlock(void); #define chSysPuts(msg) {}
-#define INT_REQUIRED_STACK 0x40 // Must include registers and stack frames.
-#define UserStackSize(n) (sizeof(Thread) + \
- sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK))
-
+#ifdef THUMB
+#define INT_REQUIRED_STACK 0x10
+#else /* !THUMB */
+#define INT_REQUIRED_STACK 0
+#endif /* THUMB */
+#define UserStackSize(n) (sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ (INT_REQUIRED_STACK) + \
+ (n))
#define IDLE_THREAD_STACK_SIZE 8
void _IdleThread(void *p) __attribute__((noreturn));
void chSysHalt(void) __attribute__((noreturn));
-void chSysPause(void) __attribute__((noreturn));
void chSysSwitchI(Context *oldp, Context *newp);
void threadstart(void);
void DefFiqHandler(void);
diff --git a/demos/ARM7-LPC214x-GCC/chcore2.s b/demos/ARM7-LPC214x-GCC/chcore2.s index 1eb301fbe..e29c92f5e 100644 --- a/demos/ARM7-LPC214x-GCC/chcore2.s +++ b/demos/ARM7-LPC214x-GCC/chcore2.s @@ -115,9 +115,6 @@ chSysSwitchI: IrqHandler:
sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr}
-// mrs r0, SPSR // Workaround for ARM7TDMI+VIC
-// tst r0, #I_BIT // spurious interrupts.
-// ldmnefd sp!, {r0-r3, r12, pc}
bl NonVectoredIrq
b IrqCommon
@@ -125,9 +122,6 @@ IrqHandler: T0IrqHandler:
sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr}
-// mrs r0, SPSR // Workaround for ARM7TDMI+VIC
-// tst r0, #I_BIT // spurious interrupts.
-// ldmnefd sp!, {r0-r3, r12, pc}^
bl Timer0Irq
b IrqCommon
@@ -135,9 +129,6 @@ T0IrqHandler: UART0IrqHandler:
sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr}
-// mrs r0, SPSR // Workaround for ARM7TDMI+VIC
-// tst r0, #I_BIT // spurious interrupts.
-// ldmnefd sp!, {r0-r3, r12, pc}^
bl UART0Irq
b IrqCommon
@@ -145,9 +136,6 @@ UART0IrqHandler: UART1IrqHandler:
sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr}
-// mrs r0, SPSR // Workaround for ARM7TDMI+VIC
-// tst r0, #I_BIT // spurious interrupts.
-// ldmnefd sp!, {r0-r3, r12, pc}^
bl UART1Irq
b IrqCommon
diff --git a/demos/AVR-AT90CANx-GCC/chcore.c b/demos/AVR-AT90CANx-GCC/chcore.c index 262732676..3bc5b027e 100644 --- a/demos/AVR-AT90CANx-GCC/chcore.c +++ b/demos/AVR-AT90CANx-GCC/chcore.c @@ -121,9 +121,7 @@ void hwinit(void) { TIMSK0 = (1 << OCIE0A); // Interrupt on compare.
}
-void chSysPause(void) {
-
- chThdSetPriority(IDLEPRIO);
+void _IdleThread(void *p) {
while (TRUE) {
// asm volatile ("sleep");
diff --git a/demos/AVR-AT90CANx-GCC/chcore.h b/demos/AVR-AT90CANx-GCC/chcore.h index 935c37488..32c939d32 100644 --- a/demos/AVR-AT90CANx-GCC/chcore.h +++ b/demos/AVR-AT90CANx-GCC/chcore.h @@ -48,7 +48,7 @@ struct extctx { };
/*
- * Stack saved context.
+ * System saved context.
*/
struct intctx {
BYTE8 r29;
@@ -72,6 +72,10 @@ struct intctx { UWORD16 pc;
};
+/*
+ * Port dependent part of the Thread structure, you may add fields in
+ * this structure.
+ */
typedef struct {
struct intctx *sp;
} Context;
@@ -93,18 +97,20 @@ typedef struct { */
#define EXTRA_INT_STACK 0x10
-#define UserStackSize(n) (sizeof(Thread) + \
- sizeof(struct intctx) + \
- sizeof(struct extctx) + \
- EXTRA_INT_STACK + \
+#define UserStackSize(n) (sizeof(Thread) + \
+ sizeof(struct intctx) + \
+ sizeof(struct extctx) + \
+ EXTRA_INT_STACK + \
(n))
#define chSysLock() asm("cli")
#define chSysUnlock() asm("sei")
#define chSysPuts(msg) {}
+#define IDLE_THREAD_STACK_SIZE 8
+void _IdleThread(void *p) __attribute__((noreturn));
+
void chSysHalt(void) __attribute__((noreturn)) ;
-void chSysPause(void) __attribute__((noreturn)) ;
void chSysSwitchI(Context *oldp, Context *newp);
void threadstart(void);
diff --git a/demos/AVR-AT90CANx-GCC/main.c b/demos/AVR-AT90CANx-GCC/main.c index 48f58d080..61156b040 100644 --- a/demos/AVR-AT90CANx-GCC/main.c +++ b/demos/AVR-AT90CANx-GCC/main.c @@ -24,7 +24,6 @@ void hwinit(void);
static BYTE8 waThread1[UserStackSize(32)];
-
static t_msg Thread1(void *arg) {
while (TRUE) {
@@ -37,8 +36,19 @@ int main(int argc, char **argv) { hwinit();
+ /*
+ * The main() function becomes a thread here then the interrupts are
+ * enabled and ChibiOS/RT goes live.
+ */
chSysInit();
+
+ /*
+ * Starts the LED blinker thread.
+ */
chThdCreate(NORMALPRIO, 0, waThread1, sizeof(waThread1), Thread1, NULL);
- chSysPause();
+
+ while(TRUE)
+ /* Do stuff*/ ;
+
return 0;
}
diff --git a/demos/Win32-MSVS/chcore.c b/demos/Win32-MSVS/chcore.c index 8aedbb465..0df82eec6 100644 --- a/demos/Win32-MSVS/chcore.c +++ b/demos/Win32-MSVS/chcore.c @@ -68,7 +68,7 @@ void ChkIntSources(void) { }
}
-void __fastcall chSysPause(void) {
+t_msg _IdleThread(void) {
chThdSetPriority(IDLEPRIO);
diff --git a/demos/Win32-MSVS/chcore.h b/demos/Win32-MSVS/chcore.h index 58e278fe4..6d11921cf 100644 --- a/demos/Win32-MSVS/chcore.h +++ b/demos/Win32-MSVS/chcore.h @@ -62,12 +62,13 @@ typedef struct { #define chSysPuts(msg) {}
#define INT_REQUIRED_STACK 0x0
-
#define UserStackSize(n) (sizeof(Thread) + sizeof(void *)*2 + \
sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK))
+#define IDLE_THREAD_STACK_SIZE 16384
+t_msg _IdleThread(void *p);
+
void __fastcall chSysHalt(void);
-void __fastcall chSysPause(void);
void __fastcall chSysSwitchI(Context *oldp, Context *newp);
void __fastcall threadexit(void);
diff --git a/demos/Win32-MSVS/demo.c b/demos/Win32-MSVS/demo.c index 077877f8e..1d4f4aa16 100644 --- a/demos/Win32-MSVS/demo.c +++ b/demos/Win32-MSVS/demo.c @@ -25,16 +25,12 @@ static ULONG32 wdguard;
static BYTE8 wdarea[UserStackSize(2048)];
-static ULONG32 iguard;
-static BYTE8 iarea[UserStackSize(2048)];
-
static ULONG32 cdguard;
static BYTE8 cdarea[UserStackSize(2048)];
static Thread *cdtp;
static t_msg WatchdogThread(void *arg);
static t_msg ConsoleThread(void *arg);
-static t_msg InitThread(void *arg);
t_msg TestThread(void *p);
@@ -43,34 +39,16 @@ extern FullDuplexDriver COM1, COM2; #define cprint(msg) chMsgSend(cdtp, (t_msg)msg)
-/*------------------------------------------------------------------------*
- * Simulator main, start here your threads, examples inside. *
- *------------------------------------------------------------------------*/
-int main(void) {
-
- InitCore();
-
- // Startup ChibiOS/RT.
- chSysInit();
- chThdCreate(NORMALPRIO + 2, 0, wdarea, sizeof(wdarea), WatchdogThread, NULL);
- cdtp = chThdCreate(NORMALPRIO + 1, 0, cdarea, sizeof(cdarea), ConsoleThread, NULL);
- chThdCreate(NORMALPRIO, 0, iarea, sizeof(iarea), InitThread, NULL);
- chSysPause();
- return 0;
-}
-
/*
* Watchdog thread, it checks magic values located under the various stack
* areas. The system is halted if something is wrong.
*/
static t_msg WatchdogThread(void *arg) {
wdguard = 0xA51F2E3D;
- iguard = 0xA51F2E3D;
cdguard = 0xA51F2E3D;
while (TRUE) {
if ((wdguard != 0xA51F2E3D) ||
- (iguard != 0xA51F2E3D) ||
(cdguard != 0xA51F2E3D)) {
printf("Halted by watchdog");
chSysHalt();
@@ -294,13 +272,20 @@ static t_evhandler fhandlers[2] = { COM2Handler
};
-/*
- * Init-like thread, it starts the shells and handles their termination.
- * It is a good example of events usage.
- */
-static t_msg InitThread(void *arg) {
+/*------------------------------------------------------------------------*
+ * Simulator main, start here your threads, examples inside. *
+ *------------------------------------------------------------------------*/
+int main(void) {
EventListener c1fel, c2fel;
+ InitCore();
+
+ // Startup ChibiOS/RT.
+ chSysInit();
+
+ chThdCreate(NORMALPRIO + 2, 0, wdarea, sizeof(wdarea), WatchdogThread, NULL);
+ cdtp = chThdCreate(NORMALPRIO + 1, 0, cdarea, sizeof(cdarea), ConsoleThread, NULL);
+
cprint("Console service started on COM1, COM2\n");
cprint(" - Listening for connections on COM1\n");
chFDDGetAndClearFlags(&COM1);
diff --git a/demos/Win32-MinGW/chcore.c b/demos/Win32-MinGW/chcore.c index c96611f8b..eab41ab27 100644 --- a/demos/Win32-MinGW/chcore.c +++ b/demos/Win32-MinGW/chcore.c @@ -91,9 +91,7 @@ void ChkIntSources(void) { }
}
-__attribute__((fastcall)) void chSysPause(void) {
-
- chThdSetPriority(IDLEPRIO);
+t_msg _IdleThread(void *p) {
while (TRUE) {
diff --git a/demos/Win32-MinGW/chcore.h b/demos/Win32-MinGW/chcore.h index 6d3055081..a28aa2833 100644 --- a/demos/Win32-MinGW/chcore.h +++ b/demos/Win32-MinGW/chcore.h @@ -62,12 +62,13 @@ typedef struct { #define chSysPuts(msg) {}
#define INT_REQUIRED_STACK 0x0
-
#define UserStackSize(n) (sizeof(Thread) + sizeof(void *) * 2 + \
sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK))
+#define IDLE_THREAD_STACK_SIZE 16384
+t_msg _IdleThread(void *p);
+
__attribute__((fastcall)) void chSysHalt(void);
-__attribute__((fastcall)) void chSysPause(void);
__attribute__((fastcall)) void chSysSwitchI(Context *oldp, Context *newp);
__attribute__((fastcall)) void threadstart(void);
diff --git a/demos/Win32-MinGW/demo.c b/demos/Win32-MinGW/demo.c index 077877f8e..1d4f4aa16 100644 --- a/demos/Win32-MinGW/demo.c +++ b/demos/Win32-MinGW/demo.c @@ -25,16 +25,12 @@ static ULONG32 wdguard;
static BYTE8 wdarea[UserStackSize(2048)];
-static ULONG32 iguard;
-static BYTE8 iarea[UserStackSize(2048)];
-
static ULONG32 cdguard;
static BYTE8 cdarea[UserStackSize(2048)];
static Thread *cdtp;
static t_msg WatchdogThread(void *arg);
static t_msg ConsoleThread(void *arg);
-static t_msg InitThread(void *arg);
t_msg TestThread(void *p);
@@ -43,34 +39,16 @@ extern FullDuplexDriver COM1, COM2; #define cprint(msg) chMsgSend(cdtp, (t_msg)msg)
-/*------------------------------------------------------------------------*
- * Simulator main, start here your threads, examples inside. *
- *------------------------------------------------------------------------*/
-int main(void) {
-
- InitCore();
-
- // Startup ChibiOS/RT.
- chSysInit();
- chThdCreate(NORMALPRIO + 2, 0, wdarea, sizeof(wdarea), WatchdogThread, NULL);
- cdtp = chThdCreate(NORMALPRIO + 1, 0, cdarea, sizeof(cdarea), ConsoleThread, NULL);
- chThdCreate(NORMALPRIO, 0, iarea, sizeof(iarea), InitThread, NULL);
- chSysPause();
- return 0;
-}
-
/*
* Watchdog thread, it checks magic values located under the various stack
* areas. The system is halted if something is wrong.
*/
static t_msg WatchdogThread(void *arg) {
wdguard = 0xA51F2E3D;
- iguard = 0xA51F2E3D;
cdguard = 0xA51F2E3D;
while (TRUE) {
if ((wdguard != 0xA51F2E3D) ||
- (iguard != 0xA51F2E3D) ||
(cdguard != 0xA51F2E3D)) {
printf("Halted by watchdog");
chSysHalt();
@@ -294,13 +272,20 @@ static t_evhandler fhandlers[2] = { COM2Handler
};
-/*
- * Init-like thread, it starts the shells and handles their termination.
- * It is a good example of events usage.
- */
-static t_msg InitThread(void *arg) {
+/*------------------------------------------------------------------------*
+ * Simulator main, start here your threads, examples inside. *
+ *------------------------------------------------------------------------*/
+int main(void) {
EventListener c1fel, c2fel;
+ InitCore();
+
+ // Startup ChibiOS/RT.
+ chSysInit();
+
+ chThdCreate(NORMALPRIO + 2, 0, wdarea, sizeof(wdarea), WatchdogThread, NULL);
+ cdtp = chThdCreate(NORMALPRIO + 1, 0, cdarea, sizeof(cdarea), ConsoleThread, NULL);
+
cprint("Console service started on COM1, COM2\n");
cprint(" - Listening for connections on COM1\n");
chFDDGetAndClearFlags(&COM1);
diff --git a/readme.txt b/readme.txt index cf6696e56..28b58a9df 100644 --- a/readme.txt +++ b/readme.txt @@ -44,13 +44,11 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet. executing chSysInit() and can use all the ChibiOS/RT APIs (it was required
to run the idle loop in previous versions).
Now it is also possible to use ChibiOS/RT with a single main() thread and
- just use it for the I/O capabilities, Virtual Timers and events. Mow you
+ just use it for the I/O capabilities, Virtual Timers and events. Now you
don't have to use multiple threads if you don't really need to.
-- Cleaned up the LPC2148 demo in main.c, it is now well documented and
- explains everything, I assumed too much stuff to be "obvious".
- Added a spreadsheet in the documentation that describes the advantages
and disadvantages of the various optimization options (both GCC options and
- ChibiOS/RT options), very interesting read IMO. No .xls available, ODF only.
+ ChibiOS/RT options), very interesting read IMO.
- The GCC option +falign-functions=16 is now default in the Makefile, it is
required because of the MAM unit into the LPC chips, without this option
the code performance is less predictable and can change of some % points
@@ -58,11 +56,16 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet. is bad for a RTOS. This option however increases the code size slightly
because of the alignment gaps.
- Fine tuning in the scheduler code for improved performance, deeper
- inlining and small changes, about 5% better scheduler performance.
+ inlining and other small changes, about 5% better scheduler performance.
- Increased the default system-mode stack size from 128 to 256 bytes because
- some optimizations and the THUMB mode seem to use more stack space.
+ some optimizations and the THUMB mode seem to eat more stack space.
- Included a Makefile in the LPC2148 demo that builds in THUMB mode.
- Const-ified a parameter in the chEvtWait() and chEvtWaitTimeout() APIs.
+- Removed the CPU register clearing on thread start, it was not really useful,
+ it is better to maximize performance instead.
+- Cleaned up the ARM port code. Now it is easier to understand.
+- Cleaned up the LPC2148 demo in main.c, it is now well documented and
+ explains everything, I assumed too much stuff to be "obvious".
*** 0.4.0 ***
- NEW, added a benchmark functionality to the test suite. The benchmark
|