/*******************************************************************************
**
** 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;
}
Пример #2
0
/*******************************************************************************
**
** 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;
}