git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@97 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2007-11-19 11:09:33 +00:00
parent e3617bedb2
commit b3361bd0e8
12 changed files with 103 additions and 127 deletions

View File

@ -31,9 +31,22 @@
typedef void *regarm; 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 r4;
regarm r5; regarm r5;
regarm r6; regarm r6;
@ -47,42 +60,25 @@ struct stackregs {
regarm lr; regarm lr;
}; };
/*
* Port dependent part of the Thread structure, you may add fields in
* this structure.
*/
typedef struct { typedef struct {
struct stackregs *r13; struct intctx *r13;
} Context; } Context;
#ifdef CH_CURRP_REGISTER_CACHE /*
#define SETUP_CONTEXT(workspace, wsize, pf, arg) \ * Platform dependent part of the \p chThdCreate() API.
{ \ */
tp->p_ctx.r13 = (struct stackregs *)((BYTE8 *)workspace + \ #define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
wsize - \ tp->p_ctx.r13 = (struct intctx *)((BYTE8 *)workspace + \
sizeof(struct stackregs)); \ wsize - \
sizeof(struct intctx)); \
tp->p_ctx.r13->r4 = pf; \ tp->p_ctx.r13->r4 = pf; \
tp->p_ctx.r13->r5 = arg; \ 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; \ 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)); \
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 #ifdef THUMB
extern void chSysLock(void); extern void chSysLock(void);
@ -94,16 +90,21 @@ extern void chSysUnlock(void);
#define chSysPuts(msg) {} #define chSysPuts(msg) {}
#define INT_REQUIRED_STACK 0x40 // Must include registers and stack frames. #ifdef THUMB
#define UserStackSize(n) (sizeof(Thread) + \ #define INT_REQUIRED_STACK 0x10
sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK)) #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 #define IDLE_THREAD_STACK_SIZE 8
void _IdleThread(void *p) __attribute__((noreturn)); void _IdleThread(void *p) __attribute__((noreturn));
void chSysHalt(void) __attribute__((noreturn)); void chSysHalt(void) __attribute__((noreturn));
void chSysPause(void) __attribute__((noreturn));
void chSysSwitchI(Context *oldp, Context *newp); void chSysSwitchI(Context *oldp, Context *newp);
void threadstart(void); void threadstart(void);
void DefFiqHandler(void); void DefFiqHandler(void);

View File

@ -115,9 +115,6 @@ chSysSwitchI:
IrqHandler: IrqHandler:
sub lr, lr, #4 sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr} 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 bl NonVectoredIrq
b IrqCommon b IrqCommon
@ -125,9 +122,6 @@ IrqHandler:
T0IrqHandler: T0IrqHandler:
sub lr, lr, #4 sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr} 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 bl Timer0Irq
b IrqCommon b IrqCommon
@ -135,9 +129,6 @@ T0IrqHandler:
UART0IrqHandler: UART0IrqHandler:
sub lr, lr, #4 sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr} 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 bl UART0Irq
b IrqCommon b IrqCommon
@ -145,9 +136,6 @@ UART0IrqHandler:
UART1IrqHandler: UART1IrqHandler:
sub lr, lr, #4 sub lr, lr, #4
stmfd sp!, {r0-r3, r12, lr} 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 bl UART1Irq
b IrqCommon b IrqCommon

View File

