From 4fc627f08b942df8312ad02f24a361b18c4b790b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 18 Nov 2007 09:45:45 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@95 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARM7-LPC214x-GCC/buzzer.c | 4 ++-- demos/ARM7-LPC214x-GCC/chcore.c | 9 +++++---- demos/ARM7-LPC214x-GCC/chcore.h | 4 ++++ demos/ARM7-LPC214x-GCC/main.c | 23 +-------------------- readme.txt | 9 ++++++++- src/chinit.c | 36 ++++++++++++++++----------------- src/templates/chcore.c | 4 +--- src/templates/chcore.h | 16 +++++++++++++-- 8 files changed, 53 insertions(+), 52 deletions(-) diff --git a/demos/ARM7-LPC214x-GCC/buzzer.c b/demos/ARM7-LPC214x-GCC/buzzer.c index 218d920d0..7d80d8881 100644 --- a/demos/ARM7-LPC214x-GCC/buzzer.c +++ b/demos/ARM7-LPC214x-GCC/buzzer.c @@ -52,8 +52,8 @@ void InitBuzzer(void) { TC *tc = T1Base; StopCounter(tc); tc->TC_CTCR = 0; // Clock source is PCLK. - tc->TC_PR = 0; // Prescaler disabled. - tc->TC_MCR = 2; // Clear TC on match MR0. + tc->TC_PR = 0; // Prescaler disabled. + tc->TC_MCR = 2; // Clear TC on match MR0. } static void stop(void *p) { diff --git a/demos/ARM7-LPC214x-GCC/chcore.c b/demos/ARM7-LPC214x-GCC/chcore.c index 2f60c9d53..bf157cf43 100644 --- a/demos/ARM7-LPC214x-GCC/chcore.c +++ b/demos/ARM7-LPC214x-GCC/chcore.c @@ -140,14 +140,15 @@ void hwinit(void) { InitBuzzer(); } -void chSysPause(void) { - - chThdSetPriority(IDLEPRIO); +/* + * System idle thread loop. + */ +void _IdleThread(void *p) { while (TRUE) { // Note, it is disabled because it causes trouble with the JTAG probe. // Enable it in the final code only. -// PCON = 1; /* Stops CPU clock until next interrupt. */ +// PCON = 1; } } diff --git a/demos/ARM7-LPC214x-GCC/chcore.h b/demos/ARM7-LPC214x-GCC/chcore.h index 9a1401f1c..7aef95d12 100644 --- a/demos/ARM7-LPC214x-GCC/chcore.h +++ b/demos/ARM7-LPC214x-GCC/chcore.h @@ -98,6 +98,10 @@ extern void chSysUnlock(void); #define UserStackSize(n) (sizeof(Thread) + \ sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK)) + +#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); diff --git a/demos/ARM7-LPC214x-GCC/main.c b/demos/ARM7-LPC214x-GCC/main.c index 14e03170d..1829e6eb6 100644 --- a/demos/ARM7-LPC214x-GCC/main.c +++ b/demos/ARM7-LPC214x-GCC/main.c @@ -25,18 +25,6 @@ #include "buzzer.h" #include "evtimer.h" -/* - * System Idle Thread, this thread only runs when on other threads in the - * system require the CPU. - * The role of this thread is to minimize the power consumption when idling - * and serve the interrupts. - */ -static BYTE8 waIdleThread[UserStackSize(16)]; -static t_msg IdleThread(void *arg) { - - chSysPause(); -} - /* * Red LEDs blinker thread, times are in milliseconds. */ @@ -138,15 +126,6 @@ int main(int argc, char **argv) { */ chSysInit(); - /* - * This thread has the lowest priority in the system, its role is just to - * execute the chSysPause() and serve interrupts in its context. - * In ChibiOS/RT at least one thread in the system *must* execute - * chThdPause(), it can be done in a dedicated thread or in the main() - * function (that would never exit the call). - */ - chThdCreate(IDLEPRIO, 0, waIdleThread, sizeof(waIdleThread), IdleThread, NULL); - /* * If a button is pressed during the reset then the blinking leds threads * are not started in order to make accurate benchmarks. @@ -163,7 +142,7 @@ int main(int argc, char **argv) { chThdSetPriority(NORMALPRIO); /* - * Normal main() activity, in this demo it server events incoming from + * Normal main() activity, in this demo it serves events generated by * various sources. */ evtInit(&evt, 500); /* Initializes an event timer object. */ diff --git a/readme.txt b/readme.txt index 9cf09029b..673d5f0c5 100644 --- a/readme.txt +++ b/readme.txt @@ -39,6 +39,13 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet. ***************************************************************************** *** 0.4.1 *** +- Modified the initialization code in order to have a dedicated idle thread in + the system, now the main() function behaves like a normal thread after + 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. 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 @@ -51,7 +58,7 @@ 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. + inlining and 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. - Included a Makefile in the LPC2148 demo that builds in THUMB mode. diff --git a/src/chinit.c b/src/chinit.c index 4a25567a8..918da1796 100644 --- a/src/chinit.c +++ b/src/chinit.c @@ -24,27 +24,17 @@ #include -static Thread idlethread; /** * ChibiOS/RT initialization. After executing this function the current - * instructions stream becomes the idle thread. The thread must execute the - * first user thread and then go to sleep into the \p chSysPause() where it - * will just serve the interrupts while keeping the lowest possible power - * mode.

- * @code - * chSysInit(); - * chThdCreate(...); // Starts one or more user threads. - * chSysPause(); - * @endcode + * instructions stream becomes the main thread. * @note Interrupts should be still disabled when \p chSysInit() is invoked * and are internally enabled. - * @note The idle thread has absolute priority when exiting from the - * \p chSysInit(), this is done to make sure that all the initializations - * performed in the \p main() procedure are completed before any thread - * starts. The priority is set to \p IDLEPRIO into the \p chSysPause(). + * @note The main thread is created with priority \p NORMALPRIO. */ void chSysInit(void) { + static Thread mainthread; + static BYTE8 waIdleThread[UserStackSize(IDLE_THREAD_STACK_SIZE)]; chSchInit(); chDbgInit(); @@ -52,13 +42,23 @@ void chSysInit(void) { chVTInit(); #endif /* - * Now this instructions flow becomes the idle thread. + * Now this instructions flow becomes the main thread. */ - _InitThread(ABSPRIO, 0, &idlethread); - idlethread.p_state = PRCURR; - currp = &idlethread; + _InitThread(NORMALPRIO, 0, &mainthread); + mainthread.p_state = PRCURR; + currp = &mainthread; chSysUnlock(); + + /* + * The idle thread is created using the port-provided implementation. + * This thread has the lowest priority in the system, its role is just to + * execute the chSysPause() and serve interrupts in its context. + * In ChibiOS/RT at least one thread in the system *must* execute + * chThdPause(), it can be done in a dedicated thread or in the main() + * function (that would never exit the call). + */ + chThdCreate(IDLEPRIO, 0, waIdleThread, sizeof(waIdleThread), (t_tfunc)_IdleThread, NULL); } /** @} */ diff --git a/src/templates/chcore.c b/src/templates/chcore.c index bc8c68b90..ec2b39592 100644 --- a/src/templates/chcore.c +++ b/src/templates/chcore.c @@ -36,9 +36,7 @@ * The priority is internally set to the minimum system value so that this * thread is executed only if there are no other ready threads in the system. */ -void chSysPause(void) { - - chThdSetPriority(IDLEPRIO); +void _IdleThread(void *p) { while (TRUE) ; diff --git a/src/templates/chcore.h b/src/templates/chcore.h index e917ffa6f..7f2c5fb0b 100644 --- a/src/templates/chcore.h +++ b/src/templates/chcore.h @@ -42,8 +42,20 @@ typedef struct { { \ } -#define INT_REQUIRED_STACK 0 // Must include registers and stack frames. +/** + * Stack size for the system idle thread. + */ +#define IDLE_THREAD_STACK_SIZE 0 +/** + * Per-thread stack overhead for interrupts servicing. + */ +#define INT_REQUIRED_STACK 0 + +/** + * Macro to be used when allocating stack spaces, it adds the system-specific + * overhead. + */ #define UserStackSize(n) (sizeof(Thread) + \ sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK)) @@ -74,8 +86,8 @@ typedef struct { */ #define chSysPuts(msg) {} +void _IdleThread(void *p); void chSysHalt(void); -void chSysPause(void); void chSysSwitchI(Context *oldp, Context *newp); #endif /* _CHCORE_H_ */