Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RTX_lib.c Source File

RTX_lib.c

Go to the documentation of this file.
00001 /**
00002  * @file    RTX_lib.c
00003  * @brief   
00004  *
00005  * DAPLink Interface Firmware
00006  * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
00007  * SPDX-License-Identifier: Apache-2.0
00008  *
00009  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00010  * not use this file except in compliance with the License.
00011  * You may obtain a copy of the License at
00012  *
00013  * http://www.apache.org/licenses/LICENSE-2.0
00014  *
00015  * Unless required by applicable law or agreed to in writing, software
00016  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00017  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00018  * See the License for the specific language governing permissions and
00019  * limitations under the License.
00020  */
00021 
00022 #pragma thumb
00023 #pragma O3
00024 
00025 /*----------------------------------------------------------------------------
00026  *      Definitions
00027  *---------------------------------------------------------------------------*/
00028 #if   (__TARGET_ARCH_6S_M || __TARGET_ARCH_7_M || __TARGET_ARCH_7E_M)
00029  #define __CM__   1
00030 #elif (__TARGET_ARCH_7_R)
00031  #define __CR__   1
00032 #else
00033  #define __ARM__  1
00034 #endif
00035 
00036 #if (__ARM__ || __CR__)
00037  #define runtask_id()   os_tsk_self()
00038  #define mutex_init(m)  os_mut_init(m)
00039 #endif
00040 #if (__CM__)
00041  #ifndef OS_TIMER
00042   #define OS_TIMER      0
00043  #endif
00044  #define runtask_id()   rt_tsk_self()
00045  #define mutex_init(m)  rt_mut_init(m)
00046 #endif
00047 
00048 #define mutex_wait(m)   os_mut_wait(m,0xFFFF)
00049 #define mutex_rel(m)    os_mut_release(m)
00050 
00051 
00052 /*----------------------------------------------------------------------------
00053  *      Global Variables
00054  *---------------------------------------------------------------------------*/
00055 U16 const os_maxtaskrun = OS_TASKCNT;
00056 U32 const os_stackinfo  = (OS_STKCHECK<<24)| (OS_PRIVCNT<<16) | (OS_STKSIZE*4);
00057 U32 const os_rrobin     = (OS_ROBIN << 16) | OS_ROBINTOUT;
00058 #if (__CM__)
00059  U32 const os_trv       = OS_TRV;
00060 #endif
00061 #if (__CM__ || __CR__)
00062  U8  const os_flags     = OS_RUNPRIV;
00063 #endif
00064 
00065 /* Export following defines to uVision debugger. */
00066 U32 const os_clockrate __attribute__((used)) =  OS_TICK;
00067 U32 const os_timernum  __attribute__((used)) = (OS_TIMER << 16) | OS_TIMERCNT;
00068 
00069 /* Memory pool for TCB allocation    */
00070 _declare_box (mp_tcb, OS_TCB_SIZE, OS_TASKCNT);
00071 U16 const mp_tcb_size = sizeof(mp_tcb);
00072 
00073 /* Memory pool for System stack allocation (+ os_idle_demon). */
00074 _declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASKCNT-OS_PRIVCNT+1);
00075 U32 const mp_stk_size = sizeof(mp_stk);
00076 
00077 #ifndef OS_FIFOSZ
00078  #define OS_FIFOSZ        16
00079 #endif
00080 
00081 /* Fifo Queue buffer for ISR requests.*/
00082 U32 os_fifo[OS_FIFOSZ*2+1];
00083 U8 const os_fifo_size = OS_FIFOSZ;
00084 
00085 /* An array of Active task pointers. */
00086 void *os_active_TCB[OS_TASKCNT];
00087 
00088 #if (OS_TIMERCNT != 0)
00089  /* Memory pool for User Timer allocation */
00090  _declare_box (mp_tmr, OS_TMR_SIZE, OS_TIMERCNT);
00091  U16 const mp_tmr_size = sizeof(mp_tmr);
00092  U32 const *m_tmr = &mp_tmr[0];
00093 #else
00094  U32 const *m_tmr = NULL;
00095  U16 const mp_tmr_size = 0;
00096 #endif
00097 
00098 #ifndef __MICROLIB
00099  /* A memory space for arm standard library. */
00100  static U32    std_libspace[OS_TASKCNT][96/4];
00101  static OS_MUT std_libmutex[OS_MUTEXCNT];
00102  static U32    nr_mutex;
00103  extern void  *__libspace_start;
00104 #endif
00105 
00106 /*----------------------------------------------------------------------------
00107  *      Tick Timer configuration for ARM7/9, Cortex-R4
00108  *---------------------------------------------------------------------------*/
00109 
00110 #if (__ARM__ || __CR__)
00111 
00112 extern void os_clock_interrupt (void);
00113 
00114 /*--------------------------- os_tmr_init -----------------------------------*/
00115 
00116 #ifndef __OS_TMR_INIT
00117 void os_tmr_init (void) {
00118   /* Initialize hardware timer as system tick timer. */
00119   OS_TINIT();
00120 }
00121 #endif
00122 
00123 /*--------------------------- os_tmr_reload ---------------------------------*/
00124 
00125 #if (!defined(__OS_TMR_RELOAD) && defined(OS_TREL))
00126 void os_tmr_reload (void) {
00127   /* Reload system timer for next period. */
00128   OS_TREL();
00129 }
00130 #endif
00131 
00132 /*--------------------------- os_tmr_force_irq ------------------------------*/
00133 
00134 #ifndef __OS_TMR_FORCE_IRQ
00135 void os_tmr_force_irq (void) {
00136   /* Force a timer interrupt. */
00137   OS_TFIRQ();
00138 }
00139 #endif
00140 
00141 /*--------------------------- os_tmr_inspect_cnt ----------------------------*/
00142 
00143 #ifndef __OS_TMR_INSPECT_CNT
00144 U32 os_tmr_inspect_cnt (void) {
00145   /* Inspect current value of rtx timer. */
00146   return (OS_TVAL);
00147 }
00148 #endif
00149 
00150 /*--------------------------- os_tmr_inspect_ovf ----------------------------*/
00151 
00152 #ifndef __OS_TMR_INSPECT_OVF
00153 BOOL os_tmr_inspect_ovf (void) {
00154   /* Inspect current state of timer overflow flag. */
00155   return (OS_TOVF);
00156 }
00157 #endif
00158 
00159 /*--------------------------- os_irq_ack_lock -------------------------------*/
00160 
00161 #ifndef __OS_IRQ_ACK_LOCK
00162 void os_irq_ack_lock (void) {
00163   /* Acknowledge and disable a timer interrupt. */
00164   OS_TIACK();
00165   OS_LOCK();
00166 }
00167 #endif
00168 
00169 /*--------------------------- tsk_lock --------------------------------------*/
00170 
00171 #ifndef __TSK_LOCK
00172 void __swi(5) tsk_lock (void);
00173 void __SWI_5           (void) {
00174   /* Disable RTX System Tick Timer interrupts. */
00175   OS_LOCK();
00176 }
00177 #endif
00178 
00179 /*--------------------------- tsk_unlock ------------------------------------*/
00180 
00181 #ifndef __TSK_UNLOCK
00182 void tsk_unlock (void) {
00183   /* Enable RTX System Tick Timer Interrupts. */
00184   OS_UNLOCK();
00185 }
00186 #endif
00187 
00188 #endif /* #if (__ARM__ || __CR__) */
00189 
00190 
00191 /*----------------------------------------------------------------------------
00192  *      RT Agent interface for ARM7/9
00193  *---------------------------------------------------------------------------*/
00194 
00195 #if (__ARM__ && __RTA_RTX_CONFIG)
00196 
00197 #include "RT_Agent.h"
00198 
00199 #if (__RTA_ENABLED && __RTA_RTX_TASK_SWITCHING)
00200 /*
00201  * RT Agent - Event Viewer Packing
00202  *
00203  *    |---+---------+---------+------|
00204  *    | 0 | os_time | hw_tick | t_id |
00205  *    |---+---------+---------+------|
00206  * bit  31          ^          7    0
00207  *                  +-- OS_TIME_SL
00208  *
00209  *  value hw_tick is truncated    by number of bits specified by OS_TVAL_SR
00210  *  value os_time is shifted left by number of bits specified by OS_TIME_SL
00211  */
00212 
00213 /* Define pack shift values depending on the tick time value OS_TICK.  */
00214 /* Packing results in a time of ~1 second being represented, and an    */
00215 /* accuracy of ~0.15us. (based on the hw tick timer accuracy.          */
00216 
00217 #if   ((OS_TICK) < 0x80)        // OS_TICK < 128us  ==> tick 14 bits, timer 9
00218  #define OS_TIME_SL     17
00219 #elif ((OS_TICK) < 0x100)       // OS_TICK < 256us  ==> tick 13 bits, timer 10
00220  #define OS_TIME_SL     18
00221 #elif ((OS_TICK) < 0x200)       // OS_TICK < 512us  ==> tick 12 bits, timer 11
00222  #define OS_TIME_SL     19
00223 #elif ((OS_TICK) < 0x400)       // OS_TICK < 1.024ms ==> tick 11 bits, timer 12
00224  #define OS_TIME_SL     20
00225 #elif ((OS_TICK) < 0x800)       // OS_TICK < 2.048ms ==> tick 10 bits, timer 13
00226  #define OS_TIME_SL     21
00227 #elif ((OS_TICK) < 0x1000)      // OS_TICK < 4.096ms ==> tick 9 bits, timer 14
00228  #define OS_TIME_SL     22
00229 #elif ((OS_TICK) < 0x2000)      // OS_TICK < 8.192ms ==> tick 8 bits, timer 15
00230  #define OS_TIME_SL     23
00231 #elif ((OS_TICK) < 0x4000)      // OS_TICK < 16.384ms ==> tick 7 bits, timer 16
00232  #define OS_TIME_SL     24
00233 #elif ((OS_TICK) < 0x8000)      // OS_TICK < 32.768ms ==> tick 6 bits, timer 17
00234  #define OS_TIME_SL     25
00235 #elif ((OS_TICK) < 0x10000)     // OS_TICK < 65.536ms ==> tick 5 bits, timer 18
00236  #define OS_TIME_SL     26
00237 #elif ((OS_TICK) < 0x20000)     // OS_TICK < 131.070ms ==> tick 4 bits, timer 19
00238  #define OS_TIME_SL     27
00239 #elif ((OS_TICK) < 0x40000)     // OS_TICK < 262.140ms ==> tick 3 bits, timer 20
00240  #define OS_TIME_SL     28
00241 #elif ((OS_TICK) < 0x80000)     // OS_TICK < 524.280ms ==> tick 2 bits, timer 21
00242  #define OS_TIME_SL     29
00243 #else                           // OS_TICK >= 524.280ms ==> tick 1 bit, timer 22
00244  #define OS_TIME_SL     30
00245 #endif
00246 
00247 /* Define hw_tick truncation depending on the timer reload value OS_TRV */
00248 #if ((OS_TRV) < 0x10)
00249  #define OS_TVAL_SR     (12 - OS_TIME_SL)
00250 #elif ((OS_TRV) < 0x20)
00251  #define OS_TVAL_SR     (13 - OS_TIME_SL)
00252 #elif ((OS_TRV) < 0x40)
00253  #define OS_TVAL_SR     (14 - OS_TIME_SL)
00254 #elif ((OS_TRV) < 0x80)
00255  #define OS_TVAL_SR     (15 - OS_TIME_SL)
00256 #elif ((OS_TRV) < 0x100)
00257  #define OS_TVAL_SR     (16 - OS_TIME_SL)
00258 #elif ((OS_TRV) < 0x200)
00259  #define OS_TVAL_SR     (17 - OS_TIME_SL)
00260 #elif ((OS_TRV) < 0x400)
00261  #define OS_TVAL_SR     (18 - OS_TIME_SL)
00262 #elif ((OS_TRV) < 0x800)
00263  #define OS_TVAL_SR     (19 - OS_TIME_SL)
00264 #elif ((OS_TRV) < 0x1000)
00265  #define OS_TVAL_SR     (20 - OS_TIME_SL)
00266 #elif ((OS_TRV) < 0x2000)
00267  #define OS_TVAL_SR     (21 - OS_TIME_SL)
00268 #elif ((OS_TRV) < 0x4000)
00269  #define OS_TVAL_SR     (22 - OS_TIME_SL)
00270 #elif ((OS_TRV) < 0x8000)
00271  #define OS_TVAL_SR     (23 - OS_TIME_SL)
00272 #elif ((OS_TRV) < 0x10000)
00273  #define OS_TVAL_SR     (24 - OS_TIME_SL)
00274 #elif ((OS_TRV) < 0x20000)
00275  #define OS_TVAL_SR     (25 - OS_TIME_SL)
00276 #elif ((OS_TRV) < 0x40000)
00277  #define OS_TVAL_SR     (26 - OS_TIME_SL)
00278 #elif ((OS_TRV) < 0x80000)
00279  #define OS_TVAL_SR     (27 - OS_TIME_SL)
00280 #elif ((OS_TRV) < 0x100000)
00281  #define OS_TVAL_SR     (28 - OS_TIME_SL)
00282 #elif ((OS_TRV) < 0x200000)
00283  #define OS_TVAL_SR     (29 - OS_TIME_SL)
00284 #elif ((OS_TRV) < 0x400000)
00285  #define OS_TVAL_SR     (30 - OS_TIME_SL)
00286 #elif ((OS_TRV) < 0x800000)
00287  #define OS_TVAL_SR     (31 - OS_TIME_SL)
00288 #elif ((OS_TRV) < 0x1000000)
00289  #define OS_TVAL_SR     (32 - OS_TIME_SL)
00290 #elif ((OS_TRV) < 0x2000000)
00291  #define OS_TVAL_SR     (33 - OS_TIME_SL)
00292 #elif ((OS_TRV) < 0x4000000)
00293  #define OS_TVAL_SR     (34 - OS_TIME_SL)
00294 #elif ((OS_TRV) < 0x8000000)
00295  #define OS_TVAL_SR     (35 - OS_TIME_SL)
00296 #else
00297  #define OS_TVAL_SR     (36 - OS_TIME_SL)
00298 #endif
00299 
00300 #if (OS_TVAL_SR < 0)
00301  #undef  OS_TVAL_SR
00302  #define OS_TVAL_SR     0
00303 #endif
00304 
00305 extern U32 os_time;
00306 
00307 /* Export following defines to uVision debugger. */
00308 U8  const os_time_sl __attribute__((used)) = OS_TIME_SL;
00309 U32 const os_treload __attribute__((used)) = OS_TRV;
00310 
00311 __weak extern void RTA_Task_Mon (unsigned int tsk);
00312 
00313 #define RTA_CMD_RTX_TASK_INFO   0x0A
00314 
00315 void rt_notify (U32 ptask, U32 create_tid) {
00316   /* Notify RTA user of a task creation/deletion. */
00317   U32 msg[2];
00318 
00319   /* (BOOL)create << 8 | task_id - parameter packed in RTX library */
00320   msg[0] = create_tid;
00321   msg[1] = (U32)ptask;
00322   RTA_Msg (RTA_CMD_RTX_TASK_INFO, (U32 *)&msg, 2);
00323 }
00324 
00325 /*--------------------------- rt_post_taskswitch ----------------------------*/
00326 
00327 void rt_post_taskswitch (U32 task_id)  {
00328   U32 tsk_event;
00329 
00330   /* Add the current timer value (with bottom bits removed) */
00331   tsk_event = OS_TVAL >> OS_TVAL_SR;
00332   /* Shif timer value into place, add the task ID. */
00333   tsk_event = (tsk_event << 8) | task_id;
00334   /* Add the OS tick time. */
00335   tsk_event = tsk_event | (os_time << OS_TIME_SL);
00336   /* Mask off the top bit to indicate a task switch message. */
00337   tsk_event &= 0x7FFFFFFFU;
00338 
00339   RTA_Task_Mon (tsk_event);
00340 }
00341 
00342 #endif /* #if (__RTA_ENABLED && __RTA_RTX_TASK_SWITCHING) */
00343 
00344 /*--------------------------- rt_init ---------------------------------------*/
00345 
00346 void rt_init (void) {
00347   RTA_Init ();
00348 }
00349 
00350 
00351 #include "RT_Agent.c"
00352 
00353 #endif /* #if (__ARM__ && __RTA_RTX_CONFIG) */
00354                                               
00355 
00356 /*----------------------------------------------------------------------------
00357  *      RTX Optimizations (empty functions)
00358  *---------------------------------------------------------------------------*/
00359 
00360 #if (__ARM__ || __CR__) && OS_ROBIN == 0
00361  void os_init_robin (void) {;}
00362  void os_chk_robin  (void) {;}
00363 #endif
00364 
00365 #if (__ARM__ || __CR__) && OS_STKCHECK == 0
00366  void os_stk_check  (U32 stk) {;}
00367 #endif
00368 
00369 #if (__CM__) && OS_ROBIN == 0
00370  void rt_init_robin (void) {;}
00371  void rt_chk_robin  (void) {;}
00372 #endif
00373 
00374 #if (__CM__) && OS_STKCHECK == 0
00375  void rt_stk_check  (void) {;}
00376 #endif
00377 
00378 
00379 /*----------------------------------------------------------------------------
00380  *      Standard Library multithreading interface
00381  *---------------------------------------------------------------------------*/
00382 
00383 #ifndef __MICROLIB
00384 
00385 /*--------------------------- __user_perthread_libspace ---------------------*/
00386 
00387 void *__user_perthread_libspace (void) {
00388   /* Provide a separate libspace for each task. */
00389   U32 idx;
00390 
00391   idx = runtask_id ();
00392   if (idx == 0) {
00393     /* RTX not running yet. */
00394     return (&__libspace_start);
00395   }
00396   return ((void *)&std_libspace[idx-1]);
00397 }
00398 
00399 /*--------------------------- _mutex_initialize -----------------------------*/
00400 
00401 int _mutex_initialize (OS_ID *mutex) {
00402   /* Allocate and initialize a system mutex. */
00403 
00404   if (nr_mutex >= OS_MUTEXCNT) {
00405     /* If you are here, you need to increase the number OS_MUTEXCNT. */
00406     for (;;);
00407   }
00408   *mutex = &std_libmutex[nr_mutex++];
00409   mutex_init (*mutex);
00410   return (1);
00411 }
00412 
00413 
00414 /*--------------------------- _mutex_acquire --------------------------------*/
00415 
00416 __used void _mutex_acquire (OS_ID *mutex) {
00417   /* Acquire a system mutex, lock stdlib resources. */
00418   if (runtask_id ()) {
00419     /* RTX running, acquire a mutex. */
00420     mutex_wait (*mutex);
00421   }
00422 }
00423 
00424 
00425 /*--------------------------- _mutex_release --------------------------------*/
00426 
00427 __used void _mutex_release (OS_ID *mutex) {
00428   /* Release a system mutex, unlock stdlib resources. */
00429   if (runtask_id ()) {
00430     /* RTX runnning, release a mutex. */
00431     mutex_rel (*mutex);
00432   }
00433 }
00434 
00435 #endif
00436 
00437 /*----------------------------------------------------------------------------
00438  * end of file
00439  *---------------------------------------------------------------------------*/
00440