@ -121,9 +121,7 @@ void hwinit(void) {
TIMSK0 = (1 << OCIE0A); // Interrupt on compare. TIMSK0 = (1 << OCIE0A); // Interrupt on compare.
} }
void chSysPause(void) { void _IdleThread(void *p) {
chThdSetPriority(IDLEPRIO);
while (TRUE) { while (TRUE) {
// asm volatile ("sleep"); // asm volatile ("sleep");

View File

@ -48,7 +48,7 @@ struct extctx {
}; };
/* /*
* Stack saved context. * System saved context.
*/ */
struct intctx { struct intctx {
BYTE8 r29; BYTE8 r29;
@ -72,6 +72,10 @@ struct intctx {
UWORD16 pc; UWORD16 pc;
}; };
/*
* Port dependent part of the Thread structure, you may add fields in
* this structure.
*/
typedef struct { typedef struct {
struct intctx *sp; struct intctx *sp;
} Context; } Context;
@ -93,18 +97,20 @@ typedef struct {
*/ */
#define EXTRA_INT_STACK 0x10 #define EXTRA_INT_STACK 0x10
#define UserStackSize(n) (sizeof(Thread) + \ #define UserStackSize(n) (sizeof(Thread) + \
sizeof(struct intctx) + \ sizeof(struct intctx) + \
sizeof(struct extctx) + \ sizeof(struct extctx) + \
EXTRA_INT_STACK + \ EXTRA_INT_STACK + \
(n)) (n))
#define chSysLock() asm("cli") #define chSysLock() asm("cli")
#define chSysUnlock() asm("sei") #define chSysUnlock() asm("sei")
#define chSysPuts(msg) {} #define chSysPuts(msg) {}
#define IDLE_THREAD_STACK_SIZE 8
void _IdleThread(void *p) __attribute__((noreturn));
void chSysHalt(void) __attribute__((noreturn)) ; void chSysHalt(void) __attribute__((noreturn)) ;
void chSysPause(void) __attribute__((noreturn)) ;
void chSysSwitchI(Context *oldp, Context *newp); void chSysSwitchI(Context *oldp, Context *newp);
void threadstart(void); void threadstart(void);

View File

@ -24,7 +24,6 @@
void hwinit(void); void hwinit(void);
static BYTE8 waThread1[UserStackSize(32)]; static BYTE8 waThread1[UserStackSize(32)];
static t_msg Thread1(void *arg) { static t_msg Thread1(void *arg) {
while (TRUE) { while (TRUE) {
@ -37,8 +36,19 @@ int main(int argc, char **argv) {
hwinit(); hwinit();
/*
* The main() function becomes a thread here then the interrupts are
* enabled and ChibiOS/RT goes live.
*/
chSysInit(); chSysInit();
/*
* Starts the LED blinker thread.
*/
chThdCreate(NORMALPRIO, 0, waThread1, sizeof(waThread1), Thread1, NULL); chThdCreate(NORMALPRIO, 0, waThread1, sizeof(waThread1), Thread1, NULL);
chSysPause();
while(TRUE)
/* Do stuff*/ ;
return 0; return 0;
} }

View File

@ -68,7 +68,7 @@ void ChkIntSources(void) {
} }
} }
void __fastcall chSysPause(void) { t_msg _IdleThread(void) {
chThdSetPriority(IDLEPRIO); chThdSetPriority(IDLEPRIO);

View File

@ -62,12 +62,13 @@ typedef struct {
#define chSysPuts(msg) {} #define chSysPuts(msg) {}
#define INT_REQUIRED_STACK 0x0 #define INT_REQUIRED_STACK 0x0
#define UserStackSize(n) (sizeof(Thread) + sizeof(void *)*2 + \ #define UserStackSize(n) (sizeof(Thread) + sizeof(void *)*2 + \
sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK)) sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK))
#define IDLE_THREAD_STACK_SIZE 16384
t_msg _IdleThread(void *p);
void __fastcall chSysHalt(void); void __fastcall chSysHalt(void);
void __fastcall chSysPause(void);
void __fastcall chSysSwitchI(Context *oldp, Context *newp); void __fastcall chSysSwitchI(Context *oldp, Context *newp);
void __fastcall threadexit(void); void __fastcall threadexit(void);

View File

@ -25,16 +25,12 @@
static ULONG32 wdguard; static ULONG32 wdguard;
static BYTE8 wdarea[UserStackSize(2048)]; static BYTE8 wdarea[UserStackSize(2048)];
static ULONG32 iguard;
static BYTE8 iarea[UserStackSize(2048)];
static ULONG32 cdguard; static ULONG32 cdguard;
static BYTE8 cdarea[UserStackSize(2048)]; static BYTE8 cdarea[UserStackSize(2048)];
static Thread *cdtp; static Thread *cdtp;
static t_msg WatchdogThread(void *arg); static t_msg WatchdogThread(void *arg);
static t_msg ConsoleThread(void *arg); static t_msg ConsoleThread(void *arg);
static t_msg InitThread(void *arg);
t_msg TestThread(void *p); t_msg TestThread(void *p);
@ -43,34 +39,16 @@ extern FullDuplexDriver COM1, COM2;
#define cprint(msg) chMsgSend(cdtp, (t_msg)msg) #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 * Watchdog thread, it checks magic values located under the various stack
* areas. The system is halted if something is wrong. * areas. The system is halted if something is wrong.
*/ */
static t_msg WatchdogThread(void *arg) { static t_msg WatchdogThread(void *arg) {
wdguard = 0xA51F2E3D; wdguard = 0xA51F2E3D;
iguard = 0xA51F2E3D;
cdguard = 0xA51F2E3D; cdguard = 0xA51F2E3D;
while (TRUE) { while (TRUE) {
if ((wdguard != 0xA51F2E3D) || if ((wdguard != 0xA51F2E3D) ||
(iguard != 0xA51F2E3D) ||
(cdguard != 0xA51F2E3D)) { (cdguard != 0xA51F2E3D)) {
printf("Halted by watchdog"); printf("Halted by watchdog");
chSysHalt(); chSysHalt();
@ -294,13 +272,20 @@ static t_evhandler fhandlers[2] = {
COM2Handler COM2Handler
}; };
/* /*------------------------------------------------------------------------*
* Init-like thread, it starts the shells and handles their termination. * Simulator main, start here your threads, examples inside. *
* It is a good example of events usage. *------------------------------------------------------------------------*/
*/ int main(void) {
static t_msg InitThread(void *arg) {
EventListener c1fel, c2fel; 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("Console service started on COM1, COM2\n");
cprint(" - Listening for connections on COM1\n"); cprint(" - Listening for connections on COM1\n");
chFDDGetAndClearFlags(&COM1); chFDDGetAndClearFlags(&COM1);

View File

@ -91,9 +91,7 @@ void ChkIntSources(void) {
} }
} }
__attribute__((fastcall)) void chSysPause(void) { t_msg _IdleThread(void *p) {
chThdSetPriority(IDLEPRIO);
while (TRUE) { while (TRUE) {

View File

@ -62,12 +62,13 @@ typedef struct {
#define chSysPuts(msg) {} #define chSysPuts(msg) {}
#define INT_REQUIRED_STACK 0x0 #define INT_REQUIRED_STACK 0x0
#define UserStackSize(n) (sizeof(Thread) + sizeof(void *) * 2 + \ #define UserStackSize(n) (sizeof(Thread) + sizeof(void *) * 2 + \
sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK)) 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 chSysHalt(void);
__attribute__((fastcall)) void chSysPause(void);
__attribute__((fastcall)) void chSysSwitchI(Context *oldp, Context *newp); __attribute__((fastcall)) void chSysSwitchI(Context *oldp, Context *newp);
__attribute__((fastcall)) void threadstart(void); __attribute__((fastcall)) void threadstart(void);

View File

@ -25,16 +25,12 @@
static ULONG32 wdguard; static ULONG32 wdguard;
static BYTE8 wdarea[UserStackSize(2048)]; static BYTE8 wdarea[UserStackSize(2048)];
static ULONG32 iguard;
static BYTE8 iarea[UserStackSize(2048)];
static ULONG32 cdguard; static ULONG32 cdguard;
static BYTE8 cdarea[UserStackSize(2048)]; static BYTE8 cdarea[UserStackSize(2048)];
static Thread *cdtp; static Thread *cdtp;
static t_msg WatchdogThread(void *arg); static t_msg WatchdogThread(void *arg);
static t_msg ConsoleThread(void *arg); static t_msg ConsoleThread(void *arg);
static t_msg InitThread(void *arg);
t_msg TestThread(void *p); t_msg TestThread(void *p);
@ -43,34 +39,16 @@ extern FullDuplexDriver COM1, COM2;
#define cprint(msg) chMsgSend(cdtp, (t_msg)msg) #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 * Watchdog thread, it checks magic values located under the various stack
* areas. The system is halted if something is wrong. * areas. The system is halted if something is wrong.
*/ */
static t_msg WatchdogThread(void *arg) { static t_msg WatchdogThread(void *arg) {
wdguard = 0xA51F2E3D; wdguard = 0xA51F2E3D;
iguard = 0xA51F2E3D;
cdguard = 0xA51F2E3D; cdguard = 0xA51F2E3D;
while (TRUE) { while (TRUE) {
if ((wdguard != 0xA51F2E3D) || if ((wdguard != 0xA51F2E3D) ||
(iguard != 0xA51F2E3D) ||
(cdguard != 0xA51F2E3D)) { (cdguard != 0xA51F2E3D)) {
printf("Halted by watchdog"); printf("Halted by watchdog");
chSysHalt(); chSysHalt();
@ -294,13 +272,20 @@ static t_evhandler fhandlers[2] = {
COM2Handler COM2Handler
}; };
/* /*------------------------------------------------------------------------*
* Init-like thread, it starts the shells and handles their termination. * Simulator main, start here your threads, examples inside. *
* It is a good example of events usage. *------------------------------------------------------------------------*/
*/ int main(void) {
static t_msg InitThread(void *arg) {
EventListener c1fel, c2fel; 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("Console service started on COM1, COM2\n");
cprint(" - Listening for connections on COM1\n"); cprint(" - Listening for connections on COM1\n");
chFDDGetAndClearFlags(&COM1); chFDDGetAndClearFlags(&COM1);

View File

@ -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 executing chSysInit() and can use all the ChibiOS/RT APIs (it was required
to run the idle loop in previous versions). to run the idle loop in previous versions).
Now it is also possible to use ChibiOS/RT with a single main() thread and 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. 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 - Added a spreadsheet in the documentation that describes the advantages
and disadvantages of the various optimization options (both GCC options and 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 - 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 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 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 is bad for a RTOS. This option however increases the code size slightly
because of the alignment gaps. because of the alignment gaps.
- Fine tuning in the scheduler code for improved performance, deeper - 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 - 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. - Included a Makefile in the LPC2148 demo that builds in THUMB mode.
- Const-ified a parameter in the chEvtWait() and chEvtWaitTimeout() APIs. - 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 *** *** 0.4.0 ***
- NEW, added a benchmark functionality to the test suite. The benchmark - NEW, added a benchmark functionality to the test suite. The benchmark