예제 #1
0
파일: OsQueue.c 프로젝트: uLipe/uLipeRtosV4
/*
 * QueueDeleteLoop()
 *
 * Internal function, used to assert all tasks waiting for any event related
 * to queue when a kernel object is about to be destroyed
 *
 */
inline static void QueueDeleteLoop(OsHandler_t h)
{
	QueuePtr_t q = (QueuePtr_t)h;
	uint32_t i = 0, j = 0;

		
	//remove out all tasks of all wait lists:
	while((q->queueSlotWait.prioGrp != 0)&&(q->queueInsertWait.prioGrp != 0))
	{
		//Remove for priority order:
		i = uLipeKernelFindHighPrio(&q->queueSlotWait);
		j = uLipeKernelFindHighPrio(&q->queueInsertWait);
		
		uLipePrioClr(i, &q->queueSlotWait);
		uLipePrioClr(j, &q->queueInsertWait);


		//Set these tasks as ready:
        //make this task ready:
        tcbPtrTbl[i]->taskStatus &= ~(1 << kTaskPendQueue);
        if(tcbPtrTbl[i]->taskStatus == 0)
        {
            uLipePrioSet(i, &taskPrioList);
        }

        //make this task ready:
        tcbPtrTbl[j]->taskStatus &= ~(1 << kTaskPendQueue);
        if(tcbPtrTbl[j]->taskStatus == 0)
        {
            uLipePrioSet(j, &taskPrioList);
        }
		
	}		
}
예제 #2
0
/*
 * QueueDeleteLoop()
 *
 * Internal function, used to assert all tasks waiting for any event related
 * to queue when a kernel object is about to be destroyed
 *
 */
inline static void QueueDeleteLoop(OsHandler_t h)
{
	QueuePtr_t q = (QueuePtr_t)h;
	uint32_t i = 0, j = 0;

#if OS_USE_DEPRECATED == 1	
	for(i = 0; i < OS_NUMBER_OF_TASKS; i++)
	{
		//check for tasks waiting for slot free:
		if(q->tasksPending[i] != OS_Q_PEND_NOT)
		{
			//make this task ready:
			tcbPtrTbl[i]->taskStatus = (1 << kTaskReady);
			uLipePrioSet(i, &taskPrioList);
		}

		//remove this task from wait list:
		q->tasksPending[i] = OS_Q_PEND_NOT;

	}
#else
		
	//remove out all tasks of all wait lists:
	while((q->queueSlotWait.prioGrp != 0)&&(q->queueInsertWait.prioGrp != 0))
	{
		//Remove for priority order:
		i = uLipeFindHighPrio(&q->queueSlotWait);
		j = uLipeFindHighPrio(&q->queueInsertWait);
		
		uLipePrioClr(i, &q->queueSlotWait);
		uLipePrioClr(j, &q->queueInsertWait);


		//Set these tasks as ready:
		tcbPtrTbl[i]->taskStatus = (1 << kTaskReady);
		uLipePrioSet(i, &taskPrioList);		
		tcbPtrTbl[j]->taskStatus = (1 << kTaskReady);
		uLipePrioSet(j, &taskPrioList);		
		
	}		
#endif
}
예제 #3
0
/*
 * QueueRemoveLoop()
 *
 * Internal function, used to process all tasks that waiting to at least
 * one slot became free, when a slot had its data removed
 *
 */
