Milos RTOS v0.3.4a
Real Time Operating System
system.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  * system.c
00003  * (C) 2010 Ivan Meleca
00004  * Based on original code written by Ruben Meleca
00005  * www.milos.it
00006 
00007 #   This program is free software; you can redistribute it and/or modify
00008 #   it under the terms of the GNU General Public License as published by
00009 #   the Free Software Foundation; either version 2 of the License, or
00010 #   (at your option) any later version.
00011 #
00012 #   This program is distributed in the hope that it will be useful,
00013 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 #   GNU General Public License for more details.
00016 #
00017 #   You should have received a copy of the GNU General Public License
00018 #   along with this program; if not, write to the Free Software
00019 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 
00021 ***************************************************************************/
00022 
00023 #include "system.h"
00024 #include "dbgterm.h"
00025 #include "heap.h"
00026 #include "thread.h"
00027 #include "timer.h"
00028 #include "device.h"
00029 #include "rtc.h"
00030 
00073 __BOOL  __systemReset = __FALSE;                        
00074 __STATIC __APP_ENTRY*   __systemAppEntry = __NULL;      
00075 __STATIC __VOLATILE u32 __systemIrqCount;               
00076 __STATIC __VOLATILE u32 __systemTickCount = 0;          
00077 __STATIC __VOLATILE u32 __systemSecondsCount = 0;       
00078 __STATIC __VOLATILE u32 __systemContextSwCount = 0;     
00080 __STATIC __VOLATILE u32 __systemNestingISR = 0;         
00081 __STATIC __PTHREAD      __systemThreadPtr;              
00082 __STATIC __VOLATILE u8  __systemContextSwRequest;       
00102 __VOID __systemThread(__VOID)
00103 {
00104     u32 ticks = __systemTickCount;
00105 
00106     /* Start thread for software timers */
00107 #if __CONFIG_ENABLE_SWTIMERS
00108     __timerInit(__CONFIG_STACK_TIMTHREAD);
00109 #endif
00110 
00111     /* Initialize the Debug Terminal, if enabled */
00112 #if __CONFIG_DBGTERM_ENABLED
00113     __dbgInit();
00114 #endif // __CONFIG_DBGTERM_ENABLED
00115 
00116     if (__systemAppEntry)
00117     {
00118         (__systemAppEntry)();
00119     }
00120     
00121     for(;;)
00122     {
00123 
00124 #if __CONFIG_ENABLE_WATCHDOG
00125         if (!__systemReset)
00126         {
00127 //          __cpuResetWatchdog();
00128         }
00129 #endif /* __CONFIG_ENABLE_WATCHDOG */
00130         
00131 #if __CONFIG_ENABLE_HEARTBEAT
00132         __cpuHeartBeat();
00133 #endif /* __CONFIG_ENABLE_HEARTBEAT */
00134 
00135         /* Seconds counter */
00136         if (__systemTickCount < ticks)
00137         {
00138             /* overflowed */
00139             ticks = 0xFFFFFFFF - ticks;
00140         }
00141 
00142         if (__systemTickCount - ticks > CPU_MS_TO_TICKS(1000))
00143         {
00144             __systemSecondsCount += (__systemTickCount - ticks) / CPU_MS_TO_TICKS(1000);
00145             ticks = __systemTickCount;
00146         }
00147 
00148         __threadSleep(__CONFIG_SYSTHREAD_SLEEP_TIME);
00149     }
00150 }
00151 
00158 __STATIC __VOID __systemInitThread(__VOID)
00159 {
00160 
00161     /* Create system thread */
00162     __systemThreadPtr = __threadCreate( "system",                       /* name         */
00163                                         __systemThread,                 /* function     */
00164                                         __CONFIG_PRIO_SYSTHREAD,        /* priority     */
00165                                         __CONFIG_STACK_SYSTHREAD,       /* stack        */
00166                                         1,                              /* time to live */
00167                                         __NULL);                        /* parameter    */
00168 
00169     /* Call platform custom initialization before activating
00170      * the scheduler
00171      */
00172     __cpuCustomCreateSystemThread();
00173 }
00174 
00186 __VOID __systemInit(__APP_ENTRY* entry)
00187 {
00188     /* Avoid interrupts we are not handling yet */
00189     __systemStop();
00190     
00191     __systemAppEntry = entry;
00192     
00193     /* Init CPU hardware */
00194     __cpuInitHardware();
00195     
00196     /* MMU */
00197     __cpuStartMMU();
00198 
00199     /* Init Interrupts */
00200     __cpuInitInterrupts();
00201 
00202     /* Init Heap */
00203     __heapInit(&__CPU_HEAP_BASE, (u32) &__CPU_HEAP_SIZE);
00204 
00205     /* Init RTC */
00206 #if __CONFIG_COMPILE_RTC
00207     __rtcInit();
00208 #endif /* __CONFIG_COMPILE_RTC */
00209 
00210     /* Initialize Watchdog */
00211 #if __CONFIG_ENABLE_WATCHDOG
00212 //  __cpuStartWatchdog();
00213 #endif /* __CONFIG_ENABLE_WATCHDOG */
00214     
00215     /* Create System Threads */
00216     __systemInitThread();
00217 
00218     /* Init Scheduler timer after creating the first thread */
00219     __cpuInitSchedulerTimer();
00220 
00221     __systemScheduleThreadChange();
00222 
00223     /* Enable interrupts */
00224     __systemStart();
00225 
00226     /* If everything is OK, we should be running the OS by now.
00227      * This function will never return. __systemThread() will now enter execution under
00228      * the context of the OS.
00229      */
00230     for (;;)
00231     {
00232     }
00233 }
00234 
00242 __VOID __systemProcessTick(__VOID)
00243 {
00244     /* Software system ticks */
00245     __systemTickCount++;
00246     __threadProcessTick();
00247 }
00248 
00254 __VOID __systemStop(__VOID)
00255 {
00256     if (!__systemIrqCount)
00257     {
00258         __cpuDisableInterrupts();
00259     }
00260     __systemIrqCount++;
00261 }
00262 
00268 __VOID __systemStart(__VOID)
00269 {
00270     if (__systemIrqCount && --__systemIrqCount) {
00271         return;
00272     }
00273 
00274     /* enable interrupts */
00275     __cpuEnableInterrupts();
00276 }
00277 
00278 
00289 __VOID __systemEnableScheduler(__VOID)
00290 {
00291     __systemStop();
00292     if (__systemContextSwCount)
00293     {
00294         __systemContextSwCount--;
00295 
00296         /* Check for pending thread change request */
00297         if (!__systemContextSwCount && __systemContextSwRequest)
00298         {
00299             __systemContextSwRequest = 0;
00300 
00301             /* Check if there is a ready thread with higher priority
00302              * than the current one.
00303              */
00304             if (__threadGetCurrent()) {
00305                 if (__threadGetCurrent()->th_priority > __threadGetReady()->th_priority)
00306                 {
00307                     __threadAddToReadyList(__threadGetCurrent());
00308                     __threadSetCurrent(__NULL);
00309                     __systemScheduleThreadChange();
00310                 }
00311             }
00312         }
00313     }
00314     __systemStart();
00315 }
00316 
00324 __VOID __systemDisableScheduler(__VOID)
00325 {
00326     __systemStop();
00327     __systemContextSwCount++;
00328     if (__cpuThreadChangeScheduled())
00329         __cpuClearPendingThreadChange();
00330     __systemStart();
00331 }
00332 
00338 __VOID __systemScheduleThreadChange(__VOID)
00339 {
00340     if (!__systemContextSwCount)
00341     {
00342         __cpuScheduleThreadChange();
00343     } else
00344     {
00345         __systemContextSwRequest = 1;
00346     }
00347 }
00348 
00354 __VOID __systemEnterISR(__VOID)
00355 {
00356     __systemNestingISR++;
00357 }
00358 
00365 __VOID __systemLeaveISR(__VOID)
00366 {
00367     __systemNestingISR--;
00368 }
00369 
00376 u32 __systemGetTickCount(__VOID)
00377 {
00378     return __systemTickCount;
00379 }
00380 
00386 u32 __systemGetSecondsCount(__VOID)
00387 {
00388     return __systemSecondsCount;
00389 }
00390 
00396 u32 __systemGetIrqCount(__VOID)
00397 {
00398     return __systemIrqCount;
00399 }
00400 
00406 __BOOL __systemSchedulerDisabled(__VOID)
00407 {
00408     if (__systemContextSwCount) return __TRUE;
00409     return __FALSE;
00410 }
00411 
 All Data Structures Files Functions Variables Typedefs Defines