Eric Ebert
/
CoOS
CoOS Demonstrator adapted to mbed Hardware.
task.c@0:57690853989a, 2010-12-03 (annotated)
- Committer:
- ericebert
- Date:
- Fri Dec 03 19:45:30 2010 +0000
- Revision:
- 0:57690853989a
Some basic LED-Flashing works in the CoOS-RTOS using Tasks
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ericebert | 0:57690853989a | 1 | /** |
ericebert | 0:57690853989a | 2 | ******************************************************************************* |
ericebert | 0:57690853989a | 3 | * @file task.c |
ericebert | 0:57690853989a | 4 | * @version V1.1.3 |
ericebert | 0:57690853989a | 5 | * @date 2010.04.26 |
ericebert | 0:57690853989a | 6 | * @brief task management implementation code of CooCox CoOS kernel. |
ericebert | 0:57690853989a | 7 | ******************************************************************************* |
ericebert | 0:57690853989a | 8 | * @copy |
ericebert | 0:57690853989a | 9 | * |
ericebert | 0:57690853989a | 10 | * INTERNAL FILE,DON'T PUBLIC. |
ericebert | 0:57690853989a | 11 | * |
ericebert | 0:57690853989a | 12 | * <h2><center>© COPYRIGHT 2009 CooCox </center></h2> |
ericebert | 0:57690853989a | 13 | ******************************************************************************* |
ericebert | 0:57690853989a | 14 | */ |
ericebert | 0:57690853989a | 15 | |
ericebert | 0:57690853989a | 16 | |
ericebert | 0:57690853989a | 17 | /*---------------------------- Include ---------------------------------------*/ |
ericebert | 0:57690853989a | 18 | #include <coocox.h> |
ericebert | 0:57690853989a | 19 | |
ericebert | 0:57690853989a | 20 | /*---------------------------- Variable Define -------------------------------*/ |
ericebert | 0:57690853989a | 21 | |
ericebert | 0:57690853989a | 22 | /*!< Table use to save TCB pointer. */ |
ericebert | 0:57690853989a | 23 | OSTCB TCBTbl[CFG_MAX_USER_TASKS+SYS_TASK_NUM] = {{0}}; |
ericebert | 0:57690853989a | 24 | |
ericebert | 0:57690853989a | 25 | /*!< The stack of IDLE task. */ |
ericebert | 0:57690853989a | 26 | OS_STK idle_stk[CFG_IDLE_STACK_SIZE] = {0}; |
ericebert | 0:57690853989a | 27 | |
ericebert | 0:57690853989a | 28 | P_OSTCB FreeTCB = 0; /*!< pointer to free TCB */ |
ericebert | 0:57690853989a | 29 | P_OSTCB TCBRdy = 0; /*!< Pointer to the READY list. */ |
ericebert | 0:57690853989a | 30 | P_OSTCB TCBNext = 0; /*!< Poniter to task that next scheduled by OS */ |
ericebert | 0:57690853989a | 31 | P_OSTCB TCBRunning = 0; /*!< Pointer to TCB that current running task. */ |
ericebert | 0:57690853989a | 32 | U64 OSCheckTime = 0; /*!< The counter of system tick. */ |
ericebert | 0:57690853989a | 33 | |
ericebert | 0:57690853989a | 34 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 35 | OS_TID PriNum; |
ericebert | 0:57690853989a | 36 | U8 ActivePri[CFG_MAX_USER_TASKS+SYS_TASK_NUM]; |
ericebert | 0:57690853989a | 37 | U8 TaskNumPerPri[CFG_MAX_USER_TASKS+SYS_TASK_NUM]; |
ericebert | 0:57690853989a | 38 | OS_TID RdyTaskPri[CFG_MAX_USER_TASKS+SYS_TASK_NUM] = {0}; |
ericebert | 0:57690853989a | 39 | U32 RdyTaskPriInfo[(CFG_MAX_USER_TASKS+SYS_TASK_NUM+31)/32]; |
ericebert | 0:57690853989a | 40 | #endif |
ericebert | 0:57690853989a | 41 | |
ericebert | 0:57690853989a | 42 | |
ericebert | 0:57690853989a | 43 | /** |
ericebert | 0:57690853989a | 44 | ******************************************************************************* |
ericebert | 0:57690853989a | 45 | * @brief Create a TCB list. |
ericebert | 0:57690853989a | 46 | * @param[in] None |
ericebert | 0:57690853989a | 47 | * @param[out] None |
ericebert | 0:57690853989a | 48 | * @retval None |
ericebert | 0:57690853989a | 49 | * |
ericebert | 0:57690853989a | 50 | * @par Description |
ericebert | 0:57690853989a | 51 | * @details This function is called by CoOSInit() to initial the empty list |
ericebert | 0:57690853989a | 52 | * of OS_TCBS,supply a pointer to free TCB. |
ericebert | 0:57690853989a | 53 | ******************************************************************************* |
ericebert | 0:57690853989a | 54 | */ |
ericebert | 0:57690853989a | 55 | void CreateTCBList(void) |
ericebert | 0:57690853989a | 56 | { |
ericebert | 0:57690853989a | 57 | U8 i; |
ericebert | 0:57690853989a | 58 | P_OSTCB ptcb1,ptcb2; |
ericebert | 0:57690853989a | 59 | |
ericebert | 0:57690853989a | 60 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 61 | PriNum = 0; |
ericebert | 0:57690853989a | 62 | #endif |
ericebert | 0:57690853989a | 63 | |
ericebert | 0:57690853989a | 64 | ptcb1 = &TCBTbl[0]; /* Build the free TCB list */ |
ericebert | 0:57690853989a | 65 | ptcb2 = &TCBTbl[1]; |
ericebert | 0:57690853989a | 66 | for(i=0;i< (CFG_MAX_USER_TASKS+SYS_TASK_NUM-1);i++ ) |
ericebert | 0:57690853989a | 67 | { |
ericebert | 0:57690853989a | 68 | ptcb1->taskID = i; |
ericebert | 0:57690853989a | 69 | ptcb1->state = TASK_DORMANT; |
ericebert | 0:57690853989a | 70 | ptcb1->TCBnext = ptcb2; |
ericebert | 0:57690853989a | 71 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 72 | RdyTaskPri[i] = INVALID_ID; |
ericebert | 0:57690853989a | 73 | ActivePri[i] = INVALID_ID; |
ericebert | 0:57690853989a | 74 | #endif |
ericebert | 0:57690853989a | 75 | ptcb1++; |
ericebert | 0:57690853989a | 76 | ptcb2++; |
ericebert | 0:57690853989a | 77 | } |
ericebert | 0:57690853989a | 78 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 79 | ActivePri[i] = INVALID_ID; |
ericebert | 0:57690853989a | 80 | #endif |
ericebert | 0:57690853989a | 81 | |
ericebert | 0:57690853989a | 82 | ptcb1->taskID = i; |
ericebert | 0:57690853989a | 83 | ptcb1->TCBnext = 0; |
ericebert | 0:57690853989a | 84 | FreeTCB = &TCBTbl[0]; /* Initialize FreeTCB as head item of list */ |
ericebert | 0:57690853989a | 85 | } |
ericebert | 0:57690853989a | 86 | |
ericebert | 0:57690853989a | 87 | |
ericebert | 0:57690853989a | 88 | |
ericebert | 0:57690853989a | 89 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 90 | |
ericebert | 0:57690853989a | 91 | /** |
ericebert | 0:57690853989a | 92 | ******************************************************************************* |
ericebert | 0:57690853989a | 93 | * @brief Get sequence number for Assign priority |
ericebert | 0:57690853989a | 94 | * @param[in] pri Assign priority |
ericebert | 0:57690853989a | 95 | * @param[out] SequenceNum priority number |
ericebert | 0:57690853989a | 96 | * @retval TRUE Assign priority in priority queue. |
ericebert | 0:57690853989a | 97 | * FALSE Assign priority not in priority queue. |
ericebert | 0:57690853989a | 98 | * |
ericebert | 0:57690853989a | 99 | * @par Description |
ericebert | 0:57690853989a | 100 | * @details This function is called in Binary-Scheduling Algorithm |
ericebert | 0:57690853989a | 101 | * to get sequence number for Assign priority. |
ericebert | 0:57690853989a | 102 | ******************************************************************************* |
ericebert | 0:57690853989a | 103 | */ |
ericebert | 0:57690853989a | 104 | static BOOL GetPriSeqNum(U8 pri,OS_TID* SequenceNum) |
ericebert | 0:57690853989a | 105 | { |
ericebert | 0:57690853989a | 106 | OS_TID seqNum; |
ericebert | 0:57690853989a | 107 | OS_TID num,tmpNum; |
ericebert | 0:57690853989a | 108 | num = 0; |
ericebert | 0:57690853989a | 109 | seqNum = PriNum; |
ericebert | 0:57690853989a | 110 | while(num != seqNum) |
ericebert | 0:57690853989a | 111 | { |
ericebert | 0:57690853989a | 112 | tmpNum = num; |
ericebert | 0:57690853989a | 113 | num = (num+seqNum)/2; |
ericebert | 0:57690853989a | 114 | if(pri == ActivePri[num]) |
ericebert | 0:57690853989a | 115 | { |
ericebert | 0:57690853989a | 116 | *SequenceNum = num; |
ericebert | 0:57690853989a | 117 | return TRUE; |
ericebert | 0:57690853989a | 118 | } |
ericebert | 0:57690853989a | 119 | else if (pri < ActivePri[num]) |
ericebert | 0:57690853989a | 120 | { |
ericebert | 0:57690853989a | 121 | seqNum = num; |
ericebert | 0:57690853989a | 122 | num = tmpNum; |
ericebert | 0:57690853989a | 123 | } |
ericebert | 0:57690853989a | 124 | else |
ericebert | 0:57690853989a | 125 | { |
ericebert | 0:57690853989a | 126 | num++; |
ericebert | 0:57690853989a | 127 | } |
ericebert | 0:57690853989a | 128 | } |
ericebert | 0:57690853989a | 129 | *SequenceNum = num; |
ericebert | 0:57690853989a | 130 | return FALSE; |
ericebert | 0:57690853989a | 131 | } |
ericebert | 0:57690853989a | 132 | |
ericebert | 0:57690853989a | 133 | |
ericebert | 0:57690853989a | 134 | /** |
ericebert | 0:57690853989a | 135 | ******************************************************************************* |
ericebert | 0:57690853989a | 136 | * @brief Get the nearest ready priority sequence number for Assign number |
ericebert | 0:57690853989a | 137 | * @param[in] seqNum Assign sequence number |
ericebert | 0:57690853989a | 138 | * @param[out] None |
ericebert | 0:57690853989a | 139 | * @retval INVALID_ID Cannot find higher ready priority. |
ericebert | 0:57690853989a | 140 | * Others Nearest ready priority sequence number |
ericebert | 0:57690853989a | 141 | * |
ericebert | 0:57690853989a | 142 | * @par Description |
ericebert | 0:57690853989a | 143 | * @details This function is called in Binary-Scheduling Algorithm |
ericebert | 0:57690853989a | 144 | * to get the nearest ready priority sequence number. |
ericebert | 0:57690853989a | 145 | ******************************************************************************* |
ericebert | 0:57690853989a | 146 | */ |
ericebert | 0:57690853989a | 147 | static U8 GetRdyPriSeqNum(U8 seqNum) |
ericebert | 0:57690853989a | 148 | { |
ericebert | 0:57690853989a | 149 | U32 tmp; |
ericebert | 0:57690853989a | 150 | U8 i,j,num; |
ericebert | 0:57690853989a | 151 | S8 cnt; |
ericebert | 0:57690853989a | 152 | i = seqNum/32; |
ericebert | 0:57690853989a | 153 | j = seqNum%32; |
ericebert | 0:57690853989a | 154 | |
ericebert | 0:57690853989a | 155 | do |
ericebert | 0:57690853989a | 156 | { |
ericebert | 0:57690853989a | 157 | tmp = RdyTaskPriInfo[i]; |
ericebert | 0:57690853989a | 158 | if(tmp != 0) |
ericebert | 0:57690853989a | 159 | { |
ericebert | 0:57690853989a | 160 | num = j/8; |
ericebert | 0:57690853989a | 161 | do |
ericebert | 0:57690853989a | 162 | { |
ericebert | 0:57690853989a | 163 | if((tmp&(0xff<<(num*8))) !=0 ) |
ericebert | 0:57690853989a | 164 | { |
ericebert | 0:57690853989a | 165 | if((tmp&(0xf0<<(num*8))) !=0) |
ericebert | 0:57690853989a | 166 | { |
ericebert | 0:57690853989a | 167 | for(cnt=j; cnt >=(num*8+4); cnt--) |
ericebert | 0:57690853989a | 168 | { |
ericebert | 0:57690853989a | 169 | if( (tmp&(1<<cnt)) !=0) |
ericebert | 0:57690853989a | 170 | { |
ericebert | 0:57690853989a | 171 | return (32*i+cnt); |
ericebert | 0:57690853989a | 172 | } |
ericebert | 0:57690853989a | 173 | } |
ericebert | 0:57690853989a | 174 | } |
ericebert | 0:57690853989a | 175 | |
ericebert | 0:57690853989a | 176 | if((j&0x4)==4) |
ericebert | 0:57690853989a | 177 | j = (j|0x3) -4; |
ericebert | 0:57690853989a | 178 | |
ericebert | 0:57690853989a | 179 | for(cnt=j; cnt >=num*8; cnt--) |
ericebert | 0:57690853989a | 180 | { |
ericebert | 0:57690853989a | 181 | if( (tmp&(1<<cnt)) !=0) |
ericebert | 0:57690853989a | 182 | { |
ericebert | 0:57690853989a | 183 | return (32*i+cnt); |
ericebert | 0:57690853989a | 184 | } |
ericebert | 0:57690853989a | 185 | } |
ericebert | 0:57690853989a | 186 | } |
ericebert | 0:57690853989a | 187 | j = num*8 -1; |
ericebert | 0:57690853989a | 188 | }while((num--)!=0); |
ericebert | 0:57690853989a | 189 | } |
ericebert | 0:57690853989a | 190 | j=31; |
ericebert | 0:57690853989a | 191 | }while((i--)!=0); |
ericebert | 0:57690853989a | 192 | return INVALID_ID; |
ericebert | 0:57690853989a | 193 | } |
ericebert | 0:57690853989a | 194 | |
ericebert | 0:57690853989a | 195 | |
ericebert | 0:57690853989a | 196 | /** |
ericebert | 0:57690853989a | 197 | ******************************************************************************* |
ericebert | 0:57690853989a | 198 | * @brief Remap the ready status of priority queue from Assign sequence number |
ericebert | 0:57690853989a | 199 | * @param[in] seqNum Assign sequence number |
ericebert | 0:57690853989a | 200 | * @param[out] None |
ericebert | 0:57690853989a | 201 | * @retval None |
ericebert | 0:57690853989a | 202 | * |
ericebert | 0:57690853989a | 203 | * @par Description |
ericebert | 0:57690853989a | 204 | * @details This function is called in Binary-Scheduling Algorithm |
ericebert | 0:57690853989a | 205 | * to Remap the ready status for priority queue. |
ericebert | 0:57690853989a | 206 | ******************************************************************************* |
ericebert | 0:57690853989a | 207 | */ |
ericebert | 0:57690853989a | 208 | static void PrioRemap(OS_TID seqNum) |
ericebert | 0:57690853989a | 209 | { |
ericebert | 0:57690853989a | 210 | U8 i,j; |
ericebert | 0:57690853989a | 211 | U32 tmp; |
ericebert | 0:57690853989a | 212 | tmp = j = 0; |
ericebert | 0:57690853989a | 213 | j = seqNum/32; |
ericebert | 0:57690853989a | 214 | for(i=0;i<seqNum%32;i++) |
ericebert | 0:57690853989a | 215 | { |
ericebert | 0:57690853989a | 216 | tmp |= 1<<i; |
ericebert | 0:57690853989a | 217 | } |
ericebert | 0:57690853989a | 218 | tmp &= RdyTaskPriInfo[j]; |
ericebert | 0:57690853989a | 219 | |
ericebert | 0:57690853989a | 220 | for(i=seqNum; i<PriNum; i++) |
ericebert | 0:57690853989a | 221 | { |
ericebert | 0:57690853989a | 222 | if((i%32==0)&&(i!=seqNum)) |
ericebert | 0:57690853989a | 223 | { |
ericebert | 0:57690853989a | 224 | RdyTaskPriInfo[j++] = tmp; |
ericebert | 0:57690853989a | 225 | tmp = 0; |
ericebert | 0:57690853989a | 226 | } |
ericebert | 0:57690853989a | 227 | if(RdyTaskPri[i] != INVALID_ID) |
ericebert | 0:57690853989a | 228 | { |
ericebert | 0:57690853989a | 229 | tmp = tmp | (1<<(i%32)); |
ericebert | 0:57690853989a | 230 | } |
ericebert | 0:57690853989a | 231 | } |
ericebert | 0:57690853989a | 232 | RdyTaskPriInfo[j++] = tmp; |
ericebert | 0:57690853989a | 233 | } |
ericebert | 0:57690853989a | 234 | |
ericebert | 0:57690853989a | 235 | |
ericebert | 0:57690853989a | 236 | /** |
ericebert | 0:57690853989a | 237 | ******************************************************************************* |
ericebert | 0:57690853989a | 238 | * @brief Get the ready status for assign sequence number |
ericebert | 0:57690853989a | 239 | * @param[in] seqNum Assign sequence number |
ericebert | 0:57690853989a | 240 | * @param[out] None |
ericebert | 0:57690853989a | 241 | * @retval TRUE This priority has ready task |
ericebert | 0:57690853989a | 242 | * FALSE This priority doesn't have ready task |
ericebert | 0:57690853989a | 243 | * |
ericebert | 0:57690853989a | 244 | * @par Description |
ericebert | 0:57690853989a | 245 | * @details This function is called in Binary-Scheduling Algorithm |
ericebert | 0:57690853989a | 246 | * to get the ready status for assign sequence number. |
ericebert | 0:57690853989a | 247 | ******************************************************************************* |
ericebert | 0:57690853989a | 248 | */ |
ericebert | 0:57690853989a | 249 | static BOOL GetPrioSeqNumStatus(U8 seqNum) |
ericebert | 0:57690853989a | 250 | { |
ericebert | 0:57690853989a | 251 | if( (RdyTaskPriInfo[seqNum/32] & (1<<(seqNum%32))) == 0) |
ericebert | 0:57690853989a | 252 | { |
ericebert | 0:57690853989a | 253 | return FALSE; |
ericebert | 0:57690853989a | 254 | } |
ericebert | 0:57690853989a | 255 | return TRUE; |
ericebert | 0:57690853989a | 256 | } |
ericebert | 0:57690853989a | 257 | |
ericebert | 0:57690853989a | 258 | |
ericebert | 0:57690853989a | 259 | /** |
ericebert | 0:57690853989a | 260 | ******************************************************************************* |
ericebert | 0:57690853989a | 261 | * @brief Set the ready status for assign sequence number |
ericebert | 0:57690853989a | 262 | * @param[in] seqNum Assign sequence number |
ericebert | 0:57690853989a | 263 | * @param[in] isRdy Ready statues for assign sequence number |
ericebert | 0:57690853989a | 264 | * @param[out] None |
ericebert | 0:57690853989a | 265 | * @retval None |
ericebert | 0:57690853989a | 266 | * |
ericebert | 0:57690853989a | 267 | * @par Description |
ericebert | 0:57690853989a | 268 | * @details This function is called in Binary-Scheduling Algorithm |
ericebert | 0:57690853989a | 269 | * to set the ready status for assign sequence number. |
ericebert | 0:57690853989a | 270 | ******************************************************************************* |
ericebert | 0:57690853989a | 271 | */ |
ericebert | 0:57690853989a | 272 | static void SetPrioSeqNumStatus(U8 seqNum, BOOL isRdy) |
ericebert | 0:57690853989a | 273 | { |
ericebert | 0:57690853989a | 274 | U32 tmp; |
ericebert | 0:57690853989a | 275 | tmp = RdyTaskPriInfo[seqNum/32]; |
ericebert | 0:57690853989a | 276 | tmp &= ~(1<<(seqNum%32)); |
ericebert | 0:57690853989a | 277 | tmp |= isRdy<<(seqNum%32); |
ericebert | 0:57690853989a | 278 | RdyTaskPriInfo[seqNum/32] = tmp; |
ericebert | 0:57690853989a | 279 | } |
ericebert | 0:57690853989a | 280 | |
ericebert | 0:57690853989a | 281 | |
ericebert | 0:57690853989a | 282 | /** |
ericebert | 0:57690853989a | 283 | ******************************************************************************* |
ericebert | 0:57690853989a | 284 | * @brief Active priority in queue |
ericebert | 0:57690853989a | 285 | * @param[in] pri Task priority |
ericebert | 0:57690853989a | 286 | * @param[in] None |
ericebert | 0:57690853989a | 287 | * @param[out] None |
ericebert | 0:57690853989a | 288 | * @retval None |
ericebert | 0:57690853989a | 289 | * |
ericebert | 0:57690853989a | 290 | * @par Description |
ericebert | 0:57690853989a | 291 | * @details This function is called in Binary-Scheduling Algorithm |
ericebert | 0:57690853989a | 292 | * to active priority in queue, if this priority had been in activation, |
ericebert | 0:57690853989a | 293 | * increate the task num for this priority. |
ericebert | 0:57690853989a | 294 | ******************************************************************************* |
ericebert | 0:57690853989a | 295 | */ |
ericebert | 0:57690853989a | 296 | void ActiveTaskPri(U8 pri) |
ericebert | 0:57690853989a | 297 | { |
ericebert | 0:57690853989a | 298 | OS_TID seqNum,num; |
ericebert | 0:57690853989a | 299 | if(GetPriSeqNum(pri,&seqNum) == FALSE) |
ericebert | 0:57690853989a | 300 | { |
ericebert | 0:57690853989a | 301 | for(num=PriNum;num>seqNum;num--) |
ericebert | 0:57690853989a | 302 | { |
ericebert | 0:57690853989a | 303 | ActivePri[num] = ActivePri[num-1]; |
ericebert | 0:57690853989a | 304 | TaskNumPerPri[num] = TaskNumPerPri[num-1]; |
ericebert | 0:57690853989a | 305 | RdyTaskPri[num] = RdyTaskPri[num-1]; |
ericebert | 0:57690853989a | 306 | } |
ericebert | 0:57690853989a | 307 | ActivePri[seqNum] = pri; |
ericebert | 0:57690853989a | 308 | TaskNumPerPri[seqNum] = 1; |
ericebert | 0:57690853989a | 309 | RdyTaskPri[seqNum] = INVALID_ID; |
ericebert | 0:57690853989a | 310 | PriNum++; |
ericebert | 0:57690853989a | 311 | PrioRemap(seqNum); |
ericebert | 0:57690853989a | 312 | } |
ericebert | 0:57690853989a | 313 | else |
ericebert | 0:57690853989a | 314 | { |
ericebert | 0:57690853989a | 315 | TaskNumPerPri[seqNum]++; |
ericebert | 0:57690853989a | 316 | } |
ericebert | 0:57690853989a | 317 | } |
ericebert | 0:57690853989a | 318 | |
ericebert | 0:57690853989a | 319 | |
ericebert | 0:57690853989a | 320 | |
ericebert | 0:57690853989a | 321 | /** |
ericebert | 0:57690853989a | 322 | ******************************************************************************* |
ericebert | 0:57690853989a | 323 | * @brief Delete priority in queue |
ericebert | 0:57690853989a | 324 | * @param[in] pri Task priority |
ericebert | 0:57690853989a | 325 | * @param[in] None |
ericebert | 0:57690853989a | 326 | * @param[out] None |
ericebert | 0:57690853989a | 327 | * @retval None |
ericebert | 0:57690853989a | 328 | * |
ericebert | 0:57690853989a | 329 | * @par Description |
ericebert | 0:57690853989a | 330 | * @details This function is called in Binary-Scheduling Algorithm |
ericebert | 0:57690853989a | 331 | * to decrease the task num for this priority, if the num goto 0, |
ericebert | 0:57690853989a | 332 | * remove the priority for queue. |
ericebert | 0:57690853989a | 333 | ******************************************************************************* |
ericebert | 0:57690853989a | 334 | */ |
ericebert | 0:57690853989a | 335 | void DeleteTaskPri(U8 pri) |
ericebert | 0:57690853989a | 336 | { |
ericebert | 0:57690853989a | 337 | OS_TID seqNum,num; |
ericebert | 0:57690853989a | 338 | |
ericebert | 0:57690853989a | 339 | GetPriSeqNum(pri,&seqNum); |
ericebert | 0:57690853989a | 340 | TaskNumPerPri[seqNum]--; |
ericebert | 0:57690853989a | 341 | if(TaskNumPerPri[seqNum]==0) |
ericebert | 0:57690853989a | 342 | { |
ericebert | 0:57690853989a | 343 | for(num=seqNum; num<(PriNum-1); num++) |
ericebert | 0:57690853989a | 344 | { |
ericebert | 0:57690853989a | 345 | ActivePri[num] = ActivePri[num+1]; |
ericebert | 0:57690853989a | 346 | TaskNumPerPri[num] = TaskNumPerPri[num+1]; |
ericebert | 0:57690853989a | 347 | RdyTaskPri[num] = RdyTaskPri[num+1]; |
ericebert | 0:57690853989a | 348 | } |
ericebert | 0:57690853989a | 349 | PriNum--; |
ericebert | 0:57690853989a | 350 | PrioRemap(seqNum); |
ericebert | 0:57690853989a | 351 | } |
ericebert | 0:57690853989a | 352 | } |
ericebert | 0:57690853989a | 353 | |
ericebert | 0:57690853989a | 354 | #endif |
ericebert | 0:57690853989a | 355 | |
ericebert | 0:57690853989a | 356 | |
ericebert | 0:57690853989a | 357 | /** |
ericebert | 0:57690853989a | 358 | ******************************************************************************* |
ericebert | 0:57690853989a | 359 | * @brief Insert a task to the ready list |
ericebert | 0:57690853989a | 360 | * @param[in] tcbInsert A pointer to task will be inserted. |
ericebert | 0:57690853989a | 361 | * @param[out] None |
ericebert | 0:57690853989a | 362 | * @retval None |
ericebert | 0:57690853989a | 363 | * |
ericebert | 0:57690853989a | 364 | * @par Description |
ericebert | 0:57690853989a | 365 | * @details This function is called to insert a task to the READY list. |
ericebert | 0:57690853989a | 366 | ******************************************************************************* |
ericebert | 0:57690853989a | 367 | */ |
ericebert | 0:57690853989a | 368 | void InsertToTCBRdyList(P_OSTCB tcbInsert) |
ericebert | 0:57690853989a | 369 | { |
ericebert | 0:57690853989a | 370 | P_OSTCB ptcbNext,ptcb; |
ericebert | 0:57690853989a | 371 | U8 prio; |
ericebert | 0:57690853989a | 372 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 373 | U8 seqNum; |
ericebert | 0:57690853989a | 374 | U8 RdyTaskSeqNum; |
ericebert | 0:57690853989a | 375 | #endif |
ericebert | 0:57690853989a | 376 | |
ericebert | 0:57690853989a | 377 | prio = tcbInsert->prio; /* Get PRI of inserted task */ |
ericebert | 0:57690853989a | 378 | tcbInsert->state = TASK_READY; /* Set task as TASK_READY */ |
ericebert | 0:57690853989a | 379 | |
ericebert | 0:57690853989a | 380 | #if CFG_ROBIN_EN >0 |
ericebert | 0:57690853989a | 381 | ptcb = TCBRunning; |
ericebert | 0:57690853989a | 382 | /* Set schedule time for the same PRI task as TCBRunning. */ |
ericebert | 0:57690853989a | 383 | if(prio == ptcb->prio) /* Is PRI of inserted task equal to running task? */ |
ericebert | 0:57690853989a | 384 | { |
ericebert | 0:57690853989a | 385 | if(ptcb != tcbInsert) /* Yes,is inserted task equal to running task? */ |
ericebert | 0:57690853989a | 386 | { |
ericebert | 0:57690853989a | 387 | if(ptcb != 0) /* No,TCBRunning == 0? */ |
ericebert | 0:57690853989a | 388 | { /* N0,OSCheckTime < OSTickCnt? */ |
ericebert | 0:57690853989a | 389 | if(OSCheckTime < OSTickCnt) |
ericebert | 0:57690853989a | 390 | { /* Yes,set OSCheckTime for task robin */ |
ericebert | 0:57690853989a | 391 | OSCheckTime = OSTickCnt + ptcb->timeSlice; |
ericebert | 0:57690853989a | 392 | } |
ericebert | 0:57690853989a | 393 | } |
ericebert | 0:57690853989a | 394 | } |
ericebert | 0:57690853989a | 395 | } |
ericebert | 0:57690853989a | 396 | #endif |
ericebert | 0:57690853989a | 397 | |
ericebert | 0:57690853989a | 398 | |
ericebert | 0:57690853989a | 399 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 400 | GetPriSeqNum(prio,&seqNum); |
ericebert | 0:57690853989a | 401 | if(GetPrioSeqNumStatus(seqNum) == TRUE) |
ericebert | 0:57690853989a | 402 | { |
ericebert | 0:57690853989a | 403 | ptcb = &TCBTbl[RdyTaskPri[seqNum]]; |
ericebert | 0:57690853989a | 404 | RdyTaskPri[seqNum] = tcbInsert->taskID; |
ericebert | 0:57690853989a | 405 | } |
ericebert | 0:57690853989a | 406 | else |
ericebert | 0:57690853989a | 407 | { |
ericebert | 0:57690853989a | 408 | RdyTaskPri[seqNum] = tcbInsert->taskID; |
ericebert | 0:57690853989a | 409 | RdyTaskSeqNum = GetRdyPriSeqNum(seqNum); |
ericebert | 0:57690853989a | 410 | SetPrioSeqNumStatus(seqNum, 1); |
ericebert | 0:57690853989a | 411 | if(RdyTaskSeqNum == INVALID_ID) |
ericebert | 0:57690853989a | 412 | { |
ericebert | 0:57690853989a | 413 | ptcb = TCBRdy; |
ericebert | 0:57690853989a | 414 | TaskSchedReq = TRUE; |
ericebert | 0:57690853989a | 415 | if(ptcb == 0) |
ericebert | 0:57690853989a | 416 | { |
ericebert | 0:57690853989a | 417 | TCBRdy = tcbInsert; |
ericebert | 0:57690853989a | 418 | } |
ericebert | 0:57690853989a | 419 | else |
ericebert | 0:57690853989a | 420 | { |
ericebert | 0:57690853989a | 421 | tcbInsert->TCBnext = ptcb; /* Yes,set tcbInsert as head item of list */ |
ericebert | 0:57690853989a | 422 | ptcb->TCBprev = tcbInsert; |
ericebert | 0:57690853989a | 423 | TCBRdy = tcbInsert; |
ericebert | 0:57690853989a | 424 | } |
ericebert | 0:57690853989a | 425 | return; |
ericebert | 0:57690853989a | 426 | } |
ericebert | 0:57690853989a | 427 | else |
ericebert | 0:57690853989a | 428 | { |
ericebert | 0:57690853989a | 429 | ptcb = &TCBTbl[RdyTaskPri[RdyTaskSeqNum]]; |
ericebert | 0:57690853989a | 430 | } |
ericebert | 0:57690853989a | 431 | } |
ericebert | 0:57690853989a | 432 | |
ericebert | 0:57690853989a | 433 | ptcbNext = ptcb->TCBnext; |
ericebert | 0:57690853989a | 434 | tcbInsert->TCBnext = ptcbNext; /* Set link for list */ |
ericebert | 0:57690853989a | 435 | ptcb->TCBnext = tcbInsert; |
ericebert | 0:57690853989a | 436 | tcbInsert->TCBprev = ptcb; |
ericebert | 0:57690853989a | 437 | if(ptcbNext != 0) |
ericebert | 0:57690853989a | 438 | { |
ericebert | 0:57690853989a | 439 | ptcbNext->TCBprev = tcbInsert; |
ericebert | 0:57690853989a | 440 | } |
ericebert | 0:57690853989a | 441 | |
ericebert | 0:57690853989a | 442 | |
ericebert | 0:57690853989a | 443 | #else |
ericebert | 0:57690853989a | 444 | ptcb = TCBRdy; |
ericebert | 0:57690853989a | 445 | if (ptcb == 0) /* Is ready list 0? */ |
ericebert | 0:57690853989a | 446 | { |
ericebert | 0:57690853989a | 447 | TaskSchedReq = TRUE; |
ericebert | 0:57690853989a | 448 | TCBRdy = tcbInsert; /* Yse,set tcbInsert as head item of list */ |
ericebert | 0:57690853989a | 449 | } |
ericebert | 0:57690853989a | 450 | else if (prio < ptcb->prio)/* Is PRI of inserted task higher than TCBRdy? */ |
ericebert | 0:57690853989a | 451 | { |
ericebert | 0:57690853989a | 452 | TaskSchedReq = TRUE; |
ericebert | 0:57690853989a | 453 | tcbInsert->TCBnext = ptcb; /* Yes,set tcbInsert as head item of list */ |
ericebert | 0:57690853989a | 454 | ptcb->TCBprev = tcbInsert; |
ericebert | 0:57690853989a | 455 | TCBRdy = tcbInsert; |
ericebert | 0:57690853989a | 456 | } |
ericebert | 0:57690853989a | 457 | else /* No,find correct place */ |
ericebert | 0:57690853989a | 458 | { |
ericebert | 0:57690853989a | 459 | ptcbNext = ptcb->TCBnext; /* Get next item */ |
ericebert | 0:57690853989a | 460 | while(ptcbNext != 0) /* Is last item in ready list? */ |
ericebert | 0:57690853989a | 461 | { /* No,find correct place */ |
ericebert | 0:57690853989a | 462 | if(prio < ptcbNext->prio) /* Is correct place? */ |
ericebert | 0:57690853989a | 463 | break; /* Yes,break circulation */ |
ericebert | 0:57690853989a | 464 | ptcb = ptcbNext; /* Save current item */ |
ericebert | 0:57690853989a | 465 | ptcbNext = ptcbNext->TCBnext; /* Get next item */ |
ericebert | 0:57690853989a | 466 | } |
ericebert | 0:57690853989a | 467 | tcbInsert->TCBnext = ptcbNext; /* Set link for list */ |
ericebert | 0:57690853989a | 468 | ptcb->TCBnext = tcbInsert; |
ericebert | 0:57690853989a | 469 | tcbInsert->TCBprev = ptcb; |
ericebert | 0:57690853989a | 470 | if(ptcbNext != 0) |
ericebert | 0:57690853989a | 471 | { |
ericebert | 0:57690853989a | 472 | ptcbNext->TCBprev = tcbInsert; |
ericebert | 0:57690853989a | 473 | } |
ericebert | 0:57690853989a | 474 | } |
ericebert | 0:57690853989a | 475 | #endif |
ericebert | 0:57690853989a | 476 | } |
ericebert | 0:57690853989a | 477 | |
ericebert | 0:57690853989a | 478 | |
ericebert | 0:57690853989a | 479 | |
ericebert | 0:57690853989a | 480 | /** |
ericebert | 0:57690853989a | 481 | ******************************************************************************* |
ericebert | 0:57690853989a | 482 | * @brief Remove a task from the READY list |
ericebert | 0:57690853989a | 483 | * @param[in] ptcb A pointer to task which be removed. |
ericebert | 0:57690853989a | 484 | * @param[out] None |
ericebert | 0:57690853989a | 485 | * @retval None |
ericebert | 0:57690853989a | 486 | * |
ericebert | 0:57690853989a | 487 | * @par Description |
ericebert | 0:57690853989a | 488 | * @details This function is called to remove a task from the READY list. |
ericebert | 0:57690853989a | 489 | ******************************************************************************* |
ericebert | 0:57690853989a | 490 | */ |
ericebert | 0:57690853989a | 491 | void RemoveFromTCBRdyList(P_OSTCB ptcb) |
ericebert | 0:57690853989a | 492 | { |
ericebert | 0:57690853989a | 493 | |
ericebert | 0:57690853989a | 494 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 495 | U8 prio; |
ericebert | 0:57690853989a | 496 | U8 seqNum; |
ericebert | 0:57690853989a | 497 | BOOL isChange; |
ericebert | 0:57690853989a | 498 | isChange = FALSE; |
ericebert | 0:57690853989a | 499 | prio = ptcb->prio; |
ericebert | 0:57690853989a | 500 | GetPriSeqNum(prio,&seqNum); |
ericebert | 0:57690853989a | 501 | #endif |
ericebert | 0:57690853989a | 502 | |
ericebert | 0:57690853989a | 503 | /* Is there only one item in READY list? */ |
ericebert | 0:57690853989a | 504 | if((ptcb->TCBnext == 0) && (ptcb->TCBprev == 0) ) |
ericebert | 0:57690853989a | 505 | { |
ericebert | 0:57690853989a | 506 | TCBRdy = 0; /* Yes,set READY list as 0 */ |
ericebert | 0:57690853989a | 507 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 508 | isChange = TRUE; |
ericebert | 0:57690853989a | 509 | #endif |
ericebert | 0:57690853989a | 510 | } |
ericebert | 0:57690853989a | 511 | else if(ptcb->TCBprev == 0) /* Is the first item in READY list? */ |
ericebert | 0:57690853989a | 512 | { |
ericebert | 0:57690853989a | 513 | /* Yes,remove task from the list,and reset the head of READY list */ |
ericebert | 0:57690853989a | 514 | TCBRdy = ptcb->TCBnext; |
ericebert | 0:57690853989a | 515 | ptcb->TCBnext = 0; |
ericebert | 0:57690853989a | 516 | TCBRdy->TCBprev = 0; |
ericebert | 0:57690853989a | 517 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 518 | if(TCBRdy->prio != prio) |
ericebert | 0:57690853989a | 519 | isChange = TRUE; |
ericebert | 0:57690853989a | 520 | |
ericebert | 0:57690853989a | 521 | #endif |
ericebert | 0:57690853989a | 522 | } |
ericebert | 0:57690853989a | 523 | else if( ptcb->TCBnext == 0) /* Is the last item in READY list? */ |
ericebert | 0:57690853989a | 524 | { /* Yes,remove task from list */ |
ericebert | 0:57690853989a | 525 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 526 | if(ptcb->TCBprev->prio != prio) |
ericebert | 0:57690853989a | 527 | isChange = TRUE; |
ericebert | 0:57690853989a | 528 | else |
ericebert | 0:57690853989a | 529 | RdyTaskPri[seqNum] = ptcb->TCBprev->taskID; |
ericebert | 0:57690853989a | 530 | #endif |
ericebert | 0:57690853989a | 531 | ptcb->TCBprev->TCBnext = 0; |
ericebert | 0:57690853989a | 532 | ptcb->TCBprev = 0; |
ericebert | 0:57690853989a | 533 | } |
ericebert | 0:57690853989a | 534 | else /* No, remove task from list */ |
ericebert | 0:57690853989a | 535 | { |
ericebert | 0:57690853989a | 536 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 537 | if((ptcb->TCBprev->prio != prio) && (ptcb->TCBnext->prio != prio)) |
ericebert | 0:57690853989a | 538 | isChange = TRUE; |
ericebert | 0:57690853989a | 539 | else if((ptcb->TCBprev->prio == prio) && (ptcb->TCBnext->prio != prio)) |
ericebert | 0:57690853989a | 540 | RdyTaskPri[seqNum] = ptcb->TCBprev->taskID; |
ericebert | 0:57690853989a | 541 | #endif |
ericebert | 0:57690853989a | 542 | ptcb->TCBprev->TCBnext = ptcb->TCBnext; |
ericebert | 0:57690853989a | 543 | ptcb->TCBnext->TCBprev = ptcb->TCBprev; |
ericebert | 0:57690853989a | 544 | ptcb->TCBnext = 0; |
ericebert | 0:57690853989a | 545 | ptcb->TCBprev = 0; |
ericebert | 0:57690853989a | 546 | } |
ericebert | 0:57690853989a | 547 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 548 | if(isChange == TRUE) |
ericebert | 0:57690853989a | 549 | { |
ericebert | 0:57690853989a | 550 | RdyTaskPri[seqNum] = INVALID_ID; |
ericebert | 0:57690853989a | 551 | SetPrioSeqNumStatus(seqNum, 0); |
ericebert | 0:57690853989a | 552 | } |
ericebert | 0:57690853989a | 553 | #endif |
ericebert | 0:57690853989a | 554 | } |
ericebert | 0:57690853989a | 555 | |
ericebert | 0:57690853989a | 556 | |
ericebert | 0:57690853989a | 557 | #if CFG_MUTEX_EN > 0 |
ericebert | 0:57690853989a | 558 | #define CFG_PRIORITY_SET_EN (1) |
ericebert | 0:57690853989a | 559 | #endif |
ericebert | 0:57690853989a | 560 | #if CFG_PRIORITY_SET_EN >0 |
ericebert | 0:57690853989a | 561 | /** |
ericebert | 0:57690853989a | 562 | ******************************************************************************* |
ericebert | 0:57690853989a | 563 | * @brief Change task priority |
ericebert | 0:57690853989a | 564 | * @param[in] taskID Specify task id. |
ericebert | 0:57690853989a | 565 | * @param[in] priority New priority. |
ericebert | 0:57690853989a | 566 | * @param[out] None |
ericebert | 0:57690853989a | 567 | * @retval E_OK Change priority successful. |
ericebert | 0:57690853989a | 568 | * @retval E_INVALID_ID Invalid id,change priority fail. |
ericebert | 0:57690853989a | 569 | * @retval E_PROTECTED_TASK Can't change idle task priority. |
ericebert | 0:57690853989a | 570 | * |
ericebert | 0:57690853989a | 571 | * @par Description |
ericebert | 0:57690853989a | 572 | * @details This function is called to change priority for a specify task. |
ericebert | 0:57690853989a | 573 | ******************************************************************************* |
ericebert | 0:57690853989a | 574 | */ |
ericebert | 0:57690853989a | 575 | StatusType CoSetPriority(OS_TID taskID,U8 priority) |
ericebert | 0:57690853989a | 576 | { |
ericebert | 0:57690853989a | 577 | P_OSTCB ptcb; |
ericebert | 0:57690853989a | 578 | #if CFG_MUTEX_EN >0 |
ericebert | 0:57690853989a | 579 | U8 prio; |
ericebert | 0:57690853989a | 580 | P_MUTEX pMutex; |
ericebert | 0:57690853989a | 581 | #endif |
ericebert | 0:57690853989a | 582 | #if CFG_EVENT_EN >0 |
ericebert | 0:57690853989a | 583 | P_ECB pecb; |
ericebert | 0:57690853989a | 584 | #endif |
ericebert | 0:57690853989a | 585 | |
ericebert | 0:57690853989a | 586 | if(taskID == 0) /* Is idle task? */ |
ericebert | 0:57690853989a | 587 | { |
ericebert | 0:57690853989a | 588 | return E_PROTECTED_TASK; /* Yes,error return */ |
ericebert | 0:57690853989a | 589 | } |
ericebert | 0:57690853989a | 590 | |
ericebert | 0:57690853989a | 591 | #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ |
ericebert | 0:57690853989a | 592 | if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM) |
ericebert | 0:57690853989a | 593 | { |
ericebert | 0:57690853989a | 594 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 595 | } |
ericebert | 0:57690853989a | 596 | #endif |
ericebert | 0:57690853989a | 597 | ptcb = &TCBTbl[taskID]; /* Get TCB of task ID */ |
ericebert | 0:57690853989a | 598 | #if CFG_PAR_CHECKOUT_EN >0 |
ericebert | 0:57690853989a | 599 | if(ptcb->state == TASK_DORMANT) |
ericebert | 0:57690853989a | 600 | { |
ericebert | 0:57690853989a | 601 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 602 | } |
ericebert | 0:57690853989a | 603 | if(priority > CFG_LOWEST_PRIO) |
ericebert | 0:57690853989a | 604 | { |
ericebert | 0:57690853989a | 605 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 606 | } |
ericebert | 0:57690853989a | 607 | #endif |
ericebert | 0:57690853989a | 608 | |
ericebert | 0:57690853989a | 609 | if(ptcb->prio != priority) /* Is PRI equal to original PRI? */ |
ericebert | 0:57690853989a | 610 | { /* No */ |
ericebert | 0:57690853989a | 611 | #if CFG_MUTEX_EN >0 |
ericebert | 0:57690853989a | 612 | if(ptcb->mutexID != INVALID_ID) |
ericebert | 0:57690853989a | 613 | { |
ericebert | 0:57690853989a | 614 | pMutex = &MutexTbl[ptcb->mutexID]; |
ericebert | 0:57690853989a | 615 | if(pMutex->taskID == ptcb->taskID) /* Task hold mutex? */ |
ericebert | 0:57690853989a | 616 | { |
ericebert | 0:57690853989a | 617 | pMutex->originalPrio= priority;/* Yes,change original PRI in mutex*/ |
ericebert | 0:57690853989a | 618 | if(ptcb->prio < priority) /* Is task priority higher than set?*/ |
ericebert | 0:57690853989a | 619 | { |
ericebert | 0:57690853989a | 620 | return E_OK; /* Yes,do nothing,return OK */ |
ericebert | 0:57690853989a | 621 | } |
ericebert | 0:57690853989a | 622 | } |
ericebert | 0:57690853989a | 623 | } |
ericebert | 0:57690853989a | 624 | |
ericebert | 0:57690853989a | 625 | #endif |
ericebert | 0:57690853989a | 626 | |
ericebert | 0:57690853989a | 627 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 628 | DeleteTaskPri(ptcb->prio); |
ericebert | 0:57690853989a | 629 | ActiveTaskPri(priority); |
ericebert | 0:57690853989a | 630 | #endif |
ericebert | 0:57690853989a | 631 | |
ericebert | 0:57690853989a | 632 | ptcb->prio = priority; /* Change task PRI */ |
ericebert | 0:57690853989a | 633 | if(ptcb->state == TASK_READY) /* Is task in READY list? */ |
ericebert | 0:57690853989a | 634 | { |
ericebert | 0:57690853989a | 635 | OsSchedLock(); /* Yes,reorder task in READY list */ |
ericebert | 0:57690853989a | 636 | RemoveFromTCBRdyList(ptcb); |
ericebert | 0:57690853989a | 637 | InsertToTCBRdyList(ptcb); |
ericebert | 0:57690853989a | 638 | OsSchedUnlock(); |
ericebert | 0:57690853989a | 639 | } |
ericebert | 0:57690853989a | 640 | else if(ptcb->state == TASK_RUNNING)/* Is task running? */ |
ericebert | 0:57690853989a | 641 | { |
ericebert | 0:57690853989a | 642 | if(ptcb->prio > TCBRdy->prio) /* Yes,Is PRI higher than TCBRdy? */ |
ericebert | 0:57690853989a | 643 | { |
ericebert | 0:57690853989a | 644 | OsSchedLock(); /* Yes,reorder task in READY list */ |
ericebert | 0:57690853989a | 645 | TaskSchedReq = TRUE; |
ericebert | 0:57690853989a | 646 | OsSchedUnlock(); |
ericebert | 0:57690853989a | 647 | } |
ericebert | 0:57690853989a | 648 | } |
ericebert | 0:57690853989a | 649 | else |
ericebert | 0:57690853989a | 650 | { /* No,task in WAITING list */ |
ericebert | 0:57690853989a | 651 | #if CFG_MUTEX_EN >0 |
ericebert | 0:57690853989a | 652 | if(ptcb->mutexID != INVALID_ID) /* Is task in mutex WAITING list? */ |
ericebert | 0:57690853989a | 653 | { |
ericebert | 0:57690853989a | 654 | /* Yes,reset the highest PRI in the list */ |
ericebert | 0:57690853989a | 655 | OsSchedLock(); |
ericebert | 0:57690853989a | 656 | pMutex = &MutexTbl[ptcb->mutexID]; |
ericebert | 0:57690853989a | 657 | ptcb = pMutex->waittingList; |
ericebert | 0:57690853989a | 658 | prio = pMutex->originalPrio; |
ericebert | 0:57690853989a | 659 | pMutex->hipriTaskID = pMutex->taskID; |
ericebert | 0:57690853989a | 660 | while(ptcb != 0) |
ericebert | 0:57690853989a | 661 | { |
ericebert | 0:57690853989a | 662 | if(ptcb->prio < prio) |
ericebert | 0:57690853989a | 663 | { |
ericebert | 0:57690853989a | 664 | prio = ptcb->prio; |
ericebert | 0:57690853989a | 665 | pMutex->hipriTaskID = ptcb->taskID; |
ericebert | 0:57690853989a | 666 | } |
ericebert | 0:57690853989a | 667 | ptcb = ptcb->TCBnext; |
ericebert | 0:57690853989a | 668 | } |
ericebert | 0:57690853989a | 669 | OsSchedUnlock(); |
ericebert | 0:57690853989a | 670 | if(pMutex->originalPrio != prio) |
ericebert | 0:57690853989a | 671 | { |
ericebert | 0:57690853989a | 672 | CoSetPriority(pMutex->taskID,prio); |
ericebert | 0:57690853989a | 673 | } |
ericebert | 0:57690853989a | 674 | } |
ericebert | 0:57690853989a | 675 | #endif |
ericebert | 0:57690853989a | 676 | |
ericebert | 0:57690853989a | 677 | #if CFG_EVENT_EN >0 |
ericebert | 0:57690853989a | 678 | ptcb = &TCBTbl[taskID]; |
ericebert | 0:57690853989a | 679 | if(ptcb->eventID != INVALID_ID) /* Is task in event WAITING list? */ |
ericebert | 0:57690853989a | 680 | { |
ericebert | 0:57690853989a | 681 | pecb = &EventTbl[ptcb->eventID]; |
ericebert | 0:57690853989a | 682 | |
ericebert | 0:57690853989a | 683 | /* Yes,is event sort type as preemptive PRI? */ |
ericebert | 0:57690853989a | 684 | if(pecb->eventSortType == EVENT_SORT_TYPE_PRIO) |
ericebert | 0:57690853989a | 685 | { |
ericebert | 0:57690853989a | 686 | /* Yes,reorder task in the list */ |
ericebert | 0:57690853989a | 687 | RemoveEventWaittingList(ptcb); |
ericebert | 0:57690853989a | 688 | EventTaskToWait(pecb,ptcb); |
ericebert | 0:57690853989a | 689 | } |
ericebert | 0:57690853989a | 690 | } |
ericebert | 0:57690853989a | 691 | #endif |
ericebert | 0:57690853989a | 692 | } |
ericebert | 0:57690853989a | 693 | } |
ericebert | 0:57690853989a | 694 | return E_OK; |
ericebert | 0:57690853989a | 695 | } |
ericebert | 0:57690853989a | 696 | #endif |
ericebert | 0:57690853989a | 697 | |
ericebert | 0:57690853989a | 698 | /** |
ericebert | 0:57690853989a | 699 | ******************************************************************************* |
ericebert | 0:57690853989a | 700 | * @brief Schedule function |
ericebert | 0:57690853989a | 701 | * @param[in] None |
ericebert | 0:57690853989a | 702 | * @param[out] None |
ericebert | 0:57690853989a | 703 | * @retval None |
ericebert | 0:57690853989a | 704 | * |
ericebert | 0:57690853989a | 705 | * @par Description |
ericebert | 0:57690853989a | 706 | * @details This function is called by every where need to switch context, |
ericebert | 0:57690853989a | 707 | * It is schedule function of OS kernel. |
ericebert | 0:57690853989a | 708 | ******************************************************************************* |
ericebert | 0:57690853989a | 709 | */ |
ericebert | 0:57690853989a | 710 | void Schedule(void) |
ericebert | 0:57690853989a | 711 | { |
ericebert | 0:57690853989a | 712 | U8 RunPrio,RdyPrio; |
ericebert | 0:57690853989a | 713 | P_OSTCB pRdyTcb,pCurTcb; |
ericebert | 0:57690853989a | 714 | |
ericebert | 0:57690853989a | 715 | |
ericebert | 0:57690853989a | 716 | pCurTcb = TCBRunning; |
ericebert | 0:57690853989a | 717 | pRdyTcb = TCBRdy; |
ericebert | 0:57690853989a | 718 | |
ericebert | 0:57690853989a | 719 | if((pRdyTcb==0) || (pCurTcb != TCBNext) || (OSSchedLock >1) || (OSIntNesting >0)) |
ericebert | 0:57690853989a | 720 | { |
ericebert | 0:57690853989a | 721 | return; |
ericebert | 0:57690853989a | 722 | } |
ericebert | 0:57690853989a | 723 | |
ericebert | 0:57690853989a | 724 | TaskSchedReq = FALSE; |
ericebert | 0:57690853989a | 725 | RunPrio = pCurTcb->prio; |
ericebert | 0:57690853989a | 726 | RdyPrio = pRdyTcb->prio; |
ericebert | 0:57690853989a | 727 | |
ericebert | 0:57690853989a | 728 | /* Is Running task status was changed? */ |
ericebert | 0:57690853989a | 729 | if(pCurTcb->state != TASK_RUNNING) |
ericebert | 0:57690853989a | 730 | { |
ericebert | 0:57690853989a | 731 | TCBNext = pRdyTcb; /* Yes,set TCBNext and reorder READY list */ |
ericebert | 0:57690853989a | 732 | pRdyTcb->state = TASK_RUNNING; |
ericebert | 0:57690853989a | 733 | RemoveFromTCBRdyList(pRdyTcb); |
ericebert | 0:57690853989a | 734 | } |
ericebert | 0:57690853989a | 735 | |
ericebert | 0:57690853989a | 736 | else if(RdyPrio < RunPrio ) /* Is higher PRI task coming in? */ |
ericebert | 0:57690853989a | 737 | { |
ericebert | 0:57690853989a | 738 | TCBNext = pRdyTcb; /* Yes,set TCBNext and reorder READY list */ |
ericebert | 0:57690853989a | 739 | InsertToTCBRdyList(pCurTcb); |
ericebert | 0:57690853989a | 740 | RemoveFromTCBRdyList(pRdyTcb); |
ericebert | 0:57690853989a | 741 | pRdyTcb->state = TASK_RUNNING; |
ericebert | 0:57690853989a | 742 | } |
ericebert | 0:57690853989a | 743 | |
ericebert | 0:57690853989a | 744 | #if CFG_ROBIN_EN >0 /* Is time for robinning */ |
ericebert | 0:57690853989a | 745 | else if((RunPrio == RdyPrio) && (OSCheckTime == OSTickCnt)) |
ericebert | 0:57690853989a | 746 | { |
ericebert | 0:57690853989a | 747 | TCBNext = pRdyTcb; /* Yes,set TCBNext and reorder READY list */ |
ericebert | 0:57690853989a | 748 | InsertToTCBRdyList(pCurTcb); |
ericebert | 0:57690853989a | 749 | RemoveFromTCBRdyList(pRdyTcb); |
ericebert | 0:57690853989a | 750 | pRdyTcb->state = TASK_RUNNING; |
ericebert | 0:57690853989a | 751 | } |
ericebert | 0:57690853989a | 752 | #endif |
ericebert | 0:57690853989a | 753 | else |
ericebert | 0:57690853989a | 754 | { |
ericebert | 0:57690853989a | 755 | return; |
ericebert | 0:57690853989a | 756 | } |
ericebert | 0:57690853989a | 757 | |
ericebert | 0:57690853989a | 758 | #if CFG_ROBIN_EN >0 |
ericebert | 0:57690853989a | 759 | if(TCBNext->prio == TCBRdy->prio) /* Reset OSCheckTime for task robinnig */ |
ericebert | 0:57690853989a | 760 | OSCheckTime = OSTickCnt + TCBNext->timeSlice; |
ericebert | 0:57690853989a | 761 | #endif |
ericebert | 0:57690853989a | 762 | |
ericebert | 0:57690853989a | 763 | |
ericebert | 0:57690853989a | 764 | #if CFG_STK_CHECKOUT_EN > 0 /* Is stack overflow? */ |
ericebert | 0:57690853989a | 765 | if((pCurTcb->stkPtr < pCurTcb->stack)||(*(U32*)(pCurTcb->stack) != MAGIC_WORD)) |
ericebert | 0:57690853989a | 766 | { |
ericebert | 0:57690853989a | 767 | CoStkOverflowHook(pCurTcb->taskID); /* Yes,call handler */ |
ericebert | 0:57690853989a | 768 | } |
ericebert | 0:57690853989a | 769 | #endif |
ericebert | 0:57690853989a | 770 | |
ericebert | 0:57690853989a | 771 | SwitchContext(); /* Call task context switch */ |
ericebert | 0:57690853989a | 772 | } |
ericebert | 0:57690853989a | 773 | |
ericebert | 0:57690853989a | 774 | |
ericebert | 0:57690853989a | 775 | /** |
ericebert | 0:57690853989a | 776 | ******************************************************************************* |
ericebert | 0:57690853989a | 777 | * @brief Assign a TCB to task being created |
ericebert | 0:57690853989a | 778 | * @param[in] None |
ericebert | 0:57690853989a | 779 | * @param[out] None |
ericebert | 0:57690853989a | 780 | * |
ericebert | 0:57690853989a | 781 | * @retval XXXX |
ericebert | 0:57690853989a | 782 | * |
ericebert | 0:57690853989a | 783 | * @par Description |
ericebert | 0:57690853989a | 784 | * @details This function is called to assign a task control block for task |
ericebert | 0:57690853989a | 785 | * being created. |
ericebert | 0:57690853989a | 786 | ******************************************************************************* |
ericebert | 0:57690853989a | 787 | */ |
ericebert | 0:57690853989a | 788 | static P_OSTCB AssignTCB(void) |
ericebert | 0:57690853989a | 789 | { |
ericebert | 0:57690853989a | 790 | P_OSTCB ptcb; |
ericebert | 0:57690853989a | 791 | |
ericebert | 0:57690853989a | 792 | OsSchedLock(); /* Lock schedule */ |
ericebert | 0:57690853989a | 793 | if(FreeTCB == 0) /* Is there no free TCB */ |
ericebert | 0:57690853989a | 794 | { |
ericebert | 0:57690853989a | 795 | OsSchedUnlock(); /* Yes,unlock schedule */ |
ericebert | 0:57690853989a | 796 | return 0; /* Error return */ |
ericebert | 0:57690853989a | 797 | } |
ericebert | 0:57690853989a | 798 | ptcb = FreeTCB; /* Yes,assgin free TCB for this task */ |
ericebert | 0:57690853989a | 799 | /* Set next item as the head of free TCB list */ |
ericebert | 0:57690853989a | 800 | FreeTCB = FreeTCB->TCBnext; |
ericebert | 0:57690853989a | 801 | OsSchedUnlock(); |
ericebert | 0:57690853989a | 802 | return ptcb; |
ericebert | 0:57690853989a | 803 | } |
ericebert | 0:57690853989a | 804 | |
ericebert | 0:57690853989a | 805 | |
ericebert | 0:57690853989a | 806 | /** |
ericebert | 0:57690853989a | 807 | ******************************************************************************* |
ericebert | 0:57690853989a | 808 | * @brief Create a task |
ericebert | 0:57690853989a | 809 | * @param[in] task Task code entry. |
ericebert | 0:57690853989a | 810 | * @param[in] argv The parameter passed to task. |
ericebert | 0:57690853989a | 811 | * @param[in] parameter Task priority + stack size + time slice + isWaitting. |
ericebert | 0:57690853989a | 812 | * @param[in] stk Pointer to stack top of task. |
ericebert | 0:57690853989a | 813 | * @param[out] None |
ericebert | 0:57690853989a | 814 | * @retval E_CREATE_FAIL Fail to create a task . |
ericebert | 0:57690853989a | 815 | * @retval others Valid task id. |
ericebert | 0:57690853989a | 816 | * |
ericebert | 0:57690853989a | 817 | * @par Description |
ericebert | 0:57690853989a | 818 | * @details This function is called by application to create a task,return a id |
ericebert | 0:57690853989a | 819 | * to mark this task. |
ericebert | 0:57690853989a | 820 | ******************************************************************************* |
ericebert | 0:57690853989a | 821 | */ |
ericebert | 0:57690853989a | 822 | OS_TID CreateTask(FUNCPtr task,void *argv,U32 parameter,OS_STK *stk) |
ericebert | 0:57690853989a | 823 | { |
ericebert | 0:57690853989a | 824 | OS_STK* stkTopPtr; |
ericebert | 0:57690853989a | 825 | P_OSTCB ptcb; |
ericebert | 0:57690853989a | 826 | U8 prio; |
ericebert | 0:57690853989a | 827 | #if CFG_ROBIN_EN >0 |
ericebert | 0:57690853989a | 828 | U16 timeSlice; |
ericebert | 0:57690853989a | 829 | #endif |
ericebert | 0:57690853989a | 830 | |
ericebert | 0:57690853989a | 831 | #if CFG_STK_CHECKOUT_EN >0 /* Check validity of parameter */ |
ericebert | 0:57690853989a | 832 | U16 sktSz; |
ericebert | 0:57690853989a | 833 | sktSz = (parameter&0xfff00)>>8; |
ericebert | 0:57690853989a | 834 | #endif |
ericebert | 0:57690853989a | 835 | prio = parameter&0xff; |
ericebert | 0:57690853989a | 836 | |
ericebert | 0:57690853989a | 837 | #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ |
ericebert | 0:57690853989a | 838 | if(task == 0) |
ericebert | 0:57690853989a | 839 | { |
ericebert | 0:57690853989a | 840 | return E_CREATE_FAIL; |
ericebert | 0:57690853989a | 841 | } |
ericebert | 0:57690853989a | 842 | if(stk == 0) |
ericebert | 0:57690853989a | 843 | { |
ericebert | 0:57690853989a | 844 | return E_CREATE_FAIL; |
ericebert | 0:57690853989a | 845 | } |
ericebert | 0:57690853989a | 846 | if(prio > CFG_LOWEST_PRIO) |
ericebert | 0:57690853989a | 847 | { |
ericebert | 0:57690853989a | 848 | return E_CREATE_FAIL; |
ericebert | 0:57690853989a | 849 | } |
ericebert | 0:57690853989a | 850 | #if CFG_STK_CHECKOUT_EN >0 |
ericebert | 0:57690853989a | 851 | if(sktSz < 20) |
ericebert | 0:57690853989a | 852 | { |
ericebert | 0:57690853989a | 853 | return E_CREATE_FAIL; |
ericebert | 0:57690853989a | 854 | } |
ericebert | 0:57690853989a | 855 | #endif // CFG_STK_CHECKOUT_EN |
ericebert | 0:57690853989a | 856 | #endif // CFG_PAR_CHECKOUT_EN |
ericebert | 0:57690853989a | 857 | |
ericebert | 0:57690853989a | 858 | #if CFG_TASK_SCHEDULE_EN == 0 |
ericebert | 0:57690853989a | 859 | if(TCBRunning != 0) |
ericebert | 0:57690853989a | 860 | return E_CREATE_FAIL; |
ericebert | 0:57690853989a | 861 | #endif |
ericebert | 0:57690853989a | 862 | |
ericebert | 0:57690853989a | 863 | stkTopPtr = InitTaskContext(task,argv,stk); /* Initialize task context. */ |
ericebert | 0:57690853989a | 864 | |
ericebert | 0:57690853989a | 865 | ptcb = AssignTCB(); /* Get free TCB to use */ |
ericebert | 0:57690853989a | 866 | |
ericebert | 0:57690853989a | 867 | if(ptcb == 0) /* Is free TCB equal to 0? */ |
ericebert | 0:57690853989a | 868 | { |
ericebert | 0:57690853989a | 869 | return E_CREATE_FAIL; /* Yes,error return */ |
ericebert | 0:57690853989a | 870 | } |
ericebert | 0:57690853989a | 871 | |
ericebert | 0:57690853989a | 872 | ptcb->stkPtr = stkTopPtr; /* Initialize TCB as user set */ |
ericebert | 0:57690853989a | 873 | ptcb->prio = prio; |
ericebert | 0:57690853989a | 874 | #if CFG_STK_CHECKOUT_EN >0 |
ericebert | 0:57690853989a | 875 | ptcb->stack = stk+1 - sktSz; /* Set bottom stack for stack overflow check */ |
ericebert | 0:57690853989a | 876 | *(U32*)(ptcb->stack) = MAGIC_WORD; |
ericebert | 0:57690853989a | 877 | #endif |
ericebert | 0:57690853989a | 878 | |
ericebert | 0:57690853989a | 879 | #if CFG_TASK_WAITTING_EN >0 |
ericebert | 0:57690853989a | 880 | ptcb->delayTick = INVALID_VALUE; |
ericebert | 0:57690853989a | 881 | #endif |
ericebert | 0:57690853989a | 882 | |
ericebert | 0:57690853989a | 883 | #if CFG_TASK_SCHEDULE_EN == 0 |
ericebert | 0:57690853989a | 884 | ptcb->taskFuc = task; |
ericebert | 0:57690853989a | 885 | ptcb->taskStk = stk; |
ericebert | 0:57690853989a | 886 | #endif |
ericebert | 0:57690853989a | 887 | ptcb->TCBnext = 0; /* Initialize TCB link in READY list */ |
ericebert | 0:57690853989a | 888 | ptcb->TCBprev = 0; |
ericebert | 0:57690853989a | 889 | |
ericebert | 0:57690853989a | 890 | #if CFG_ROBIN_EN >0 /* Set task time slice for task robin */ |
ericebert | 0:57690853989a | 891 | timeSlice = (parameter&0x7fff0000)>>20; |
ericebert | 0:57690853989a | 892 | if(timeSlice == 0) |
ericebert | 0:57690853989a | 893 | { |
ericebert | 0:57690853989a | 894 | timeSlice = CFG_TIME_SLICE; |
ericebert | 0:57690853989a | 895 | } |
ericebert | 0:57690853989a | 896 | ptcb->timeSlice = timeSlice; |
ericebert | 0:57690853989a | 897 | #endif |
ericebert | 0:57690853989a | 898 | |
ericebert | 0:57690853989a | 899 | #if CFG_FLAG_EN > 0 |
ericebert | 0:57690853989a | 900 | ptcb->pnode = 0; /* Initialize task as no flag waiting */ |
ericebert | 0:57690853989a | 901 | #endif |
ericebert | 0:57690853989a | 902 | |
ericebert | 0:57690853989a | 903 | #if CFG_EVENT_EN > 0 |
ericebert | 0:57690853989a | 904 | ptcb->eventID = INVALID_ID; /* Initialize task as no event waiting*/ |
ericebert | 0:57690853989a | 905 | ptcb->pmail = 0; |
ericebert | 0:57690853989a | 906 | ptcb->waitNext = 0; |
ericebert | 0:57690853989a | 907 | ptcb->waitPrev = 0; |
ericebert | 0:57690853989a | 908 | #endif |
ericebert | 0:57690853989a | 909 | |
ericebert | 0:57690853989a | 910 | #if CFG_MUTEX_EN > 0 |
ericebert | 0:57690853989a | 911 | /* Initialize task as no mutex holding or waiting */ |
ericebert | 0:57690853989a | 912 | ptcb->mutexID = INVALID_ID; |
ericebert | 0:57690853989a | 913 | #endif |
ericebert | 0:57690853989a | 914 | |
ericebert | 0:57690853989a | 915 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 916 | ActiveTaskPri(prio); |
ericebert | 0:57690853989a | 917 | #endif |
ericebert | 0:57690853989a | 918 | |
ericebert | 0:57690853989a | 919 | if((parameter>>31) == 0) /* Is task in waitting state? */ |
ericebert | 0:57690853989a | 920 | { /* No,set it into ready list */ |
ericebert | 0:57690853989a | 921 | OsSchedLock(); /* Lock schedule */ |
ericebert | 0:57690853989a | 922 | InsertToTCBRdyList(ptcb); /* Insert into the READY list */ |
ericebert | 0:57690853989a | 923 | OsSchedUnlock(); /* Unlock schedule */ |
ericebert | 0:57690853989a | 924 | } |
ericebert | 0:57690853989a | 925 | else |
ericebert | 0:57690853989a | 926 | { /* Yes,Set task status as TASK_WAITING*/ |
ericebert | 0:57690853989a | 927 | ptcb->state = TASK_WAITING; |
ericebert | 0:57690853989a | 928 | } |
ericebert | 0:57690853989a | 929 | return ptcb->taskID; /* Return task ID */ |
ericebert | 0:57690853989a | 930 | } |
ericebert | 0:57690853989a | 931 | |
ericebert | 0:57690853989a | 932 | |
ericebert | 0:57690853989a | 933 | /** |
ericebert | 0:57690853989a | 934 | ******************************************************************************* |
ericebert | 0:57690853989a | 935 | * @brief Delete Task |
ericebert | 0:57690853989a | 936 | * @param[in] taskID Task ID |
ericebert | 0:57690853989a | 937 | * @param[out] None |
ericebert | 0:57690853989a | 938 | * @retval E_INVALID_ID Invalid task ID. |
ericebert | 0:57690853989a | 939 | * @retval E_PROTECTED_TASK Protected task in OS. |
ericebert | 0:57690853989a | 940 | * @retval E_OK Delete successful. |
ericebert | 0:57690853989a | 941 | * |
ericebert | 0:57690853989a | 942 | * @par Description |
ericebert | 0:57690853989a | 943 | * @details This function is called to delete assign task. |
ericebert | 0:57690853989a | 944 | ******************************************************************************* |
ericebert | 0:57690853989a | 945 | */ |
ericebert | 0:57690853989a | 946 | StatusType CoDelTask(OS_TID taskID) |
ericebert | 0:57690853989a | 947 | { |
ericebert | 0:57690853989a | 948 | P_OSTCB ptcb; |
ericebert | 0:57690853989a | 949 | |
ericebert | 0:57690853989a | 950 | #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ |
ericebert | 0:57690853989a | 951 | if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM) |
ericebert | 0:57690853989a | 952 | { |
ericebert | 0:57690853989a | 953 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 954 | } |
ericebert | 0:57690853989a | 955 | #endif |
ericebert | 0:57690853989a | 956 | ptcb = &TCBTbl[taskID]; |
ericebert | 0:57690853989a | 957 | #if CFG_PAR_CHECKOUT_EN >0 |
ericebert | 0:57690853989a | 958 | if(ptcb->state == TASK_DORMANT) |
ericebert | 0:57690853989a | 959 | { |
ericebert | 0:57690853989a | 960 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 961 | } |
ericebert | 0:57690853989a | 962 | #endif |
ericebert | 0:57690853989a | 963 | if(taskID == 0) /* Is idle task? */ |
ericebert | 0:57690853989a | 964 | { |
ericebert | 0:57690853989a | 965 | return E_PROTECTED_TASK; /* Yes,error return */ |
ericebert | 0:57690853989a | 966 | } |
ericebert | 0:57690853989a | 967 | |
ericebert | 0:57690853989a | 968 | if(ptcb->state == TASK_RUNNING) /* Is task running? */ |
ericebert | 0:57690853989a | 969 | { |
ericebert | 0:57690853989a | 970 | if(OSSchedLock != 0) /* Yes,is OS lock? */ |
ericebert | 0:57690853989a | 971 | { |
ericebert | 0:57690853989a | 972 | return E_OS_IN_LOCK; /* Yes,error return */ |
ericebert | 0:57690853989a | 973 | } |
ericebert | 0:57690853989a | 974 | } |
ericebert | 0:57690853989a | 975 | |
ericebert | 0:57690853989a | 976 | #if CFG_MUTEX_EN >0 /* Do task hold mutex? */ |
ericebert | 0:57690853989a | 977 | if(ptcb->mutexID != INVALID_ID) |
ericebert | 0:57690853989a | 978 | { |
ericebert | 0:57690853989a | 979 | if(MutexTbl[ptcb->mutexID].taskID == ptcb->taskID) |
ericebert | 0:57690853989a | 980 | { /* Yes,leave the mutex */ |
ericebert | 0:57690853989a | 981 | CoLeaveMutexSection(ptcb->mutexID); |
ericebert | 0:57690853989a | 982 | } |
ericebert | 0:57690853989a | 983 | } |
ericebert | 0:57690853989a | 984 | |
ericebert | 0:57690853989a | 985 | #endif |
ericebert | 0:57690853989a | 986 | |
ericebert | 0:57690853989a | 987 | OsSchedLock(); /* Lock schedule */ |
ericebert | 0:57690853989a | 988 | |
ericebert | 0:57690853989a | 989 | if(ptcb->state == TASK_READY) /* Is task in READY list? */ |
ericebert | 0:57690853989a | 990 | { |
ericebert | 0:57690853989a | 991 | RemoveFromTCBRdyList(ptcb); /* Yes,remove task from the READY list*/ |
ericebert | 0:57690853989a | 992 | } |
ericebert | 0:57690853989a | 993 | |
ericebert | 0:57690853989a | 994 | #if CFG_TASK_WAITTING_EN > 0 |
ericebert | 0:57690853989a | 995 | else if(ptcb->state == TASK_WAITING)/* Is task in the WAITING list? */ |
ericebert | 0:57690853989a | 996 | { |
ericebert | 0:57690853989a | 997 | /* Yes,Is task in delay list? */ |
ericebert | 0:57690853989a | 998 | if(ptcb->delayTick != INVALID_VALUE) |
ericebert | 0:57690853989a | 999 | { |
ericebert | 0:57690853989a | 1000 | RemoveDelayList(ptcb); /* Yes,remove task from READY list */ |
ericebert | 0:57690853989a | 1001 | } |
ericebert | 0:57690853989a | 1002 | |
ericebert | 0:57690853989a | 1003 | #if CFG_EVENT_EN > 0 |
ericebert | 0:57690853989a | 1004 | if(ptcb->eventID != INVALID_ID) /* Is task in event waiting list? */ |
ericebert | 0:57690853989a | 1005 | { |
ericebert | 0:57690853989a | 1006 | /* Yes,remove task from event waiting list */ |
ericebert | 0:57690853989a | 1007 | RemoveEventWaittingList(ptcb); |
ericebert | 0:57690853989a | 1008 | } |
ericebert | 0:57690853989a | 1009 | #endif |
ericebert | 0:57690853989a | 1010 | |
ericebert | 0:57690853989a | 1011 | #if CFG_FLAG_EN > 0 |
ericebert | 0:57690853989a | 1012 | if(ptcb->pnode != 0) /* Is task in flag waiting list? */ |
ericebert | 0:57690853989a | 1013 | { |
ericebert | 0:57690853989a | 1014 | /* Yes,remove task from flag waiting list */ |
ericebert | 0:57690853989a | 1015 | RemoveLinkNode((P_FLAG_NODE)ptcb->pnode); |
ericebert | 0:57690853989a | 1016 | } |
ericebert | 0:57690853989a | 1017 | #endif |
ericebert | 0:57690853989a | 1018 | |
ericebert | 0:57690853989a | 1019 | #if CFG_MUTEX_EN >0 |
ericebert | 0:57690853989a | 1020 | if(ptcb->mutexID != INVALID_ID) /* Is task in mutex waiting list? */ |
ericebert | 0:57690853989a | 1021 | { |
ericebert | 0:57690853989a | 1022 | RemoveMutexList(ptcb); /* Yes,remove task from mutex waiting list*/ |
ericebert | 0:57690853989a | 1023 | } |
ericebert | 0:57690853989a | 1024 | #endif |
ericebert | 0:57690853989a | 1025 | } |
ericebert | 0:57690853989a | 1026 | #endif |
ericebert | 0:57690853989a | 1027 | ptcb->state = TASK_DORMANT; /* Release TCB */ |
ericebert | 0:57690853989a | 1028 | TaskSchedReq = TRUE; |
ericebert | 0:57690853989a | 1029 | |
ericebert | 0:57690853989a | 1030 | #if CFG_ORDER_LIST_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 1031 | DeleteTaskPri(ptcb->prio); |
ericebert | 0:57690853989a | 1032 | #endif |
ericebert | 0:57690853989a | 1033 | |
ericebert | 0:57690853989a | 1034 | #if CFG_TASK_SCHEDULE_EN >0 |
ericebert | 0:57690853989a | 1035 | ptcb->TCBnext = FreeTCB; |
ericebert | 0:57690853989a | 1036 | FreeTCB = ptcb; |
ericebert | 0:57690853989a | 1037 | #endif |
ericebert | 0:57690853989a | 1038 | OsSchedUnlock(); /* Unlock schedule */ |
ericebert | 0:57690853989a | 1039 | return E_OK; /* return OK */ |
ericebert | 0:57690853989a | 1040 | } |
ericebert | 0:57690853989a | 1041 | |
ericebert | 0:57690853989a | 1042 | |
ericebert | 0:57690853989a | 1043 | /** |
ericebert | 0:57690853989a | 1044 | ******************************************************************************* |
ericebert | 0:57690853989a | 1045 | * @brief Exit Task |
ericebert | 0:57690853989a | 1046 | * @param[in] None |
ericebert | 0:57690853989a | 1047 | * @param[out] None |
ericebert | 0:57690853989a | 1048 | * @retval None |
ericebert | 0:57690853989a | 1049 | * |
ericebert | 0:57690853989a | 1050 | * @par Description |
ericebert | 0:57690853989a | 1051 | * @details This function is called to exit current task. |
ericebert | 0:57690853989a | 1052 | ******************************************************************************* |
ericebert | 0:57690853989a | 1053 | */ |
ericebert | 0:57690853989a | 1054 | void CoExitTask(void) |
ericebert | 0:57690853989a | 1055 | { |
ericebert | 0:57690853989a | 1056 | CoDelTask(TCBRunning->taskID); /* Call task delete function */ |
ericebert | 0:57690853989a | 1057 | } |
ericebert | 0:57690853989a | 1058 | |
ericebert | 0:57690853989a | 1059 | |
ericebert | 0:57690853989a | 1060 | #if CFG_TASK_SCHEDULE_EN ==0 |
ericebert | 0:57690853989a | 1061 | /** |
ericebert | 0:57690853989a | 1062 | ******************************************************************************* |
ericebert | 0:57690853989a | 1063 | * @brief Activate Task |
ericebert | 0:57690853989a | 1064 | * @param[in] taskID Task ID |
ericebert | 0:57690853989a | 1065 | * @param[in] argv Task argv |
ericebert | 0:57690853989a | 1066 | * @param[out] None |
ericebert | 0:57690853989a | 1067 | * @retval E_INVALID_ID Invalid task ID. |
ericebert | 0:57690853989a | 1068 | * @retval E_OK Activate task successful. |
ericebert | 0:57690853989a | 1069 | * |
ericebert | 0:57690853989a | 1070 | * @par Description |
ericebert | 0:57690853989a | 1071 | * @details This function is called to activate current task. |
ericebert | 0:57690853989a | 1072 | ******************************************************************************* |
ericebert | 0:57690853989a | 1073 | */ |
ericebert | 0:57690853989a | 1074 | StatusType CoActivateTask(OS_TID taskID,void *argv) |
ericebert | 0:57690853989a | 1075 | { |
ericebert | 0:57690853989a | 1076 | P_OSTCB ptcb; |
ericebert | 0:57690853989a | 1077 | OS_STK* stkTopPtr; |
ericebert | 0:57690853989a | 1078 | #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ |
ericebert | 0:57690853989a | 1079 | if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM) |
ericebert | 0:57690853989a | 1080 | { |
ericebert | 0:57690853989a | 1081 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 1082 | } |
ericebert | 0:57690853989a | 1083 | #endif |
ericebert | 0:57690853989a | 1084 | ptcb = &TCBTbl[taskID]; |
ericebert | 0:57690853989a | 1085 | #if CFG_PAR_CHECKOUT_EN >0 |
ericebert | 0:57690853989a | 1086 | if(ptcb->stkPtr == 0) |
ericebert | 0:57690853989a | 1087 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 1088 | #endif |
ericebert | 0:57690853989a | 1089 | if(ptcb->state != TASK_DORMANT) |
ericebert | 0:57690853989a | 1090 | return E_OK; |
ericebert | 0:57690853989a | 1091 | |
ericebert | 0:57690853989a | 1092 | |
ericebert | 0:57690853989a | 1093 | /* Initialize task context. */ |
ericebert | 0:57690853989a | 1094 | stkTopPtr = InitTaskContext(ptcb->taskFuc,argv,ptcb->taskStk); |
ericebert | 0:57690853989a | 1095 | |
ericebert | 0:57690853989a | 1096 | ptcb->stkPtr = stkTopPtr; /* Initialize TCB as user set */ |
ericebert | 0:57690853989a | 1097 | OsSchedLock(); /* Lock schedule */ |
ericebert | 0:57690853989a | 1098 | InsertToTCBRdyList(ptcb); /* Insert into the READY list */ |
ericebert | 0:57690853989a | 1099 | OsSchedUnlock(); /* Unlock schedule */ |
ericebert | 0:57690853989a | 1100 | return E_OK; |
ericebert | 0:57690853989a | 1101 | } |
ericebert | 0:57690853989a | 1102 | #endif |
ericebert | 0:57690853989a | 1103 | |
ericebert | 0:57690853989a | 1104 | |
ericebert | 0:57690853989a | 1105 | /** |
ericebert | 0:57690853989a | 1106 | ******************************************************************************* |
ericebert | 0:57690853989a | 1107 | * @brief Get current task id |
ericebert | 0:57690853989a | 1108 | * @param[in] None |
ericebert | 0:57690853989a | 1109 | * @param[out] None |
ericebert | 0:57690853989a | 1110 | * @retval ID of the current task. |
ericebert | 0:57690853989a | 1111 | * |
ericebert | 0:57690853989a | 1112 | * @par Description |
ericebert | 0:57690853989a | 1113 | * @details This function is called to get current task id. |
ericebert | 0:57690853989a | 1114 | ******************************************************************************* |
ericebert | 0:57690853989a | 1115 | */ |
ericebert | 0:57690853989a | 1116 | OS_TID CoGetCurTaskID(void) |
ericebert | 0:57690853989a | 1117 | { |
ericebert | 0:57690853989a | 1118 | return (TCBRunning->taskID); /* Return running task ID */ |
ericebert | 0:57690853989a | 1119 | } |
ericebert | 0:57690853989a | 1120 | |
ericebert | 0:57690853989a | 1121 | #if CFG_TASK_SUSPEND_EN >0 |
ericebert | 0:57690853989a | 1122 | /** |
ericebert | 0:57690853989a | 1123 | ******************************************************************************* |
ericebert | 0:57690853989a | 1124 | * @brief Suspend Task |
ericebert | 0:57690853989a | 1125 | * @param[in] taskID ID of task that want to suspend. |
ericebert | 0:57690853989a | 1126 | * @param[out] None |
ericebert | 0:57690853989a | 1127 | * @retval E_OK Task suspend successful. |
ericebert | 0:57690853989a | 1128 | * @retval E_INVALID_ID Invalid event ID. |
ericebert | 0:57690853989a | 1129 | * @retval E_PROTECTED_TASK Can't suspend idle task. |
ericebert | 0:57690853989a | 1130 | * @retval E_ALREADY_IN_WAITING Task now in waiting state. |
ericebert | 0:57690853989a | 1131 | |
ericebert | 0:57690853989a | 1132 | * |
ericebert | 0:57690853989a | 1133 | * @par Description |
ericebert | 0:57690853989a | 1134 | * @details This function is called to exit current task. |
ericebert | 0:57690853989a | 1135 | ******************************************************************************* |
ericebert | 0:57690853989a | 1136 | */ |
ericebert | 0:57690853989a | 1137 | StatusType CoSuspendTask(OS_TID taskID) |
ericebert | 0:57690853989a | 1138 | { |
ericebert | 0:57690853989a | 1139 | P_OSTCB ptcb; |
ericebert | 0:57690853989a | 1140 | |
ericebert | 0:57690853989a | 1141 | if(taskID == 0) /* Is idle task? */ |
ericebert | 0:57690853989a | 1142 | { |
ericebert | 0:57690853989a | 1143 | return E_PROTECTED_TASK; /* Yes,error return */ |
ericebert | 0:57690853989a | 1144 | } |
ericebert | 0:57690853989a | 1145 | #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ |
ericebert | 0:57690853989a | 1146 | if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM) |
ericebert | 0:57690853989a | 1147 | { |
ericebert | 0:57690853989a | 1148 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 1149 | } |
ericebert | 0:57690853989a | 1150 | #endif |
ericebert | 0:57690853989a | 1151 | ptcb = &TCBTbl[taskID]; |
ericebert | 0:57690853989a | 1152 | #if CFG_PAR_CHECKOUT_EN >0 |
ericebert | 0:57690853989a | 1153 | if(ptcb->state == TASK_DORMANT) |
ericebert | 0:57690853989a | 1154 | { |
ericebert | 0:57690853989a | 1155 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 1156 | } |
ericebert | 0:57690853989a | 1157 | #endif |
ericebert | 0:57690853989a | 1158 | if(OSSchedLock != 0) |
ericebert | 0:57690853989a | 1159 | { |
ericebert | 0:57690853989a | 1160 | return E_OS_IN_LOCK; |
ericebert | 0:57690853989a | 1161 | } |
ericebert | 0:57690853989a | 1162 | if(ptcb->state == TASK_WAITING) /* Is task in WAITING list? */ |
ericebert | 0:57690853989a | 1163 | { |
ericebert | 0:57690853989a | 1164 | return E_ALREADY_IN_WAITING; /* Yes,error return */ |
ericebert | 0:57690853989a | 1165 | } |
ericebert | 0:57690853989a | 1166 | |
ericebert | 0:57690853989a | 1167 | OsSchedLock(); |
ericebert | 0:57690853989a | 1168 | if(ptcb != TCBRunning) /* Is runing task? */ |
ericebert | 0:57690853989a | 1169 | { |
ericebert | 0:57690853989a | 1170 | RemoveFromTCBRdyList(ptcb); /* No,Remove task from READY list */ |
ericebert | 0:57690853989a | 1171 | } |
ericebert | 0:57690853989a | 1172 | else |
ericebert | 0:57690853989a | 1173 | { |
ericebert | 0:57690853989a | 1174 | TaskSchedReq = TRUE; |
ericebert | 0:57690853989a | 1175 | } |
ericebert | 0:57690853989a | 1176 | |
ericebert | 0:57690853989a | 1177 | ptcb->state = TASK_WAITING; /* Set task status as TASK_WAITING */ |
ericebert | 0:57690853989a | 1178 | OsSchedUnlock(); /* Call task schedule */ |
ericebert | 0:57690853989a | 1179 | return E_OK; /* Return OK */ |
ericebert | 0:57690853989a | 1180 | } |
ericebert | 0:57690853989a | 1181 | |
ericebert | 0:57690853989a | 1182 | |
ericebert | 0:57690853989a | 1183 | /** |
ericebert | 0:57690853989a | 1184 | ******************************************************************************* |
ericebert | 0:57690853989a | 1185 | * @brief Awake Task |
ericebert | 0:57690853989a | 1186 | * @param[in] taskID ID of task that will been awaked. |
ericebert | 0:57690853989a | 1187 | * @param[out] None |
ericebert | 0:57690853989a | 1188 | * @retval E_OK Task awake successful. |
ericebert | 0:57690853989a | 1189 | * @retval E_INVALID_ID Invalid task ID. |
ericebert | 0:57690853989a | 1190 | * @retval E_TASK_NOT_WAITING Task now not in waiting state. |
ericebert | 0:57690853989a | 1191 | * @retval E_TASK_WAIT_OTHER Task now waiting other awake event. |
ericebert | 0:57690853989a | 1192 | * @retval E_PROTECTED_TASK Idle task mustn't be awaked. |
ericebert | 0:57690853989a | 1193 | * |
ericebert | 0:57690853989a | 1194 | * @par Description |
ericebert | 0:57690853989a | 1195 | * @details This function is called to awake current task. |
ericebert | 0:57690853989a | 1196 | ******************************************************************************* |
ericebert | 0:57690853989a | 1197 | */ |
ericebert | 0:57690853989a | 1198 | StatusType CoAwakeTask(OS_TID taskID) |
ericebert | 0:57690853989a | 1199 | { |
ericebert | 0:57690853989a | 1200 | P_OSTCB ptcb; |
ericebert | 0:57690853989a | 1201 | |
ericebert | 0:57690853989a | 1202 | if(taskID == 0) /* Is idle task? */ |
ericebert | 0:57690853989a | 1203 | { |
ericebert | 0:57690853989a | 1204 | return E_PROTECTED_TASK; /* Yes,error return */ |
ericebert | 0:57690853989a | 1205 | } |
ericebert | 0:57690853989a | 1206 | #if CFG_PAR_CHECKOUT_EN >0 /* Check validity of parameter */ |
ericebert | 0:57690853989a | 1207 | if(taskID >= CFG_MAX_USER_TASKS + SYS_TASK_NUM) |
ericebert | 0:57690853989a | 1208 | { |
ericebert | 0:57690853989a | 1209 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 1210 | } |
ericebert | 0:57690853989a | 1211 | #endif |
ericebert | 0:57690853989a | 1212 | ptcb = &TCBTbl[taskID]; |
ericebert | 0:57690853989a | 1213 | #if CFG_PAR_CHECKOUT_EN >0 |
ericebert | 0:57690853989a | 1214 | if(ptcb->state == TASK_DORMANT) |
ericebert | 0:57690853989a | 1215 | { |
ericebert | 0:57690853989a | 1216 | return E_INVALID_ID; |
ericebert | 0:57690853989a | 1217 | } |
ericebert | 0:57690853989a | 1218 | #endif |
ericebert | 0:57690853989a | 1219 | |
ericebert | 0:57690853989a | 1220 | if(ptcb->state != TASK_WAITING) /* Is task in WAITING list */ |
ericebert | 0:57690853989a | 1221 | { |
ericebert | 0:57690853989a | 1222 | return E_TASK_NOT_WAITING; /* No,error return */ |
ericebert | 0:57690853989a | 1223 | } |
ericebert | 0:57690853989a | 1224 | |
ericebert | 0:57690853989a | 1225 | #if CFG_TASK_WAITTING_EN > 0 |
ericebert | 0:57690853989a | 1226 | if(ptcb->delayTick != INVALID_VALUE)/* Is task in READY list */ |
ericebert | 0:57690853989a | 1227 | { |
ericebert | 0:57690853989a | 1228 | return E_TASK_WAIT_OTHER; /* Yes,error return */ |
ericebert | 0:57690853989a | 1229 | } |
ericebert | 0:57690853989a | 1230 | |
ericebert | 0:57690853989a | 1231 | #if CFG_FLAG_EN > 0 |
ericebert | 0:57690853989a | 1232 | if(ptcb->pnode != 0) /* Is task in flag waiting list */ |
ericebert | 0:57690853989a | 1233 | { |
ericebert | 0:57690853989a | 1234 | return E_TASK_WAIT_OTHER; /* Yes,error return */ |
ericebert | 0:57690853989a | 1235 | } |
ericebert | 0:57690853989a | 1236 | #endif |
ericebert | 0:57690853989a | 1237 | |
ericebert | 0:57690853989a | 1238 | #if CFG_EVENT_EN>0 |
ericebert | 0:57690853989a | 1239 | if(ptcb->eventID != INVALID_ID) /* Is task in event waiting list */ |
ericebert | 0:57690853989a | 1240 | { |
ericebert | 0:57690853989a | 1241 | return E_TASK_WAIT_OTHER; /* Yes,error return */ |
ericebert | 0:57690853989a | 1242 | } |
ericebert | 0:57690853989a | 1243 | #endif |
ericebert | 0:57690853989a | 1244 | |
ericebert | 0:57690853989a | 1245 | #if CFG_MUTEX_EN > 0 |
ericebert | 0:57690853989a | 1246 | if(ptcb->mutexID != INVALID_ID) /* Is task in mutex waiting list */ |
ericebert | 0:57690853989a | 1247 | { |
ericebert | 0:57690853989a | 1248 | return E_TASK_WAIT_OTHER; /* Yes,error return */ |
ericebert | 0:57690853989a | 1249 | } |
ericebert | 0:57690853989a | 1250 | #endif |
ericebert | 0:57690853989a | 1251 | |
ericebert | 0:57690853989a | 1252 | #endif //CFG_TASK_WAITTING_EN |
ericebert | 0:57690853989a | 1253 | |
ericebert | 0:57690853989a | 1254 | /* All no,so WAITING state was set by CoSuspendTask() */ |
ericebert | 0:57690853989a | 1255 | OsSchedLock(); /* Lock schedule */ |
ericebert | 0:57690853989a | 1256 | InsertToTCBRdyList(ptcb); /* Insert the task into the READY list*/ |
ericebert | 0:57690853989a | 1257 | OsSchedUnlock(); /* Unlock schedule */ |
ericebert | 0:57690853989a | 1258 | return E_OK; /* return OK */ |
ericebert | 0:57690853989a | 1259 | } |
ericebert | 0:57690853989a | 1260 | #endif |