inline static void QueueRemoveLoop(OsHandler_t h)
{
	QueuePtr_t q = (QueuePtr_t)h;	
	uint32_t i = 0;

#if OS_USE_DEPRECATED == 1	
	for(i = 0; i < OS_NUMBER_OF_TASKS; i++)
	{
		//check for tasks waiting for slot free:
		if(q->tasksPending[i] == OS_Q_PEND_FULL)
		{
			//make this task ready:
			tcbPtrTbl[i]->taskStatus = (1 << kTaskReady);
			uLipePrioSet(i, &taskPrioList);

			//remove this task from wait list:
			q->tasksPending[i] = OS_Q_PEND_NOT;
		}
	}
#else

	//extract the highest priority task which waits for a slot:
	i = (uint16_t)uLipeFindHighPrio(&q->queueSlotWait);

	//valid prio?
	if(i != 0)
	{
		//Remove task from wait list:
		uLipePrioClr(i, &q->queueSlotWait);


		//make this task ready:
		tcbPtrTbl[i]->taskStatus = (1 << kTaskReady);
		uLipePrioSet(i, &taskPrioList);
	}	
	
	
#endif	
	
}
예제 #4
0
파일: OsFlags.c 프로젝트: uLipe/uLipeRtosV4
inline static void FlagsDeleteLoop(OsHandler_t h)
{
	FlagsGrpPtr_t f = (FlagsGrpPtr_t)h;
	uint16_t i = 0;

	i = uLipeKernelFindHighPrio(&f->waitTasks[f->activeList]);
	while( i != 0)
	{
        //make this task ready:
        tcbPtrTbl[i]->taskStatus &= ~((1 << kTaskPendFlagAll) | (1 << kTaskPendFlagAny) | (1 << kTaskPenFlagConsume));
        if(tcbPtrTbl[i]->taskStatus == 0) uLipePrioSet(i, &taskPrioList);
        i = uLipeKernelFindHighPrio(&f->waitTasks[f->activeList]);
        uLipePrioClr(i, &f->waitTasks[f->activeList]);

	}
}
예제 #5
0
파일: OsQueue.c 프로젝트: uLipe/uLipeRtosV4
/*
 * QueueInsertLoop()
 *
 * Internal function, used to proccess all tasks that waiting to at least
 * one slot became filled, when a slot had is space filled of data
 */
inline static void QueueInsertLoop(OsHandler_t h)
{
	QueuePtr_t q = (QueuePtr_t)h;
	uint32_t i = 0;

	//extract the highest priority task which waits for a slot:
	i = (uint16_t)uLipeKernelFindHighPrio(&q->queueInsertWait);

	//valid prio?
	if(i != 0)
	{
		//Remove task from wait list:
		uLipePrioClr(i, &q->queueInsertWait);


        //make this task ready:
        tcbPtrTbl[i]->taskStatus &= ~((1 << kTaskPendQueue)|(1 << kTaskPendDelay));
        if(tcbPtrTbl[i]->taskStatus == 0)
        {
            uLipePrioSet(i, &taskPrioList);
        }
	}	
}
예제 #6
0
파일: OsQueue.c 프로젝트: uLipe/uLipeRtosV4
/*
 * uLipeQueueRemove()
 */
void *uLipeQueueRemove(OsHandler_t h, uint8_t opt, uint16_t timeout, OsStatus_t *err)
{
    QueuePtr_t q = (QueuePtr_t)h;
	uint32_t sReg = 0;
	void *ptr = NULL;

	//check arguments:
	if(q == 0)
	{
        if(err != NULL )*err = kInvalidParam ;
		return(NULL);
	}

	//Arguments valid, then proceed:
	OS_CRITICAL_IN();

	//Check queue status first:
	if(q->usedSlots == 0)
	{
		OS_CRITICAL_OUT();

		//Queue full, check options:
		switch(opt)
		{
			case OS_Q_BLOCK_EMPTY:
			{
				//task will block so:
				OS_CRITICAL_IN();

                uLipePrioClr(currentTask->taskPrio, &taskPrioList);
				//prepare task to wait
                currentTask->taskStatus |= (1 << kTaskPendQueue);
                if(timeout != 0)
                {
                    currentTask->taskStatus |= (1 << kTaskPendDelay);
                    currentTask->delayTime = timeout;
                    uLipePrioSet(currentTask->taskPrio, &timerPendingList.list[timerPendingList.activeList]);
                }

				//Adds task to wait list:
                currentTask->queueBmp = &q->queueInsertWait;
				uLipePrioSet(currentTask->taskPrio, &q->queueInsertWait);
				OS_CRITICAL_OUT();

				//So check for a context switch:
				uLipeKernelTaskYield();

                if(err != NULL )*err = kQueueEmpty;

				return(ptr);
			}
			break;
            case OS_Q_NON_BLOCK:
            {
                if(q->usedSlots != 0) break;
                else
                {
                    OS_CRITICAL_OUT();

                    if(err != NULL )*err = kQueueEmpty;
                    return(ptr);
                }

            }
            break;
			default:
			{
				//All other cases, only return:
                if(err != NULL )*err = kQueueEmpty;
				return(ptr);
			}
			break;
		}

	}

	//queue holds data, so remove it:
	ptr = (void *) q->queueBase[q->queueBack];
	q->queueBack++;

	//queue bevahes as circular FIFO fashion
	if(q->queueBack > (q->numSlots - 1))
	{
		q->queueBack = 0;
	}
	//Update the number of used slots:
	q->usedSlots--;

	//Update tasks wich pend this queue:
	QueueRemoveLoop(h);

	OS_CRITICAL_OUT();

	//Check for context switching:
	uLipeKernelTaskYield();

	if(err != NULL )*err = kStatusOk;

	//All gone well:
	return(ptr);
}
예제 #7
0
파일: OsQueue.c 프로젝트: uLipe/uLipeRtosV4
/*
 * uLipeQueueInsert()
 */
