/******************************************************************************* ** ** Function GKI_isend_msg ** ** Description Called from interrupt context to send a buffer to a task ** ** Returns Nothing ** *******************************************************************************/ void GKI_isend_msg (UINT8 task_id, UINT8 mbox, void *msg) { BUFFER_HDR_T *p_hdr; tGKI_COM_CB *p_cb = &gki_cb.com; /* If task non-existant or not started, drop buffer */ if ((task_id >= GKI_MAX_TASKS) || (mbox >= NUM_TASK_MBOX) || (p_cb->OSRdyTbl[task_id] == TASK_DEAD)) { GKI_exception(GKI_ERROR_SEND_MSG_BAD_DEST, "Sending to unknown dest"); GKI_freebuf (msg); return; } #if (GKI_ENABLE_BUF_CORRUPTION_CHECK == TRUE) if (gki_chk_buf_damage(msg)) { GKI_exception(GKI_ERROR_BUF_CORRUPTED, "Send - Buffer corrupted"); return; } #endif #if (GKI_ENABLE_OWNER_CHECK == TRUE) if (gki_chk_buf_owner(msg)) { GKI_exception(GKI_ERROR_NOT_BUF_OWNER, "Send by non-owner"); return; } #endif p_hdr = (BUFFER_HDR_T *) ((UINT8 *) msg - BUFFER_HDR_SIZE); if (p_hdr->status != BUF_STATUS_UNLINKED) { GKI_exception(GKI_ERROR_SEND_MSG_BUF_LINKED, "Send - buffer linked"); return; } if (p_cb->OSTaskQFirst[task_id][mbox]) p_cb->OSTaskQLast[task_id][mbox]->p_next = p_hdr; else p_cb->OSTaskQFirst[task_id][mbox] = p_hdr; p_cb->OSTaskQLast[task_id][mbox] = p_hdr; p_hdr->p_next = NULL; p_hdr->status = BUF_STATUS_QUEUED; p_hdr->task_id = task_id; GKI_isend_event(task_id, (UINT16)EVENT_MASK(mbox)); return; }
/******************************************************************************* ** ** Function GKI_timer_update ** ** Description This function is called by an OS to drive the GKI's timers. ** It is typically called at every system tick to ** update the timers for all tasks, and check for timeouts. ** ** Note: It has been designed to also allow for variable tick updates ** so that systems with strict power savings requirements can ** have the update occur at variable intervals. ** ** Parameters: ticks_since_last_update - (input) This is the number of TICKS that have ** occurred since the last time GKI_timer_update was called. ** ** Returns void ** *******************************************************************************/ void GKI_timer_update (INT32 ticks_since_last_update) { UINT8 task_id; long next_expiration; /* Holds the next soonest expiration time after this update */ /* Increment the number of ticks used for time stamps */ gki_cb.com.OSTicks += ticks_since_last_update; /* If any timers are running in any tasks, decrement the remaining time til * the timer updates need to take place (next expiration occurs) */ gki_cb.com.OSTicksTilExp -= ticks_since_last_update; /* Don't allow timer interrupt nesting */ if (gki_cb.com.timer_nesting) return; gki_cb.com.timer_nesting = 1; #if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0)) /* if inactivity delay timer is set and expired */ if (gki_cb.com.OSTicksTilStop) { if( gki_cb.com.OSTicksTilStop <= (UINT32)ticks_since_last_update ) { if(gki_cb.com.p_tick_cb) { gki_cb.com.system_tick_running = FALSE; (gki_cb.com.p_tick_cb) (FALSE); /* stop system tick */ } gki_cb.com.OSTicksTilStop = 0; /* clear inactivity delay timer */ gki_cb.com.timer_nesting = 0; return; } else gki_cb.com.OSTicksTilStop -= ticks_since_last_update; } #endif /* No need to update the ticks if no timeout has occurred */ if (gki_cb.com.OSTicksTilExp > 0) { gki_cb.com.timer_nesting = 0; return; } GKI_disable(); next_expiration = GKI_NO_NEW_TMRS_STARTED; /* If here then gki_cb.com.OSTicksTilExp <= 0. If negative, then increase gki_cb.com.OSNumOrigTicks to account for the difference so timer updates below are decremented by the full number of ticks. gki_cb.com.OSNumOrigTicks is reset at the bottom of this function so changing this value only affects the timer updates below */ gki_cb.com.OSNumOrigTicks -= gki_cb.com.OSTicksTilExp; /* Check for OS Task Timers */ for (task_id = 0; task_id < GKI_MAX_TASKS; task_id++) { if (gki_cb.com.OSWaitTmr[task_id] > 0) /* If timer is running */ { gki_cb.com.OSWaitTmr[task_id] -= gki_cb.com.OSNumOrigTicks; if (gki_cb.com.OSWaitTmr[task_id] <= 0) { /* Timer Expired */ gki_cb.com.OSRdyTbl[task_id] = TASK_READY; } } #if (GKI_NUM_TIMERS > 0) /* If any timer is running, decrement */ if (gki_cb.com.OSTaskTmr0[task_id] > 0) { gki_cb.com.OSTaskTmr0[task_id] -= gki_cb.com.OSNumOrigTicks; if (gki_cb.com.OSTaskTmr0[task_id] <= 0) { /* Set Timer 0 Expired event mask and reload timer */ #if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE) GKI_isend_event (task_id, TIMER_0_EVT_MASK); #else GKI_send_event (task_id, TIMER_0_EVT_MASK); #endif gki_cb.com.OSTaskTmr0[task_id] = gki_cb.com.OSTaskTmr0R[task_id]; } } /* Check to see if this timer is the next one to expire */ if (gki_cb.com.OSTaskTmr0[task_id] > 0 && gki_cb.com.OSTaskTmr0[task_id] < next_expiration) next_expiration = gki_cb.com.OSTaskTmr0[task_id]; #endif #if (GKI_NUM_TIMERS > 1) /* If any timer is running, decrement */ if (gki_cb.com.OSTaskTmr1[task_id] > 0) { gki_cb.com.OSTaskTmr1[task_id] -= gki_cb.com.OSNumOrigTicks; if (gki_cb.com.OSTaskTmr1[task_id] <= 0) { /* Set Timer 1 Expired event mask and reload timer */ #if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE) GKI_isend_event (task_id, TIMER_1_EVT_MASK); #else GKI_send_event (task_id, TIMER_1_EVT_MASK); #endif gki_cb.com.OSTaskTmr1[task_id] = gki_cb.com.OSTaskTmr1R[task_id]; } } /* Check to see if this timer is the next one to expire */ if (gki_cb.com.OSTaskTmr1[task_id] > 0 && gki_cb.com.OSTaskTmr1[task_id] < next_expiration) next_expiration = gki_cb.com.OSTaskTmr1[task_id]; #endif #if (GKI_NUM_TIMERS > 2) /* If any timer is running, decrement */ if (gki_cb.com.OSTaskTmr2[task_id] > 0) { gki_cb.com.OSTaskTmr2[task_id] -= gki_cb.com.OSNumOrigTicks; if (gki_cb.com.OSTaskTmr2[task_id] <= 0) { /* Set Timer 2 Expired event mask and reload timer */ #if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE) GKI_isend_event (task_id, TIMER_2_EVT_MASK); #else GKI_send_event (task_id, TIMER_2_EVT_MASK); #endif gki_cb.com.OSTaskTmr2[task_id] = gki_cb.com.OSTaskTmr2R[task_id]; } } /* Check to see if this timer is the next one to expire */ if (gki_cb.com.OSTaskTmr2[task_id] > 0 && gki_cb.com.OSTaskTmr2[task_id] < next_expiration) next_expiration = gki_cb.com.OSTaskTmr2[task_id]; #endif #if (GKI_NUM_TIMERS > 3) /* If any timer is running, decrement */ if (gki_cb.com.OSTaskTmr3[task_id] > 0) { gki_cb.com.OSTaskTmr3[task_id] -= gki_cb.com.OSNumOrigTicks; if (gki_cb.com.OSTaskTmr3[task_id] <= 0) { /* Set Timer 3 Expired event mask and reload timer */ #if (defined(GKI_TIMER_UPDATES_FROM_ISR) && GKI_TIMER_UPDATES_FROM_ISR == TRUE) GKI_isend_event (task_id, TIMER_3_EVT_MASK); #else GKI_send_event (task_id, TIMER_3_EVT_MASK); #endif gki_cb.com.OSTaskTmr3[task_id] = gki_cb.com.OSTaskTmr3R[task_id]; } } /* Check to see if this timer is the next one to expire */ if (gki_cb.com.OSTaskTmr3[task_id] > 0 && gki_cb.com.OSTaskTmr3[task_id] < next_expiration) next_expiration = gki_cb.com.OSTaskTmr3[task_id]; #endif } /* Set the next timer experation value if there is one to start */ if (next_expiration < GKI_NO_NEW_TMRS_STARTED) { gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = next_expiration; } else { gki_cb.com.OSTicksTilExp = gki_cb.com.OSNumOrigTicks = 0; } gki_cb.com.timer_nesting = 0; GKI_enable(); return; }