Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard. Patched to work with NUCLEO L152 board

Fork of mbed-rtos by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RTX_CM_lib.h Source File

RTX_CM_lib.h

00001 /*----------------------------------------------------------------------------
00002  *      RL-ARM - RTX
00003  *----------------------------------------------------------------------------
00004  *      Name:    RTX_CM_LIB.H
00005  *      Purpose: RTX Kernel System Configuration
00006  *      Rev.:    V4.60
00007  *----------------------------------------------------------------------------
00008  *
00009  * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
00010  * All rights reserved.
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are met:
00013  *  - Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  *  - Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  *  - Neither the name of ARM  nor the names of its contributors may be used
00019  *    to endorse or promote products derived from this software without
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
00026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  *---------------------------------------------------------------------------*/
00034 #include "mbed_error.h"
00035 
00036 #if   defined (__CC_ARM)
00037 #pragma O3
00038 #define __USED __attribute__((used))
00039 #elif defined (__GNUC__)
00040 #pragma GCC optimize ("O3")
00041 #define __USED __attribute__((used))
00042 #elif defined (__ICCARM__)
00043 #define __USED __root
00044 #endif
00045 
00046 
00047 /*----------------------------------------------------------------------------
00048  *      Definitions
00049  *---------------------------------------------------------------------------*/
00050 
00051 #define _declare_box(pool,size,cnt)  uint32_t pool[(((size)+3)/4)*(cnt) + 3]
00052 #define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
00053 
00054 #define OS_TCB_SIZE     48
00055 #define OS_TMR_SIZE     8
00056 
00057 #if defined (__CC_ARM) && !defined (__MICROLIB)
00058 
00059 typedef void    *OS_ID;
00060 typedef uint32_t OS_TID;
00061 typedef uint32_t OS_MUT[3];
00062 typedef uint32_t OS_RESULT;
00063 
00064 #define runtask_id()    rt_tsk_self()
00065 #define mutex_init(m)   rt_mut_init(m)
00066 #define mutex_wait(m)   os_mut_wait(m,0xFFFF)
00067 #define mutex_rel(m)    os_mut_release(m)
00068 
00069 extern OS_TID    rt_tsk_self    (void);
00070 extern void      rt_mut_init    (OS_ID mutex);
00071 extern OS_RESULT rt_mut_release (OS_ID mutex);
00072 extern OS_RESULT rt_mut_wait    (OS_ID mutex, uint16_t timeout);
00073 
00074 #define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout)
00075 #define os_mut_release(mutex)      _os_mut_release((uint32_t)rt_mut_release,mutex)
00076 
00077 OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex)                   __svc_indirect(0);
00078 OS_RESULT _os_mut_wait    (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0);
00079 
00080 #endif
00081 
00082 
00083 /*----------------------------------------------------------------------------
00084  *      Global Variables
00085  *---------------------------------------------------------------------------*/
00086 
00087 #if (OS_TIMERS != 0)
00088 #define OS_TASK_CNT (OS_TASKCNT + 1)
00089 #else
00090 #define OS_TASK_CNT  OS_TASKCNT
00091 #endif
00092 
00093 uint16_t const os_maxtaskrun = OS_TASK_CNT;
00094 uint32_t const os_rrobin     = (OS_ROBIN << 16) | OS_ROBINTOUT;
00095 uint32_t const os_trv        = OS_TRV;
00096 uint8_t  const os_flags      = OS_RUNPRIV;
00097 
00098 /* Export following defines to uVision debugger. */
00099 __USED uint32_t const os_clockrate = OS_TICK;
00100 __USED uint32_t const os_timernum  = 0;
00101 
00102 /* Stack for the os_idle_demon */
00103 unsigned int idle_task_stack[OS_IDLESTKSIZE];
00104 unsigned short const idle_task_stack_size = OS_IDLESTKSIZE;
00105 
00106 #ifndef OS_FIFOSZ
00107  #define OS_FIFOSZ      16
00108 #endif
00109 
00110 /* Fifo Queue buffer for ISR requests.*/
00111 uint32_t       os_fifo[OS_FIFOSZ*2+1];
00112 uint8_t  const os_fifo_size = OS_FIFOSZ;
00113 
00114 /* An array of Active task pointers. */
00115 void *os_active_TCB[OS_TASK_CNT];
00116 
00117 /* User Timers Resources */
00118 #if (OS_TIMERS != 0)
00119 extern void osTimerThread (void const *argument);
00120 osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ);
00121 osThreadId osThreadId_osTimerThread;
00122 osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *);
00123 osMessageQId osMessageQId_osTimerMessageQ;
00124 #else
00125 osThreadDef_t os_thread_def_osTimerThread = { NULL };
00126 osThreadId osThreadId_osTimerThread;
00127 osMessageQDef(osTimerMessageQ, 0, void *);
00128 osMessageQId osMessageQId_osTimerMessageQ;
00129 #endif
00130 
00131 
00132 /*----------------------------------------------------------------------------
00133  *      RTX Optimizations (empty functions)
00134  *---------------------------------------------------------------------------*/
00135 
00136 #if OS_ROBIN == 0
00137  void rt_init_robin (void) {;}
00138  void rt_chk_robin  (void) {;}
00139 #endif
00140 
00141 #if OS_STKCHECK == 0
00142  void rt_stk_check  (void) {;}
00143 #endif
00144 
00145 
00146 /*----------------------------------------------------------------------------
00147  *      Standard Library multithreading interface
00148  *---------------------------------------------------------------------------*/
00149 
00150 #if defined (__CC_ARM) && !defined (__MICROLIB)
00151  static OS_MUT   std_libmutex[OS_MUTEXCNT];
00152  static uint32_t nr_mutex;
00153 
00154  /*--------------------------- _mutex_initialize -----------------------------*/
00155 
00156 int _mutex_initialize (OS_ID *mutex) {
00157   /* Allocate and initialize a system mutex. */
00158 
00159   if (nr_mutex >= OS_MUTEXCNT) {
00160     /* If you are here, you need to increase the number OS_MUTEXCNT. */
00161     error("Not enough stdlib mutexes\n");
00162   }
00163   *mutex = &std_libmutex[nr_mutex++];
00164   mutex_init (*mutex);
00165   return (1);
00166 }
00167 
00168 
00169 /*--------------------------- _mutex_acquire --------------------------------*/
00170 
00171 __attribute__((used)) void _mutex_acquire (OS_ID *mutex) {
00172   /* Acquire a system mutex, lock stdlib resources. */
00173   if (runtask_id ()) {
00174     /* RTX running, acquire a mutex. */
00175     mutex_wait (*mutex);
00176   }
00177 }
00178 
00179 
00180 /*--------------------------- _mutex_release --------------------------------*/
00181 
00182 __attribute__((used)) void _mutex_release (OS_ID *mutex) {
00183   /* Release a system mutex, unlock stdlib resources. */
00184   if (runtask_id ()) {
00185     /* RTX running, release a mutex. */
00186     mutex_rel (*mutex);
00187   }
00188 }
00189 
00190 #endif
00191 
00192 
00193 /*----------------------------------------------------------------------------
00194  *      RTX Startup
00195  *---------------------------------------------------------------------------*/
00196 
00197 /* Main Thread definition */
00198 extern int main (void);
00199 osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL};
00200 
00201 // This define should be probably moved to the CMSIS layer
00202 #if   defined(TARGET_LPC1768)
00203 #define INITIAL_SP            (0x10008000UL)
00204 
00205 #elif defined(TARGET_LPC11U24)
00206 #define INITIAL_SP            (0x10002000UL)
00207 
00208 #elif defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO)
00209 #define INITIAL_SP            (0x10002000UL)
00210 
00211 #elif defined(TARGET_LPC1114)
00212 #define INITIAL_SP            (0x10001000UL)
00213 
00214 #elif defined(TARGET_LPC812)
00215 #define INITIAL_SP            (0x10001000UL)
00216 
00217 #elif defined(TARGET_KL25Z)
00218 #define INITIAL_SP            (0x20003000UL)
00219 
00220 #elif defined(TARGET_K64F)
00221 #define INITIAL_SP            (0x20030000UL)
00222 
00223 #elif defined(TARGET_KL46Z)
00224 #define INITIAL_SP            (0x20006000UL)
00225 
00226 #elif defined(TARGET_KL05Z)
00227 #define INITIAL_SP            (0x20000C00UL)
00228 
00229 #elif defined(TARGET_LPC4088)
00230 #define INITIAL_SP            (0x10010000UL)
00231 
00232 #elif defined(TARGET_LPC4337)
00233 #define INITIAL_SP            (0x10008000UL)
00234 
00235 #elif defined(TARGET_LPC1347)
00236 #define INITIAL_SP            (0x10002000UL)
00237 
00238 #elif defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8)
00239 #define INITIAL_SP            (0x20002000UL)
00240 
00241 #elif defined(TARGET_DISCO_F303VC)
00242 #define INITIAL_SP            (0x2000A000UL)
00243 
00244 #elif defined(TARGET_STM32F407) || defined(TARGET_F407VG)
00245 #define INITIAL_SP            (0x20020000UL)
00246 
00247 #elif defined(TARGET_STM32F401RE)
00248 #define INITIAL_SP            (0x20018000UL)
00249 
00250 #elif defined(TARGET_LPC1549)
00251 #define INITIAL_SP            (0x02009000UL)
00252 
00253 #elif defined(TARGET_LPC11U68)
00254 #define INITIAL_SP            (0x10004000UL)
00255 
00256 #elif defined(TARGET_NRF51822) || defined (TARGET_NUCLEO_L152RE)
00257 #define INITIAL_SP            (0x20004000UL)
00258 
00259 #elif defined(TARGET_STM32F411RE)
00260 #define INITIAL_SP            (0x20020000UL)
00261 
00262 #else
00263 #error "no target defined"
00264 
00265 #endif
00266 
00267 #ifdef __CC_ARM
00268 extern unsigned char     Image$$RW_IRAM1$$ZI$$Limit[];
00269 #define HEAP_START      (Image$$RW_IRAM1$$ZI$$Limit)
00270 #elif defined(__GNUC__)
00271 extern unsigned char     __end__[];
00272 #define HEAP_START      (__end__)
00273 #endif
00274 
00275 void set_main_stack(void) {
00276     // That is the bottom of the main stack block: no collision detection
00277     os_thread_def_main.stack_pointer = HEAP_START;
00278 
00279     // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts
00280     os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_SCHEDULERSTKSIZE * 4);
00281 }
00282 
00283 #if defined (__CC_ARM)
00284 #ifdef __MICROLIB
00285 void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
00286 void _main_init (void) {
00287   osKernelInitialize();
00288   set_main_stack();
00289   osThreadCreate(&os_thread_def_main, NULL);
00290   osKernelStart();
00291   for (;;);
00292 }
00293 #else
00294 
00295 /* The single memory model is checking for stack collision at run time, verifing
00296    that the heap pointer is underneath the stack pointer.
00297 
00298    With the RTOS there is not only one stack above the heap, there are multiple
00299    stacks and some of them are underneath the heap pointer.
00300 */
00301 #pragma import(__use_two_region_memory)
00302 
00303 __asm void __rt_entry (void) {
00304 
00305   IMPORT  __user_setup_stackheap
00306   IMPORT  __rt_lib_init
00307   IMPORT  os_thread_def_main
00308   IMPORT  osKernelInitialize
00309   IMPORT  set_main_stack
00310   IMPORT  osKernelStart
00311   IMPORT  osThreadCreate
00312   IMPORT  exit
00313 
00314   BL      __user_setup_stackheap
00315   MOV     R1,R2
00316   BL      __rt_lib_init
00317   BL      osKernelInitialize
00318   BL      set_main_stack
00319   LDR     R0,=os_thread_def_main
00320   MOVS    R1,#0
00321   BL      osThreadCreate
00322   BL      osKernelStart
00323   BL      exit
00324 
00325   ALIGN
00326 }
00327 #endif
00328 
00329 #elif defined (__GNUC__)
00330 
00331 #ifdef __CS3__
00332 
00333 /* CS3 start_c routine.
00334  *
00335  * Copyright (c) 2006, 2007 CodeSourcery Inc
00336  *
00337  * The authors hereby grant permission to use, copy, modify, distribute,
00338  * and license this software and its documentation for any purpose, provided
00339  * that existing copyright notices are retained in all copies and that this
00340  * notice is included verbatim in any distributions. No written agreement,
00341  * license, or royalty fee is required for any of the authorized uses.
00342  * Modifications to this software may be copyrighted by their authors
00343  * and need not follow the licensing terms described here, provided that
00344  * the new terms are clearly indicated on the first page of each file where
00345  * they apply.
00346  */
00347 
00348 #include "cs3.h"
00349 
00350 extern void __libc_init_array (void);
00351 
00352 __attribute ((noreturn)) void __cs3_start_c (void){
00353   unsigned regions = __cs3_region_num;
00354   const struct __cs3_region *rptr = __cs3_regions;
00355 
00356   /* Initialize memory */
00357   for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) {
00358     long long *src = (long long *)rptr->init;
00359     long long *dst = (long long *)rptr->data;
00360     unsigned limit = rptr->init_size;
00361     unsigned count;
00362 
00363     if (src != dst)
00364       for (count = 0; count != limit; count += sizeof (long long))
00365         *dst++ = *src++;
00366     else
00367       dst = (long long *)((char *)dst + limit);
00368     limit = rptr->zero_size;
00369     for (count = 0; count != limit; count += sizeof (long long))
00370       *dst++ = 0;
00371   }
00372 
00373   /* Run initializers.  */
00374   __libc_init_array ();
00375 
00376   osKernelInitialize();
00377   set_main_stack();
00378   osThreadCreate(&os_thread_def_main, NULL);
00379   osKernelStart();
00380   for (;;);
00381 }
00382 
00383 #else
00384 
00385 __attribute__((naked)) void software_init_hook (void) {
00386   __asm (
00387     ".syntax unified\n"
00388     ".thumb\n"
00389     "movs r0,#0\n"
00390     "movs r1,#0\n"
00391     "mov  r4,r0\n"
00392     "mov  r5,r1\n"
00393     "ldr  r0,= __libc_fini_array\n"
00394     "bl   atexit\n"
00395     "bl   __libc_init_array\n"
00396     "mov  r0,r4\n"
00397     "mov  r1,r5\n"
00398     "bl   osKernelInitialize\n"
00399     "bl   set_main_stack\n"
00400     "ldr  r0,=os_thread_def_main\n"
00401     "movs r1,#0\n"
00402     "bl   osThreadCreate\n"
00403     "bl   osKernelStart\n"
00404     "bl   exit\n"
00405   );
00406 }
00407 
00408 #endif
00409 
00410 #elif defined (__ICCARM__)
00411 
00412 extern int  __low_level_init(void);
00413 extern void __iar_data_init3(void);
00414 extern void exit(int arg);
00415 
00416 __noreturn __stackless void __cmain(void) {
00417   int a;
00418 
00419   if (__low_level_init() != 0) {
00420     __iar_data_init3();
00421   }
00422   osKernelInitialize();
00423   osThreadCreate(&os_thread_def_main, NULL);
00424   a = osKernelStart();
00425   exit(a);
00426 }
00427 
00428 #endif
00429 
00430 
00431 /*----------------------------------------------------------------------------
00432  * end of file
00433  *---------------------------------------------------------------------------*/
00434 
00435