OsStatus_t uLipeQueueInsert(OsHandler_t h, void *data, uint8_t opt, uint16_t timeout)
{
    QueuePtr_t q = (QueuePtr_t)h;
	uint32_t sReg = 0;

	//check arguments:
	if(data == NULL)
	{
		return(kInvalidParam);
	}
	if(q == 0)
	{
		return(kInvalidParam);
	}


	//Arguments valid, proceed then:
	OS_CRITICAL_IN();

	//Before insert, check queue status:
	if(q->usedSlots >= q->numSlots)
	{
		OS_CRITICAL_OUT();

		//Queue full, check options:
		switch(opt)
		{
			case OS_Q_BLOCK_FULL:
			{
				//suspend current task:
				uLipePrioClr(currentTask->taskPrio, &taskPrioList);
				currentTask->taskStatus |= (1 << kTaskPendQueue);
				if(timeout != 0)
				{
				    currentTask->taskStatus |= (1 << kTaskPendDelay);
	                currentTask->delayTime = timeout;
	                uLipePrioSet(currentTask->taskPrio, &timerPendingList.list[timerPendingList.activeList]);
				}
				currentTask->queueBmp = &q->queueSlotWait;

				//Adds task to wait list:
				uLipePrioSet(currentTask->taskPrio, &q->queueSlotWait);

				OS_CRITICAL_OUT();

				//So check for a context switch:
				uLipeKernelTaskYield();

				return(kQueueFull);
			}
			break;

			case OS_Q_NON_BLOCK:
			{
			    if(q->usedSlots < q->numSlots) break;
			    else
			    {
	                OS_CRITICAL_OUT();
	                return(kQueueFull);
			    }

			}
			break;

			default:
			{

				OS_CRITICAL_OUT();
				return(kQueueFull);
			}
			break;
		}
	}


	//freespace, Insert the data pointer on queue:

	q->queueBase[q->queueFront] = (void *)data;
	q->queueFront++;

	//queue behaves as a circular FIFO fashion:
	if(q->queueFront > (q->numSlots - 1))
	{
		q->queueFront = 0;
	}

	//update number of used slots
	q->usedSlots++;

	//Run insertion update loop:
	QueueInsertLoop(h);

	OS_CRITICAL_OUT();

	//check for a context switch:
	uLipeKernelTaskYield();

	//All gone ok:
	return(kStatusOk);
}
예제 #8
0
/*
 * uLipeQueueRemove()
 */
