硬件延时任务--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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值