Example #1
0
/*==============================================================================
 * - semC_take()
 *
 * - take a semC. this function maybe block the call task
 */
OS_STATUS semC_take (SEM_CNT *pSemC, uint32 timeout)
{
    int cpsr_c;

    OS_STATUS status = OS_STATUS_ERROR;

    cpsr_c = CPU_LOCK();
again:
    if (pSemC->count > 0) {
        pSemC->count--;
        G_p_current_tcb->delay_ticks = 0;
        status = OS_STATUS_OK;
    } else {

        if (timeout != 0) {
            readyQ_remove (G_p_current_tcb);
            G_p_current_tcb->delay_ticks = timeout;
            G_p_current_tcb->status = TASK_STATUS_PEND_SEM_C;
            G_p_current_tcb->pend_obj = pSemC;
            dlist_add (&pSemC->wait_list, (DL_NODE *)G_p_current_tcb);

            CONTEXT_SWITCH();

            if (G_p_current_tcb->delay_ticks != 0) {
                timeout = G_p_current_tcb->delay_ticks;  /* recalculate timeout value */
                goto again;
            }
        }
    }
    CPU_UNLOCK(cpsr_c);

    return status;
}
Example #2
0
void raw_sched(void)
{
	RAW_SR_ALLOC();

	/*if it is in interrupt or system is locked, just return*/ 
	if (raw_int_nesting || raw_sched_lock) {              
		return;                                             
	}

	USER_CPU_INT_DISABLE();
	         
	get_ready_task(&raw_ready_queue);

	/*if highest task is currently task, then no need to do switch and just return*/
	if (high_ready_obj == raw_task_active) {                 
		USER_CPU_INT_ENABLE();                                     
		return;
	}

	TRACE_TASK_SWITCH(raw_task_active, high_ready_obj);

	CONTEXT_SWITCH(); 

	USER_CPU_INT_ENABLE();  

}
Example #3
0
/*==============================================================================
 * - msgQ_send()
 *
 * - try to send a message to a msgQ, this maybe block the call task 
 */
OS_STATUS msgQ_send (MSG_QUE     *pMsgQ, 
                     const void  *buffer,
                     uint32       buf_len,
                     uint32       timeout)
{
    int cpsr_c;
    OS_STATUS status = OS_STATUS_ERROR;

    DL_NODE *pMsgNode = NULL;
    OS_TCB  *pWaitTcb = NULL;

    cpsr_c = CPU_LOCK();

again:
    if (pMsgQ->cur_num < pMsgQ->max_num) {     /*  there is some space          */
        pMsgQ->cur_num++;
        G_p_current_tcb->delay_ticks = 0;

        /*
         * alloc a messege node and add it into messge list
         */
        pMsgNode = malloc(sizeof(DL_NODE) + pMsgQ->max_len);
        memcpy((void *)(pMsgNode + 1), buffer, MIN(buf_len, pMsgQ->max_len));
        dlist_add(&pMsgQ->msg_list, pMsgNode);

        /*
         * get a wait for Receive task and put it into readyQ
         */
        pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_recv_list);
        if (pWaitTcb != NULL) {
            readyQ_put(pWaitTcb);
        }

        status =  OS_STATUS_OK;
    } else {                                   /*  there is no space            */
        if (timeout != 0) {
            readyQ_remove (G_p_current_tcb);
            G_p_current_tcb->delay_ticks = timeout;
            G_p_current_tcb->status = TASK_STATUS_PEND_MSG_S;  /* msg send pend */
            G_p_current_tcb->pend_obj = pMsgQ;
            dlist_add (&pMsgQ->wait_send_list, (DL_NODE *)G_p_current_tcb);

            CONTEXT_SWITCH();

            if (G_p_current_tcb->delay_ticks != 0) {
                timeout = G_p_current_tcb->delay_ticks;  /* recalculate timeout value */
                goto again;
            }
        }
    }

    CPU_UNLOCK(cpsr_c);

    return status;
}
Example #4
0
/*==============================================================================
 * - msgQ_receive()
 *
 * - try to receive a message from a msgQ, this maybe block the call task 
 */