void *uLipeQueueRemove(OsHandler_t h, uint8_t opt, uint16_t timeout, OsStatus_t *err)
{
	uint32_t sReg = 0;
	QueuePtr_t q = (QueuePtr_t)h;
	void *ptr = NULL;

	//check arguments:
	if(h == NULL)
	{
		return(kInvalidParam);
	}

	//Arguments valid, then proceed:
	OS_CRITICAL_IN();

	//Check queue status first:
	if(q->usedSlots == 0)
	{
		OS_CRITICAL_OUT();

		//Queue full, check options:
		switch(opt)
		{
			case OS_Q_BLOCK_EMPTY:
			{
				//task will block so:
				OS_CRITICAL_IN();

				//suspend current task:
				uLipePrioClr(currentTask->taskPrio, &taskPrioList);
				currentTask->taskStatus = (1 << kTaskPendQueue) | (1 << kTaskPendDelay);
				currentTask->delayTime = timeout;

#if OS_USE_DEPRECATED == 1				
				//Assert this task on queue wait list:
				q->tasksPending[currentTask->taskPrio] = OS_Q_PEND_EMPTY;
#else
				//Adds task to wait list:
				uLipePrioSet(currentTask->taskPrio, &q->queueInsertWait);
#endif	
				OS_CRITICAL_OUT();

				//So check for a context switch:
				uLipeKernelTaskYield();

				*err = kQueueEmpty;

				return(ptr);
			}
			break;

			default:
			{
				//All other cases, only return:
				*err = kQueueEmpty;
				return(ptr);
			}
			break;
		}

	}

	//queue holds data, so remove it:
	ptr = (void *) q->queueBase[q->queueBack];
	q->queueBack++;

	//queue bevahes as circular FIFO fashion
	if(q->queueBack > (q->numSlots - 1))
	{
		q->queueBack = 0;
	}
	//Update the number of used slots:
	q->usedSlots--;

	//Update tasks wich pend this queue:
	QueueRemoveLoop(h);

	OS_CRITICAL_OUT();

	//Check for context switching:
	uLipeKernelTaskYield();

	*err = kStatusOk;

	//All gone well:
	return(ptr);
}
예제 #9
0
파일: OsFlags.c 프로젝트: uLipe/uLipeRtosV4
/*
 * FlagsPostLoop()
 * Internal, used to process when all tasks when a flag is asserted
 */
inline static void FlagsPostLoop(OsHandler_t h)
{
	FlagsGrpPtr_t f = (FlagsGrpPtr_t)h;
	uint16_t i = 0;
	uint16_t match = FALSE;
	uint32_t mask  = 0;
	uint16_t tmp = 0;

	//Search for a match flags:
	i = uLipeKernelFindHighPrio(&f->waitTasks[f->activeList]);

	while(i != 0)
	{
		//check for pend type of this task:
		switch(tcbPtrTbl[i]->taskStatus & ((1 << kTaskPendFlagAll) | (1 << kTaskPendFlagAny)))
		{
			case (1 << kTaskPendFlagAll):
			{
				//Only match if all specific flags are set
				mask = f->flagRegister & tcbPtrTbl[i]->flagsPending;
				if(mask == tcbPtrTbl[i]->flagsPending)
				{
				    match = TRUE;
				    tcbPtrTbl[i]->taskStatus &= ~((1 << kTaskPendFlagAll | (1 << kTaskPendDelay)) );
				}
			}
			break;

			case (1 << kTaskPendFlagAny):
			{
				//Match if any of flags are set
				mask = f->flagRegister;
				if(mask != 0)
				{
				    match = TRUE;
                    tcbPtrTbl[i]->taskStatus &= ~((1 << kTaskPendFlagAny | (1 << kTaskPendDelay)) );
				}
			}
			break;

			default:
                match = FALSE; //task waiting nothing
            break;
		}

		//match ocurred?
		if(match != FALSE)
		{

			//Assert a false for next loop
			match = FALSE;


			//Check if this assert will consume flags:
			if(tcbPtrTbl[i]->taskStatus & (1 << kTaskPenFlagConsume))
			{
				//clear these flags
				tmp |= mask;
				tcbPtrTbl[i]->taskStatus &= ~(1 << kTaskPenFlagConsume) ;
                //If we had a consume event, so clear these flags;
                f->flagRegister &= ~(tmp);

			}

            //Make this task as ready:
            if(tcbPtrTbl[i]->taskStatus == 0) {
                uLipePrioSet(i, &taskPrioList);
            }

		}
		else
		{
		    /* ensure this flag is waiting for flags */
		    if(tcbPtrTbl[i]->taskStatus & ((1 << kTaskPendFlagAll) | (1 << kTaskPendFlagAny))) {
	            uLipePrioSet(i, &f->waitTasks[f->activeList ^ 0x01]);
		    }
		}

	    i = uLipeKernelFindHighPrio(&f->waitTasks[f->activeList]);
	    uLipePrioClr(i, &f->waitTasks[f->activeList]);
	}

	/* swap to new active list */
	f->activeList ^= 0x01;
}
예제 #10
0
파일: OsFlags.c 프로젝트: uLipe/uLipeRtosV4
/*
 *  uLipeFlagsPend()
 */
