diff --git a/demos/ARM7-LPC214x-GCC/chcore.c b/demos/ARM7-LPC214x-GCC/chcore.c index 3d72c20db..d06e57657 100644 --- a/demos/ARM7-LPC214x-GCC/chcore.c +++ b/demos/ARM7-LPC214x-GCC/chcore.c @@ -145,6 +145,8 @@ void hwinit(void) { void chSysPause(void) { + chThdSetPriority(IDLEPRIO); + while (TRUE) { // Note, it is disabled because it causes trouble with the JTAG probe. // Enable it in the final code only. diff --git a/demos/Win32-MSVS/chcore.c b/demos/Win32-MSVS/chcore.c index bb038a4d6..80fd11424 100644 --- a/demos/Win32-MSVS/chcore.c +++ b/demos/Win32-MSVS/chcore.c @@ -35,7 +35,7 @@ void InitCore(void) { printf("QueryPerformanceFrequency() error"); exit(1); } - printf("Core Frequency %d Hz\n", slice.LowPart); + printf("Core Frequency %u Hz\n", slice.LowPart); slice.QuadPart /= CH_FREQUENCY; QueryPerformanceCounter(&nextcnt); nextcnt.QuadPart += slice.QuadPart; @@ -69,6 +69,8 @@ static void ChkIntSources(void) { void __fastcall chSysPause(void) { + chThdSetPriority(IDLEPRIO); + while (TRUE) { ChkIntSources(); diff --git a/demos/Win32-MinGW/chcore.c b/demos/Win32-MinGW/chcore.c index 77195c44c..4f677b929 100644 --- a/demos/Win32-MinGW/chcore.c +++ b/demos/Win32-MinGW/chcore.c @@ -58,7 +58,7 @@ void InitCore(void) { printf("QueryPerformanceFrequency() error"); exit(1); } - printf("Core Frequency %d Hz\n", (int)slice.LowPart); + printf("Core Frequency %u Hz\n", (int)slice.LowPart); slice.QuadPart /= CH_FREQUENCY; QueryPerformanceCounter(&nextcnt); nextcnt.QuadPart += slice.QuadPart; @@ -92,6 +92,8 @@ static void ChkIntSources(void) { __attribute__((fastcall)) void chSysPause(void) { + chThdSetPriority(IDLEPRIO); + while (TRUE) { ChkIntSources(); diff --git a/readme.txt b/readme.txt index 5d37bc16f..3165ad1af 100644 --- a/readme.txt +++ b/readme.txt @@ -39,6 +39,11 @@ AVR-AT90CANx-GCC - Port on AVER AT90CAN128, not complete yet. ***************************************************************************** *** 0.3.2 *** +- Modified the chSysInit() to give the idle thread absolute priority, the + priority is then lowered to the minimum value into the chSysPause(). This + is done in order to ensure that the initializations performed into the + main() procedure are performed before any thread starts. +- Added chThdSetPriority() new API. - Added a generic events generator timer to the library code. - Added the "#ifdef __cplusplus" stuff to the header files. - Removed an obsolete definition in ./src/templates/chtypes.h. diff --git a/src/chinit.c b/src/chinit.c index b86626fa6..55a69b1fc 100644 --- a/src/chinit.c +++ b/src/chinit.c @@ -37,8 +37,12 @@ static Thread idlethread; * chThdCreate(...); // Starts one or more user threads. * chSysPause(); * @endcode - * @note Interrupts should be still disabled when \p chSysInit() is invoked and - * are internally enabled. + * @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(). */ void chSysInit(void) { @@ -49,7 +53,7 @@ void chSysInit(void) { /* * Now this instructions flow becomes the idle thread. */ - _InitThread(IDLEPRIO, 0, &idlethread); + _InitThread(ABSPRIO, 0, &idlethread); idlethread.p_state = PRCURR; currp = &idlethread; diff --git a/src/chthreads.c b/src/chthreads.c index 608dabe89..28b276db5 100644 --- a/src/chthreads.c +++ b/src/chthreads.c @@ -100,6 +100,27 @@ Thread *chThdCreate(t_prio prio, t_tmode mode, void *workspace, return tp; } +/** + * Changes the thread priority, reschedules if necessary. + * @param newprio the new priority of the invoking thread + */ +void chThdSetPriority(t_prio newprio) { + + chSysLock(); + +#ifdef CH_USE_RT_SEMAPHORES + if (currp->p_rtcnt) + currp->p_prio = newprio + MEPRIO; + else + currp->p_prio = newprio; +#else + currp->p_prio = newprio; +#endif + chSchRescheduleI(); + + chSysUnlock(); +} + #ifdef CH_USE_RESUME /** * Resumes a thread created with the \p P_SUSPENDED option. diff --git a/src/include/threads.h b/src/include/threads.h index 2ed92fa39..0440b6007 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -191,6 +191,7 @@ extern "C" { #endif Thread *chThdCreate(t_prio prio, t_tmode mode, void *workspace, t_size wsize, t_tfunc pf, void *arg); + void chThdSetPriority(t_prio newprio); void chThdResume(Thread *tp); void chThdExit(t_msg msg); #ifdef CH_USE_TERMINATE diff --git a/src/templates/chcore.c b/src/templates/chcore.c index f39441ed5..bc8c68b90 100644 --- a/src/templates/chcore.c +++ b/src/templates/chcore.c @@ -33,14 +33,28 @@ /** * This function implements the idle thread infinite loop. The function should * put the processor in the lowest power mode capable to serve interrupts. + * 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) {} +void chSysPause(void) { + + chThdSetPriority(IDLEPRIO); + + while (TRUE) + ; +} /** * Abonormal system termination handler. Invoked by the ChibiOS/RT when an * abnormal unrecoverable condition is met. */ -void chSysHalt(void) {} +void chSysHalt(void) { + + chSysLock(); + + while (TRUE) + ; +} /** * Context switch.