The code from https://github.com/vpcola/Nucleo

Committer:
sinrab
Date:
Wed Oct 08 11:00:24 2014 +0000
Revision:
0:5464d5e415e5
The code from https://github.com/vpcola/Nucleo

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sinrab 0:5464d5e415e5 1 /*----------------------------------------------------------------------------
sinrab 0:5464d5e415e5 2 * RL-ARM - RTX
sinrab 0:5464d5e415e5 3 *----------------------------------------------------------------------------
sinrab 0:5464d5e415e5 4 * Name: RT_SYSTEM.C
sinrab 0:5464d5e415e5 5 * Purpose: System Task Manager
sinrab 0:5464d5e415e5 6 * Rev.: V4.60
sinrab 0:5464d5e415e5 7 *----------------------------------------------------------------------------
sinrab 0:5464d5e415e5 8 *
sinrab 0:5464d5e415e5 9 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
sinrab 0:5464d5e415e5 10 * All rights reserved.
sinrab 0:5464d5e415e5 11 * Redistribution and use in source and binary forms, with or without
sinrab 0:5464d5e415e5 12 * modification, are permitted provided that the following conditions are met:
sinrab 0:5464d5e415e5 13 * - Redistributions of source code must retain the above copyright
sinrab 0:5464d5e415e5 14 * notice, this list of conditions and the following disclaimer.
sinrab 0:5464d5e415e5 15 * - Redistributions in binary form must reproduce the above copyright
sinrab 0:5464d5e415e5 16 * notice, this list of conditions and the following disclaimer in the
sinrab 0:5464d5e415e5 17 * documentation and/or other materials provided with the distribution.
sinrab 0:5464d5e415e5 18 * - Neither the name of ARM nor the names of its contributors may be used
sinrab 0:5464d5e415e5 19 * to endorse or promote products derived from this software without
sinrab 0:5464d5e415e5 20 * specific prior written permission.
sinrab 0:5464d5e415e5 21 *
sinrab 0:5464d5e415e5 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
sinrab 0:5464d5e415e5 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sinrab 0:5464d5e415e5 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sinrab 0:5464d5e415e5 25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
sinrab 0:5464d5e415e5 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
sinrab 0:5464d5e415e5 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
sinrab 0:5464d5e415e5 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
sinrab 0:5464d5e415e5 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
sinrab 0:5464d5e415e5 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sinrab 0:5464d5e415e5 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
sinrab 0:5464d5e415e5 32 * POSSIBILITY OF SUCH DAMAGE.
sinrab 0:5464d5e415e5 33 *---------------------------------------------------------------------------*/
sinrab 0:5464d5e415e5 34
sinrab 0:5464d5e415e5 35 #include "rt_TypeDef.h"
sinrab 0:5464d5e415e5 36 #include "RTX_Conf.h"
sinrab 0:5464d5e415e5 37 #include "rt_Task.h"
sinrab 0:5464d5e415e5 38 #include "rt_System.h"
sinrab 0:5464d5e415e5 39 #include "rt_Event.h"
sinrab 0:5464d5e415e5 40 #include "rt_List.h"
sinrab 0:5464d5e415e5 41 #include "rt_Mailbox.h"
sinrab 0:5464d5e415e5 42 #include "rt_Semaphore.h"
sinrab 0:5464d5e415e5 43 #include "rt_Time.h"
sinrab 0:5464d5e415e5 44 #include "rt_Robin.h"
sinrab 0:5464d5e415e5 45 #include "rt_HAL_CM.h"
sinrab 0:5464d5e415e5 46
sinrab 0:5464d5e415e5 47 /*----------------------------------------------------------------------------
sinrab 0:5464d5e415e5 48 * Global Variables
sinrab 0:5464d5e415e5 49 *---------------------------------------------------------------------------*/
sinrab 0:5464d5e415e5 50
sinrab 0:5464d5e415e5 51 int os_tick_irqn;
sinrab 0:5464d5e415e5 52
sinrab 0:5464d5e415e5 53 /*----------------------------------------------------------------------------
sinrab 0:5464d5e415e5 54 * Local Variables
sinrab 0:5464d5e415e5 55 *---------------------------------------------------------------------------*/
sinrab 0:5464d5e415e5 56
sinrab 0:5464d5e415e5 57 static volatile BIT os_lock;
sinrab 0:5464d5e415e5 58 static volatile BIT os_psh_flag;
sinrab 0:5464d5e415e5 59 static U8 pend_flags;
sinrab 0:5464d5e415e5 60
sinrab 0:5464d5e415e5 61 /*----------------------------------------------------------------------------
sinrab 0:5464d5e415e5 62 * Global Functions
sinrab 0:5464d5e415e5 63 *---------------------------------------------------------------------------*/
sinrab 0:5464d5e415e5 64
sinrab 0:5464d5e415e5 65 #if defined (__CC_ARM)
sinrab 0:5464d5e415e5 66 __asm void $$RTX$$version (void) {
sinrab 0:5464d5e415e5 67 /* Export a version number symbol for a version control. */
sinrab 0:5464d5e415e5 68
sinrab 0:5464d5e415e5 69 EXPORT __RL_RTX_VER
sinrab 0:5464d5e415e5 70
sinrab 0:5464d5e415e5 71 __RL_RTX_VER EQU 0x450
sinrab 0:5464d5e415e5 72 }
sinrab 0:5464d5e415e5 73 #endif
sinrab 0:5464d5e415e5 74
sinrab 0:5464d5e415e5 75
sinrab 0:5464d5e415e5 76 /*--------------------------- rt_suspend ------------------------------------*/
sinrab 0:5464d5e415e5 77 U32 rt_suspend (void) {
sinrab 0:5464d5e415e5 78 /* Suspend OS scheduler */
sinrab 0:5464d5e415e5 79 U32 delta = 0xFFFF;
sinrab 0:5464d5e415e5 80
sinrab 0:5464d5e415e5 81 rt_tsk_lock();
sinrab 0:5464d5e415e5 82
sinrab 0:5464d5e415e5 83 if (os_dly.p_dlnk) {
sinrab 0:5464d5e415e5 84 delta = os_dly.delta_time;
sinrab 0:5464d5e415e5 85 }
sinrab 0:5464d5e415e5 86 #ifndef __CMSIS_RTOS
sinrab 0:5464d5e415e5 87 if (os_tmr.next) {
sinrab 0:5464d5e415e5 88 if (os_tmr.tcnt < delta) delta = os_tmr.tcnt;
sinrab 0:5464d5e415e5 89 }
sinrab 0:5464d5e415e5 90 #endif
sinrab 0:5464d5e415e5 91
sinrab 0:5464d5e415e5 92 return (delta);
sinrab 0:5464d5e415e5 93 }
sinrab 0:5464d5e415e5 94
sinrab 0:5464d5e415e5 95
sinrab 0:5464d5e415e5 96 /*--------------------------- rt_resume -------------------------------------*/
sinrab 0:5464d5e415e5 97 void rt_resume (U32 sleep_time) {
sinrab 0:5464d5e415e5 98 /* Resume OS scheduler after suspend */
sinrab 0:5464d5e415e5 99 P_TCB next;
sinrab 0:5464d5e415e5 100 U32 delta;
sinrab 0:5464d5e415e5 101
sinrab 0:5464d5e415e5 102 os_tsk.run->state = READY;
sinrab 0:5464d5e415e5 103 rt_put_rdy_first (os_tsk.run);
sinrab 0:5464d5e415e5 104
sinrab 0:5464d5e415e5 105 os_robin.task = NULL;
sinrab 0:5464d5e415e5 106
sinrab 0:5464d5e415e5 107 /* Update delays. */
sinrab 0:5464d5e415e5 108 if (os_dly.p_dlnk) {
sinrab 0:5464d5e415e5 109 delta = sleep_time;
sinrab 0:5464d5e415e5 110 if (delta >= os_dly.delta_time) {
sinrab 0:5464d5e415e5 111 delta -= os_dly.delta_time;
sinrab 0:5464d5e415e5 112 os_time += os_dly.delta_time;
sinrab 0:5464d5e415e5 113 os_dly.delta_time = 1;
sinrab 0:5464d5e415e5 114 while (os_dly.p_dlnk) {
sinrab 0:5464d5e415e5 115 rt_dec_dly();
sinrab 0:5464d5e415e5 116 if (delta == 0) break;
sinrab 0:5464d5e415e5 117 delta--;
sinrab 0:5464d5e415e5 118 os_time++;
sinrab 0:5464d5e415e5 119 }
sinrab 0:5464d5e415e5 120 } else {
sinrab 0:5464d5e415e5 121 os_time += delta;
sinrab 0:5464d5e415e5 122 os_dly.delta_time -= delta;
sinrab 0:5464d5e415e5 123 }
sinrab 0:5464d5e415e5 124 } else {
sinrab 0:5464d5e415e5 125 os_time += sleep_time;
sinrab 0:5464d5e415e5 126 }
sinrab 0:5464d5e415e5 127
sinrab 0:5464d5e415e5 128 #ifndef __CMSIS_RTOS
sinrab 0:5464d5e415e5 129 /* Check the user timers. */
sinrab 0:5464d5e415e5 130 if (os_tmr.next) {
sinrab 0:5464d5e415e5 131 delta = sleep_time;
sinrab 0:5464d5e415e5 132 if (delta >= os_tmr.tcnt) {
sinrab 0:5464d5e415e5 133 delta -= os_tmr.tcnt;
sinrab 0:5464d5e415e5 134 os_tmr.tcnt = 1;
sinrab 0:5464d5e415e5 135 while (os_tmr.next) {
sinrab 0:5464d5e415e5 136 rt_tmr_tick();
sinrab 0:5464d5e415e5 137 if (delta == 0) break;
sinrab 0:5464d5e415e5 138 delta--;
sinrab 0:5464d5e415e5 139 }
sinrab 0:5464d5e415e5 140 } else {
sinrab 0:5464d5e415e5 141 os_tmr.tcnt -= delta;
sinrab 0:5464d5e415e5 142 }
sinrab 0:5464d5e415e5 143 }
sinrab 0:5464d5e415e5 144 #endif
sinrab 0:5464d5e415e5 145
sinrab 0:5464d5e415e5 146 /* Switch back to highest ready task */
sinrab 0:5464d5e415e5 147 next = rt_get_first (&os_rdy);
sinrab 0:5464d5e415e5 148 rt_switch_req (next);
sinrab 0:5464d5e415e5 149
sinrab 0:5464d5e415e5 150 rt_tsk_unlock();
sinrab 0:5464d5e415e5 151 }
sinrab 0:5464d5e415e5 152
sinrab 0:5464d5e415e5 153
sinrab 0:5464d5e415e5 154 /*--------------------------- rt_tsk_lock -----------------------------------*/
sinrab 0:5464d5e415e5 155
sinrab 0:5464d5e415e5 156 void rt_tsk_lock (void) {
sinrab 0:5464d5e415e5 157 /* Prevent task switching by locking out scheduler */
sinrab 0:5464d5e415e5 158 if (os_tick_irqn < 0) {
sinrab 0:5464d5e415e5 159 OS_LOCK();
sinrab 0:5464d5e415e5 160 os_lock = __TRUE;
sinrab 0:5464d5e415e5 161 OS_UNPEND (&pend_flags);
sinrab 0:5464d5e415e5 162 } else {
sinrab 0:5464d5e415e5 163 OS_X_LOCK(os_tick_irqn);
sinrab 0:5464d5e415e5 164 os_lock = __TRUE;
sinrab 0:5464d5e415e5 165 OS_X_UNPEND (&pend_flags);
sinrab 0:5464d5e415e5 166 }
sinrab 0:5464d5e415e5 167 }
sinrab 0:5464d5e415e5 168
sinrab 0:5464d5e415e5 169
sinrab 0:5464d5e415e5 170 /*--------------------------- rt_tsk_unlock ---------------------------------*/
sinrab 0:5464d5e415e5 171
sinrab 0:5464d5e415e5 172 void rt_tsk_unlock (void) {
sinrab 0:5464d5e415e5 173 /* Unlock scheduler and re-enable task switching */
sinrab 0:5464d5e415e5 174 if (os_tick_irqn < 0) {
sinrab 0:5464d5e415e5 175 OS_UNLOCK();
sinrab 0:5464d5e415e5 176 os_lock = __FALSE;
sinrab 0:5464d5e415e5 177 OS_PEND (pend_flags, os_psh_flag);
sinrab 0:5464d5e415e5 178 os_psh_flag = __FALSE;
sinrab 0:5464d5e415e5 179 } else {
sinrab 0:5464d5e415e5 180 OS_X_UNLOCK(os_tick_irqn);
sinrab 0:5464d5e415e5 181 os_lock = __FALSE;
sinrab 0:5464d5e415e5 182 OS_X_PEND (pend_flags, os_psh_flag);
sinrab 0:5464d5e415e5 183 os_psh_flag = __FALSE;
sinrab 0:5464d5e415e5 184 }
sinrab 0:5464d5e415e5 185 }
sinrab 0:5464d5e415e5 186
sinrab 0:5464d5e415e5 187
sinrab 0:5464d5e415e5 188 /*--------------------------- rt_psh_req ------------------------------------*/
sinrab 0:5464d5e415e5 189
sinrab 0:5464d5e415e5 190 void rt_psh_req (void) {
sinrab 0:5464d5e415e5 191 /* Initiate a post service handling request if required. */
sinrab 0:5464d5e415e5 192 if (os_lock == __FALSE) {
sinrab 0:5464d5e415e5 193 OS_PEND_IRQ ();
sinrab 0:5464d5e415e5 194 }
sinrab 0:5464d5e415e5 195 else {
sinrab 0:5464d5e415e5 196 os_psh_flag = __TRUE;
sinrab 0:5464d5e415e5 197 }
sinrab 0:5464d5e415e5 198 }
sinrab 0:5464d5e415e5 199
sinrab 0:5464d5e415e5 200
sinrab 0:5464d5e415e5 201 /*--------------------------- rt_pop_req ------------------------------------*/
sinrab 0:5464d5e415e5 202
sinrab 0:5464d5e415e5 203 void rt_pop_req (void) {
sinrab 0:5464d5e415e5 204 /* Process an ISR post service requests. */
sinrab 0:5464d5e415e5 205 struct OS_XCB *p_CB;
sinrab 0:5464d5e415e5 206 P_TCB next;
sinrab 0:5464d5e415e5 207 U32 idx;
sinrab 0:5464d5e415e5 208
sinrab 0:5464d5e415e5 209 os_tsk.run->state = READY;
sinrab 0:5464d5e415e5 210 rt_put_rdy_first (os_tsk.run);
sinrab 0:5464d5e415e5 211
sinrab 0:5464d5e415e5 212 idx = os_psq->last;
sinrab 0:5464d5e415e5 213 while (os_psq->count) {
sinrab 0:5464d5e415e5 214 p_CB = os_psq->q[idx].id;
sinrab 0:5464d5e415e5 215 if (p_CB->cb_type == TCB) {
sinrab 0:5464d5e415e5 216 /* Is of TCB type */
sinrab 0:5464d5e415e5 217 rt_evt_psh ((P_TCB)p_CB, (U16)os_psq->q[idx].arg);
sinrab 0:5464d5e415e5 218 }
sinrab 0:5464d5e415e5 219 else if (p_CB->cb_type == MCB) {
sinrab 0:5464d5e415e5 220 /* Is of MCB type */
sinrab 0:5464d5e415e5 221 rt_mbx_psh ((P_MCB)p_CB, (void *)os_psq->q[idx].arg);
sinrab 0:5464d5e415e5 222 }
sinrab 0:5464d5e415e5 223 else {
sinrab 0:5464d5e415e5 224 /* Must be of SCB type */
sinrab 0:5464d5e415e5 225 rt_sem_psh ((P_SCB)p_CB);
sinrab 0:5464d5e415e5 226 }
sinrab 0:5464d5e415e5 227 if (++idx == os_psq->size) idx = 0;
sinrab 0:5464d5e415e5 228 rt_dec (&os_psq->count);
sinrab 0:5464d5e415e5 229 }
sinrab 0:5464d5e415e5 230 os_psq->last = idx;
sinrab 0:5464d5e415e5 231
sinrab 0:5464d5e415e5 232 next = rt_get_first (&os_rdy);
sinrab 0:5464d5e415e5 233 rt_switch_req (next);
sinrab 0:5464d5e415e5 234 }
sinrab 0:5464d5e415e5 235
sinrab 0:5464d5e415e5 236
sinrab 0:5464d5e415e5 237 /*--------------------------- os_tick_init ----------------------------------*/
sinrab 0:5464d5e415e5 238
sinrab 0:5464d5e415e5 239 __weak int os_tick_init (void) {
sinrab 0:5464d5e415e5 240 /* Initialize SysTick timer as system tick timer. */
sinrab 0:5464d5e415e5 241 rt_systick_init ();
sinrab 0:5464d5e415e5 242 return (-1); /* Return IRQ number of SysTick timer */
sinrab 0:5464d5e415e5 243 }
sinrab 0:5464d5e415e5 244
sinrab 0:5464d5e415e5 245
sinrab 0:5464d5e415e5 246 /*--------------------------- os_tick_irqack --------------------------------*/
sinrab 0:5464d5e415e5 247
sinrab 0:5464d5e415e5 248 __weak void os_tick_irqack (void) {
sinrab 0:5464d5e415e5 249 /* Acknowledge timer interrupt. */
sinrab 0:5464d5e415e5 250 }
sinrab 0:5464d5e415e5 251
sinrab 0:5464d5e415e5 252
sinrab 0:5464d5e415e5 253 /*--------------------------- rt_systick ------------------------------------*/
sinrab 0:5464d5e415e5 254
sinrab 0:5464d5e415e5 255 extern void sysTimerTick(void);
sinrab 0:5464d5e415e5 256
sinrab 0:5464d5e415e5 257 void rt_systick (void) {
sinrab 0:5464d5e415e5 258 /* Check for system clock update, suspend running task. */
sinrab 0:5464d5e415e5 259 P_TCB next;
sinrab 0:5464d5e415e5 260
sinrab 0:5464d5e415e5 261 os_tsk.run->state = READY;
sinrab 0:5464d5e415e5 262 rt_put_rdy_first (os_tsk.run);
sinrab 0:5464d5e415e5 263
sinrab 0:5464d5e415e5 264 /* Check Round Robin timeout. */
sinrab 0:5464d5e415e5 265 rt_chk_robin ();
sinrab 0:5464d5e415e5 266
sinrab 0:5464d5e415e5 267 /* Update delays. */
sinrab 0:5464d5e415e5 268 os_time++;
sinrab 0:5464d5e415e5 269 rt_dec_dly ();
sinrab 0:5464d5e415e5 270
sinrab 0:5464d5e415e5 271 /* Check the user timers. */
sinrab 0:5464d5e415e5 272 #ifdef __CMSIS_RTOS
sinrab 0:5464d5e415e5 273 sysTimerTick();
sinrab 0:5464d5e415e5 274 #else
sinrab 0:5464d5e415e5 275 rt_tmr_tick ();
sinrab 0:5464d5e415e5 276 #endif
sinrab 0:5464d5e415e5 277
sinrab 0:5464d5e415e5 278 /* Switch back to highest ready task */
sinrab 0:5464d5e415e5 279 next = rt_get_first (&os_rdy);
sinrab 0:5464d5e415e5 280 rt_switch_req (next);
sinrab 0:5464d5e415e5 281 }
sinrab 0:5464d5e415e5 282
sinrab 0:5464d5e415e5 283 /*--------------------------- rt_stk_check ----------------------------------*/
sinrab 0:5464d5e415e5 284 __weak void rt_stk_check (void) {
sinrab 0:5464d5e415e5 285 /* Check for stack overflow. */
sinrab 0:5464d5e415e5 286 if (os_tsk.run->task_id == 0x01) {
sinrab 0:5464d5e415e5 287 // TODO: For the main thread the check should be done against the main heap pointer
sinrab 0:5464d5e415e5 288 } else {
sinrab 0:5464d5e415e5 289 if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) ||
sinrab 0:5464d5e415e5 290 (os_tsk.run->stack[0] != MAGIC_WORD)) {
sinrab 0:5464d5e415e5 291 os_error (OS_ERR_STK_OVF);
sinrab 0:5464d5e415e5 292 }
sinrab 0:5464d5e415e5 293 }
sinrab 0:5464d5e415e5 294 }
sinrab 0:5464d5e415e5 295
sinrab 0:5464d5e415e5 296 /*----------------------------------------------------------------------------
sinrab 0:5464d5e415e5 297 * end of file
sinrab 0:5464d5e415e5 298 *---------------------------------------------------------------------------*/
sinrab 0:5464d5e415e5 299
sinrab 0:5464d5e415e5 300