OsStatus_t uLipeFlagsPend(OsHandler_t h, uint32_t flags, uint8_t opt, uint16_t timeout)
{
	uint32_t sReg = 0;
	uint32_t mask = 0;
	uint16_t match = FALSE;
	FlagsGrpPtr_t f = (FlagsGrpPtr_t)h;


	//Check for valid handler
	if(h == 0)
	{
		return(kInvalidParam);
	}

	OS_CRITICAL_IN();

	//Check if this task already asserted:
	mask = f->flagRegister & currentTask->flagsPending;


	//check the pend type:
	switch(opt & ~(OS_FLAGS_CONSUME))
	{
		case OS_FLAGS_PEND_ALL:
		{
			if(mask != flags)
			{
			    currentTask->taskStatus |= (1 << kTaskPendFlagAll);
				//check if wants to consume:
				if(opt & OS_FLAGS_CONSUME)
				{
	                currentTask->taskStatus |= (1 << kTaskPenFlagConsume);
				}

			}
			else
			{

                if(opt & OS_FLAGS_CONSUME)
                {
                    f->flagRegister &= ~currentTask->flagsPending;
                }


				//The flags of this task is already asserted
				match = TRUE;
			}
		}
		break;

		case OS_FLAGS_PEND_ANY:
		{
			if(f->flagRegister == 0x0000000)
			{
                currentTask->taskStatus |= (1 << kTaskPendFlagAny);
                //check if wants to consume:
                if(opt & OS_FLAGS_CONSUME)
                {
                    currentTask->taskStatus |= (1 << kTaskPenFlagConsume);
                }
			}
			else
			{
                if(opt & OS_FLAGS_CONSUME)
                {
                    f->flagRegister = 0;
                }

				//Any flags of this task was already assert
				match = TRUE;
			}
		}
		break;

		default:
		{
			//Invalid option, return with error:
			OS_CRITICAL_OUT();
			return(kInvalidParam);
		}

	}

	//check for match:
	if(match != FALSE)
	{

		//Only return, without suspend task:
		OS_CRITICAL_OUT();

		return(kStatusOk);
	}

	//Set the flags:
	currentTask->flagsPending |= flags;

	//if not, then suspend task:
	uLipePrioClr(currentTask->taskPrio, &taskPrioList);
	uLipePrioSet(currentTask->taskPrio, &f->waitTasks[f->activeList]);
	currentTask->flagsBmp = &f->waitTasks[0];

	//adds the timeout
	if(timeout != 0)
	{
	    currentTask->delayTime  = timeout;
	    currentTask->taskStatus |= (1 << kTaskPendDelay);
	    uLipePrioSet(currentTask->taskPrio, &timerPendingList.list[timerPendingList.activeList]);
	}

	OS_CRITICAL_OUT();

	//Check for a context switch:
	uLipeKernelTaskYield();

	//all gone well:
	return(kStatusOk);
}