CoOS Demonstrator adapted to mbed Hardware.

Dependencies:   mbed

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?

UserRevisionLine numberNew 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>&copy; 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