OS_STATUS msgQ_receive (MSG_QUE *pMsgQ,
                        void    *buffer,
                        uint32   buf_len,
                        uint32   timeout)
{
    int cpsr_c;
    OS_STATUS status = OS_STATUS_ERROR;

    DL_NODE *pMsgNode = NULL;
    OS_TCB  *pWaitTcb = NULL;

    cpsr_c = CPU_LOCK();

again:
    if (pMsgQ->cur_num > 0) {               /* have message(s) */
        pMsgQ->cur_num--;
        G_p_current_tcb->delay_ticks = 0;

        /*
         * copy message context to msg_list
         */
        pMsgNode = dlist_get(&pMsgQ->msg_list);
        memcpy(buffer, (void *)(pMsgNode + 1), MIN(buf_len, pMsgQ->max_len));
        free(pMsgNode);

        /*
         * if there are some task wait for send, alive one of them
         */
        pWaitTcb = (OS_TCB *)dlist_get(&pMsgQ->wait_send_list);
        if (pWaitTcb != NULL) {
            readyQ_put(pWaitTcb);
        }

        status =  OS_STATUS_OK;
    } else {                                /* no message */
        if (timeout != 0) {
            readyQ_remove (G_p_current_tcb);
            G_p_current_tcb->delay_ticks = timeout;
            G_p_current_tcb->status = TASK_STATUS_PEND_MSG_R; /* msg receive pend */
            G_p_current_tcb->pend_obj = pMsgQ;
            dlist_add (&pMsgQ->wait_recv_list, (DL_NODE *)G_p_current_tcb);

            CONTEXT_SWITCH();

            if (G_p_current_tcb->delay_ticks != 0) {
                timeout = G_p_current_tcb->delay_ticks;  /* recalculate timeout value */
                goto again;
            }
        }
    }

    CPU_UNLOCK(cpsr_c);

    return status;
}
Example #5
0
void hybrid_int_process(void)
{
	TASK_0_EVENT_TYPE hybrid_ev;
	RAW_U8 *hybrid_data_temp;
	EVENT_HANLDER *hybrid_receiver;
	LIST *hybrid_node;
	RAW_U8 hybrid_highest_pri;

	RAW_SR_ALLOC();
	
	register RAW_U8 hybrid_task_may_switch = 0u;

	while (1) {
		
		USER_CPU_INT_DISABLE(); 
		
		if (task_0_events) {

			/*current running task can never be task 0*/
			if (raw_int_nesting) {

				raw_sched_lock = 0;
				USER_CPU_INT_ENABLE();
				return;
			}

			else {

				--task_0_events;
				/* There are events that we should deliver. */
				hybrid_ev = task_0_events_queue[task_0_event_end].ev;
				hybrid_data_temp = task_0_events_queue[task_0_event_end].event_data;
				hybrid_receiver = task_0_events_queue[task_0_event_end].p;

				task_0_event_end++;

				if (task_0_event_end == MAX_TASK_EVENT) {                  
					task_0_event_end = 0;
				}
				
				USER_CPU_INT_ENABLE();

				/*exceute the event handler*/
				hybrid_receiver->handle_event(hybrid_ev, hybrid_data_temp);
				hybrid_task_may_switch = 1;
			}
			
		}

		else {
			
			raw_sched_lock = 0;

			if (hybrid_task_may_switch) {
				
				hybrid_highest_pri = raw_ready_queue.highest_priority;
				/*Highest priority task must be the first element on the list*/
				hybrid_node = raw_ready_queue.task_ready_list[hybrid_highest_pri].next;

				/*Get the highest priority task object*/
				high_ready_obj = raw_list_entry(hybrid_node, RAW_TASK_OBJ, task_list);

				/*if highest task is currently task, then no need to do switch and just return*/
				if (high_ready_obj == raw_task_active) { 
					
					USER_CPU_INT_ENABLE();                                     
					return;

				}

				CONTEXT_SWITCH();
			}
			
			USER_CPU_INT_ENABLE();
			return;

		}

	}
	
		
}
Example #6
0
static void task_0_process(void *pa)
{
	TASK_0_EVENT_TYPE ev;
	RAW_U8 *data_temp;
	EVENT_HANLDER *receiver;
	
	RAW_SR_ALLOC();

	pa = pa;

	/*to prevent interrupt happen here to cause system crash at task 0 start*/
	USER_CPU_INT_DISABLE();
	
	remove_ready_list(&raw_ready_queue, &raw_task_0_obj);
	
	USER_CPU_INT_ENABLE();
	
	while (1) {

		/*Get the message info and update it*/
		USER_CPU_INT_DISABLE();

		if (task_0_events) {

			--task_0_events;
			
			/* There are events that we should deliver. */
			ev = task_0_events_queue[task_0_event_end].ev;

			data_temp = task_0_events_queue[task_0_event_end].event_data;
			receiver = task_0_events_queue[task_0_event_end].p;

			task_0_event_end++;

			if (task_0_event_end == MAX_TASK_EVENT) {                  
			    task_0_event_end = 0u;
			}

			/*lock the scheduler, so event handler can not be switched out*/
			raw_sched_lock = 1u;
			
			USER_CPU_INT_ENABLE();

			/*exceute the event handler*/
			receiver->handle_event(ev, data_temp);
		}

		else {

			/*unlock the scheduler, so scheduler can work*/
			raw_sched_lock = 0u;
			
			get_ready_task(&raw_ready_queue);
			CONTEXT_SWITCH();

			USER_CPU_INT_ENABLE();

		}
			
	}
		
}