Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.

Dependents:   LoRaWAN-lmic-app LoRaWAN-lmic-app LoRaWAN-test-10secs testes ... more

Committer:
mbed_official
Date:
Thu Nov 06 11:00:33 2014 +0000
Revision:
48:e9a2c7cb57a4
Synchronized with git revision 8724eb616b6e07a3bd111d3022652eb5bbefe9b7

Full URL: https://github.com/mbedmicro/mbed/commit/8724eb616b6e07a3bd111d3022652eb5bbefe9b7/

[RZ/A1H] mbed-RZ first release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 48:e9a2c7cb57a4 1 /*----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 2 * RL-ARM - RTX
mbed_official 48:e9a2c7cb57a4 3 *----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 4 * Name: RT_MUTEX.C
mbed_official 48:e9a2c7cb57a4 5 * Purpose: Implements mutex synchronization objects
mbed_official 48:e9a2c7cb57a4 6 * Rev.: V4.60
mbed_official 48:e9a2c7cb57a4 7 *----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 8 *
mbed_official 48:e9a2c7cb57a4 9 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
mbed_official 48:e9a2c7cb57a4 10 * All rights reserved.
mbed_official 48:e9a2c7cb57a4 11 * Redistribution and use in source and binary forms, with or without
mbed_official 48:e9a2c7cb57a4 12 * modification, are permitted provided that the following conditions are met:
mbed_official 48:e9a2c7cb57a4 13 * - Redistributions of source code must retain the above copyright
mbed_official 48:e9a2c7cb57a4 14 * notice, this list of conditions and the following disclaimer.
mbed_official 48:e9a2c7cb57a4 15 * - Redistributions in binary form must reproduce the above copyright
mbed_official 48:e9a2c7cb57a4 16 * notice, this list of conditions and the following disclaimer in the
mbed_official 48:e9a2c7cb57a4 17 * documentation and/or other materials provided with the distribution.
mbed_official 48:e9a2c7cb57a4 18 * - Neither the name of ARM nor the names of its contributors may be used
mbed_official 48:e9a2c7cb57a4 19 * to endorse or promote products derived from this software without
mbed_official 48:e9a2c7cb57a4 20 * specific prior written permission.
mbed_official 48:e9a2c7cb57a4 21 *
mbed_official 48:e9a2c7cb57a4 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mbed_official 48:e9a2c7cb57a4 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mbed_official 48:e9a2c7cb57a4 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
mbed_official 48:e9a2c7cb57a4 25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
mbed_official 48:e9a2c7cb57a4 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
mbed_official 48:e9a2c7cb57a4 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
mbed_official 48:e9a2c7cb57a4 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbed_official 48:e9a2c7cb57a4 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbed_official 48:e9a2c7cb57a4 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
mbed_official 48:e9a2c7cb57a4 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 48:e9a2c7cb57a4 32 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 48:e9a2c7cb57a4 33 *---------------------------------------------------------------------------*/
mbed_official 48:e9a2c7cb57a4 34
mbed_official 48:e9a2c7cb57a4 35 #include "rt_TypeDef.h"
mbed_official 48:e9a2c7cb57a4 36 #include "RTX_Config.h"
mbed_official 48:e9a2c7cb57a4 37 #include "rt_List.h"
mbed_official 48:e9a2c7cb57a4 38 #include "rt_Task.h"
mbed_official 48:e9a2c7cb57a4 39 #include "rt_Mutex.h"
mbed_official 48:e9a2c7cb57a4 40 #ifdef __CORTEX_A9
mbed_official 48:e9a2c7cb57a4 41 #include "rt_HAL_CA.h"
mbed_official 48:e9a2c7cb57a4 42 #else
mbed_official 48:e9a2c7cb57a4 43 #include "rt_HAL_CM.h"
mbed_official 48:e9a2c7cb57a4 44 #endif
mbed_official 48:e9a2c7cb57a4 45
mbed_official 48:e9a2c7cb57a4 46
mbed_official 48:e9a2c7cb57a4 47 /*----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 48 * Functions
mbed_official 48:e9a2c7cb57a4 49 *---------------------------------------------------------------------------*/
mbed_official 48:e9a2c7cb57a4 50
mbed_official 48:e9a2c7cb57a4 51
mbed_official 48:e9a2c7cb57a4 52 /*--------------------------- rt_mut_init -----------------------------------*/
mbed_official 48:e9a2c7cb57a4 53
mbed_official 48:e9a2c7cb57a4 54 void rt_mut_init (OS_ID mutex) {
mbed_official 48:e9a2c7cb57a4 55 /* Initialize a mutex object */
mbed_official 48:e9a2c7cb57a4 56 P_MUCB p_MCB = mutex;
mbed_official 48:e9a2c7cb57a4 57
mbed_official 48:e9a2c7cb57a4 58 p_MCB->cb_type = MUCB;
mbed_official 48:e9a2c7cb57a4 59 p_MCB->prio = 0;
mbed_official 48:e9a2c7cb57a4 60 p_MCB->level = 0;
mbed_official 48:e9a2c7cb57a4 61 p_MCB->p_lnk = NULL;
mbed_official 48:e9a2c7cb57a4 62 p_MCB->owner = NULL;
mbed_official 48:e9a2c7cb57a4 63 }
mbed_official 48:e9a2c7cb57a4 64
mbed_official 48:e9a2c7cb57a4 65
mbed_official 48:e9a2c7cb57a4 66 /*--------------------------- rt_mut_delete ---------------------------------*/
mbed_official 48:e9a2c7cb57a4 67
mbed_official 48:e9a2c7cb57a4 68 #ifdef __CMSIS_RTOS
mbed_official 48:e9a2c7cb57a4 69 OS_RESULT rt_mut_delete (OS_ID mutex) {
mbed_official 48:e9a2c7cb57a4 70 /* Delete a mutex object */
mbed_official 48:e9a2c7cb57a4 71 P_MUCB p_MCB = mutex;
mbed_official 48:e9a2c7cb57a4 72 P_TCB p_TCB;
mbed_official 48:e9a2c7cb57a4 73
mbed_official 48:e9a2c7cb57a4 74 __DMB();
mbed_official 48:e9a2c7cb57a4 75 /* Restore owner task's priority. */
mbed_official 48:e9a2c7cb57a4 76 if (p_MCB->level != 0) {
mbed_official 48:e9a2c7cb57a4 77 p_MCB->owner->prio = p_MCB->prio;
mbed_official 48:e9a2c7cb57a4 78 if (p_MCB->owner != os_tsk.run) {
mbed_official 48:e9a2c7cb57a4 79 rt_resort_prio (p_MCB->owner);
mbed_official 48:e9a2c7cb57a4 80 }
mbed_official 48:e9a2c7cb57a4 81 }
mbed_official 48:e9a2c7cb57a4 82
mbed_official 48:e9a2c7cb57a4 83 while (p_MCB->p_lnk != NULL) {
mbed_official 48:e9a2c7cb57a4 84 /* A task is waiting for mutex. */
mbed_official 48:e9a2c7cb57a4 85 p_TCB = rt_get_first ((P_XCB)p_MCB);
mbed_official 48:e9a2c7cb57a4 86 rt_ret_val(p_TCB, 0/*osOK*/);
mbed_official 48:e9a2c7cb57a4 87 rt_rmv_dly(p_TCB);
mbed_official 48:e9a2c7cb57a4 88 p_TCB->state = READY;
mbed_official 48:e9a2c7cb57a4 89 rt_put_prio (&os_rdy, p_TCB);
mbed_official 48:e9a2c7cb57a4 90 }
mbed_official 48:e9a2c7cb57a4 91
mbed_official 48:e9a2c7cb57a4 92 if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) {
mbed_official 48:e9a2c7cb57a4 93 /* preempt running task */
mbed_official 48:e9a2c7cb57a4 94 rt_put_prio (&os_rdy, os_tsk.run);
mbed_official 48:e9a2c7cb57a4 95 os_tsk.run->state = READY;
mbed_official 48:e9a2c7cb57a4 96 rt_dispatch (NULL);
mbed_official 48:e9a2c7cb57a4 97 }
mbed_official 48:e9a2c7cb57a4 98
mbed_official 48:e9a2c7cb57a4 99 p_MCB->cb_type = 0;
mbed_official 48:e9a2c7cb57a4 100
mbed_official 48:e9a2c7cb57a4 101 return (OS_R_OK);
mbed_official 48:e9a2c7cb57a4 102 }
mbed_official 48:e9a2c7cb57a4 103 #endif
mbed_official 48:e9a2c7cb57a4 104
mbed_official 48:e9a2c7cb57a4 105
mbed_official 48:e9a2c7cb57a4 106 /*--------------------------- rt_mut_release --------------------------------*/
mbed_official 48:e9a2c7cb57a4 107
mbed_official 48:e9a2c7cb57a4 108 OS_RESULT rt_mut_release (OS_ID mutex) {
mbed_official 48:e9a2c7cb57a4 109 /* Release a mutex object */
mbed_official 48:e9a2c7cb57a4 110 P_MUCB p_MCB = mutex;
mbed_official 48:e9a2c7cb57a4 111 P_TCB p_TCB;
mbed_official 48:e9a2c7cb57a4 112
mbed_official 48:e9a2c7cb57a4 113 if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) {
mbed_official 48:e9a2c7cb57a4 114 /* Unbalanced mutex release or task is not the owner */
mbed_official 48:e9a2c7cb57a4 115 return (OS_R_NOK);
mbed_official 48:e9a2c7cb57a4 116 }
mbed_official 48:e9a2c7cb57a4 117 __DMB();
mbed_official 48:e9a2c7cb57a4 118 if (--p_MCB->level != 0) {
mbed_official 48:e9a2c7cb57a4 119 return (OS_R_OK);
mbed_official 48:e9a2c7cb57a4 120 }
mbed_official 48:e9a2c7cb57a4 121 /* Restore owner task's priority. */
mbed_official 48:e9a2c7cb57a4 122 os_tsk.run->prio = p_MCB->prio;
mbed_official 48:e9a2c7cb57a4 123 if (p_MCB->p_lnk != NULL) {
mbed_official 48:e9a2c7cb57a4 124 /* A task is waiting for mutex. */
mbed_official 48:e9a2c7cb57a4 125 p_TCB = rt_get_first ((P_XCB)p_MCB);
mbed_official 48:e9a2c7cb57a4 126 #ifdef __CMSIS_RTOS
mbed_official 48:e9a2c7cb57a4 127 rt_ret_val(p_TCB, 0/*osOK*/);
mbed_official 48:e9a2c7cb57a4 128 #else
mbed_official 48:e9a2c7cb57a4 129 rt_ret_val(p_TCB, OS_R_MUT);
mbed_official 48:e9a2c7cb57a4 130 #endif
mbed_official 48:e9a2c7cb57a4 131 rt_rmv_dly (p_TCB);
mbed_official 48:e9a2c7cb57a4 132 /* A waiting task becomes the owner of this mutex. */
mbed_official 48:e9a2c7cb57a4 133 p_MCB->level = 1;
mbed_official 48:e9a2c7cb57a4 134 p_MCB->owner = p_TCB;
mbed_official 48:e9a2c7cb57a4 135 p_MCB->prio = p_TCB->prio;
mbed_official 48:e9a2c7cb57a4 136 /* Priority inversion, check which task continues. */
mbed_official 48:e9a2c7cb57a4 137 if (os_tsk.run->prio >= rt_rdy_prio()) {
mbed_official 48:e9a2c7cb57a4 138 rt_dispatch (p_TCB);
mbed_official 48:e9a2c7cb57a4 139 }
mbed_official 48:e9a2c7cb57a4 140 else {
mbed_official 48:e9a2c7cb57a4 141 /* Ready task has higher priority than running task. */
mbed_official 48:e9a2c7cb57a4 142 rt_put_prio (&os_rdy, os_tsk.run);
mbed_official 48:e9a2c7cb57a4 143 rt_put_prio (&os_rdy, p_TCB);
mbed_official 48:e9a2c7cb57a4 144 os_tsk.run->state = READY;
mbed_official 48:e9a2c7cb57a4 145 p_TCB->state = READY;
mbed_official 48:e9a2c7cb57a4 146 rt_dispatch (NULL);
mbed_official 48:e9a2c7cb57a4 147 }
mbed_official 48:e9a2c7cb57a4 148 }
mbed_official 48:e9a2c7cb57a4 149 else {
mbed_official 48:e9a2c7cb57a4 150 /* Check if own priority raised by priority inversion. */
mbed_official 48:e9a2c7cb57a4 151 if (rt_rdy_prio() > os_tsk.run->prio) {
mbed_official 48:e9a2c7cb57a4 152 rt_put_prio (&os_rdy, os_tsk.run);
mbed_official 48:e9a2c7cb57a4 153 os_tsk.run->state = READY;
mbed_official 48:e9a2c7cb57a4 154 rt_dispatch (NULL);
mbed_official 48:e9a2c7cb57a4 155 }
mbed_official 48:e9a2c7cb57a4 156 }
mbed_official 48:e9a2c7cb57a4 157 return (OS_R_OK);
mbed_official 48:e9a2c7cb57a4 158 }
mbed_official 48:e9a2c7cb57a4 159
mbed_official 48:e9a2c7cb57a4 160
mbed_official 48:e9a2c7cb57a4 161 /*--------------------------- rt_mut_wait -----------------------------------*/
mbed_official 48:e9a2c7cb57a4 162
mbed_official 48:e9a2c7cb57a4 163 OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) {
mbed_official 48:e9a2c7cb57a4 164 /* Wait for a mutex, continue when mutex is free. */
mbed_official 48:e9a2c7cb57a4 165 P_MUCB p_MCB = mutex;
mbed_official 48:e9a2c7cb57a4 166
mbed_official 48:e9a2c7cb57a4 167 if (p_MCB->level == 0) {
mbed_official 48:e9a2c7cb57a4 168 p_MCB->owner = os_tsk.run;
mbed_official 48:e9a2c7cb57a4 169 p_MCB->prio = os_tsk.run->prio;
mbed_official 48:e9a2c7cb57a4 170 goto inc;
mbed_official 48:e9a2c7cb57a4 171 }
mbed_official 48:e9a2c7cb57a4 172 if (p_MCB->owner == os_tsk.run) {
mbed_official 48:e9a2c7cb57a4 173 /* OK, running task is the owner of this mutex. */
mbed_official 48:e9a2c7cb57a4 174 inc:p_MCB->level++;
mbed_official 48:e9a2c7cb57a4 175 __DMB();
mbed_official 48:e9a2c7cb57a4 176 return (OS_R_OK);
mbed_official 48:e9a2c7cb57a4 177 }
mbed_official 48:e9a2c7cb57a4 178 /* Mutex owned by another task, wait until released. */
mbed_official 48:e9a2c7cb57a4 179 if (timeout == 0) {
mbed_official 48:e9a2c7cb57a4 180 return (OS_R_TMO);
mbed_official 48:e9a2c7cb57a4 181 }
mbed_official 48:e9a2c7cb57a4 182 /* Raise the owner task priority if lower than current priority. */
mbed_official 48:e9a2c7cb57a4 183 /* This priority inversion is called priority inheritance. */
mbed_official 48:e9a2c7cb57a4 184 if (p_MCB->prio < os_tsk.run->prio) {
mbed_official 48:e9a2c7cb57a4 185 p_MCB->owner->prio = os_tsk.run->prio;
mbed_official 48:e9a2c7cb57a4 186 rt_resort_prio (p_MCB->owner);
mbed_official 48:e9a2c7cb57a4 187 }
mbed_official 48:e9a2c7cb57a4 188 if (p_MCB->p_lnk != NULL) {
mbed_official 48:e9a2c7cb57a4 189 rt_put_prio ((P_XCB)p_MCB, os_tsk.run);
mbed_official 48:e9a2c7cb57a4 190 }
mbed_official 48:e9a2c7cb57a4 191 else {
mbed_official 48:e9a2c7cb57a4 192 p_MCB->p_lnk = os_tsk.run;
mbed_official 48:e9a2c7cb57a4 193 os_tsk.run->p_lnk = NULL;
mbed_official 48:e9a2c7cb57a4 194 os_tsk.run->p_rlnk = (P_TCB)p_MCB;
mbed_official 48:e9a2c7cb57a4 195 }
mbed_official 48:e9a2c7cb57a4 196 rt_block(timeout, WAIT_MUT);
mbed_official 48:e9a2c7cb57a4 197 return (OS_R_TMO);
mbed_official 48:e9a2c7cb57a4 198 }
mbed_official 48:e9a2c7cb57a4 199
mbed_official 48:e9a2c7cb57a4 200
mbed_official 48:e9a2c7cb57a4 201 /*----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 202 * end of file
mbed_official 48:e9a2c7cb57a4 203 *---------------------------------------------------------------------------*/
mbed_official 48:e9a2c7cb57a4 204