硬件延時任務--hwdelay_task

hwdelay_task.h

#ifndef _HWDELAY_TASK_H_
#define _HWDELAY_TASK_H_

#include <rtthread.h>
#include <stdint.h>

#define DELAY_MAILBOX_MAX   5

/*
 * 值爲10us, 那麼該延時任務的誤差就有10us, 該值設置要大量測試
 * 10us 出現了發送一次指令, 執行兩次的情況(一次)
 * 20us 小幅度測試沒出現異樣
 */
#define DELAY_HWTIMER_INTERVAL_US   20

/*
 * 這個結果值要大於0
 */
#define HWDELAYTASK_CALC_DELAY_COUNT(us)        (us < DELAY_HWTIMER_INTERVAL_US ? 1 : us/DELAY_HWTIMER_INTERVAL_US)
/*
 * 這個 s 值不能超過 2147.483647; 因爲 int 所能表示的最大範圍爲 2147483647
 */
#define HWDELAYTASK_CALC_DELAY_COUNT2(s, us)    (((s*1000000)+us)/DELAY_HWTIMER_INTERVAL_US)

struct DelayMailbox{
    volatile uint32_t count;//延時計數, 做減法, 減到0時,將數據發送到郵箱
    rt_mailbox_t send_mb;//任務到達後被髮送到的郵箱
    void* data;
};

extern rt_mailbox_t MbGuidDataDelayHandle;

int8_t delaytask_init();
int8_t delaytask_add(struct DelayMailbox* dmb);

#endif

hwdelay_task.c

#include "hwdelay_task.h"
#include "bsp_gpt.h"

#define DELAY_HWTIMER_DEV_NAME   "gpt2"     /* 定時器名稱 */

static struct imxrt_gpt* dev_hwtimer_hwdelay;
static int8_t state;

static volatile struct DelayMailbox DelayMbs[DELAY_MAILBOX_MAX] = {0};
static volatile uint8_t DelayMbsFront = 0;  //隊首
static volatile uint8_t DelayMbsRear = 0;   //隊尾,最後一個元素的索引+1

rt_mailbox_t MbGuidDataDelayHandle;

static void ht_timeout_cb(void* dev, uint32_t size){
    //這裏要測驗定時器超時回調中的代碼執行時長, 其執行時長要小於定時器的超時時間
    uint8_t i = DelayMbsFront;
    while(i != DelayMbsRear){
        //printf("DelayMbs[%u].count: %u\r\n", i, DelayMbs[i].count);
        DelayMbs[i].count--;
        if(DelayMbs[i].count == 0){
            rt_mb_send(DelayMbs[i].send_mb, (rt_ubase_t)DelayMbs[i].data);
            DelayMbsFront = (DelayMbsFront+1)%DELAY_MAILBOX_MAX;
            return;
        }
        i = (i+1)%DELAY_MAILBOX_MAX;
    }
    return;
}

int8_t delaytask_init(){
    rt_err_t res;
    
    MbGuidDataDelayHandle = rt_mb_create("_MGDDH", DELAY_MAILBOX_MAX, RT_IPC_FLAG_FIFO);
    
    dev_hwtimer_hwdelay = bsp_gpt_init(DELAY_HWTIMER_DEV_NAME, ht_timeout_cb);
    if (dev_hwtimer_hwdelay == RT_NULL) {
        printf("hwtimer sample run failed! can't find %s device!\r\n", DELAY_HWTIMER_DEV_NAME);
        return -1;
    }
    hwtimerval_t timerval = {0, DELAY_HWTIMER_INTERVAL_US};
    bsp_gpt_start(dev_hwtimer_hwdelay, &timerval, HWTIMER_MODE_PERIOD);
    return 0;
}

int8_t delaytask_add(struct DelayMailbox* dmb){
    if((DelayMbsRear+1)%DELAY_MAILBOX_MAX == DelayMbsFront){
        return -1;
    }
    DelayMbs[DelayMbsRear].count = dmb->count;
    DelayMbs[DelayMbsRear].data = dmb->data;
    DelayMbs[DelayMbsRear].send_mb = dmb->send_mb;
    DelayMbsRear = (DelayMbsRear+1)%DELAY_MAILBOX_MAX;
    //printf("DelayMbsRear: %d\r\n", DelayMbsRear);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章