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

master
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;
/*
* 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)); \
/*
* 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->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)); \
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);

View File

@ -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

View File

@ -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");

View File

@ -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);

View File

@ -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;
}

View File

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

View File

@ -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);

View File

@ -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);

View File

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

View File

@ -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);

View File

@ -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);

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
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