xenomai定时器测试

    点击查看代码
    /*
     * Copyright (C) 2019 BNIS
    * 用dmesg -c 查看
    * 定时器测试,insmod 模块后,定时器1为每隔1秒钟触发一次!测试显示定时器分辨率精度, 定时器2为每隔2秒触发一次。
    * Timer-api查看:
    * https://xenomai.org/documentation/xenomai-3/html/xeno3prm/group__rtdm__timer.html
     */
     
    //mydriver.c文件
     
    #include <linux/module.h>
    #include <rtdm/driver.h>
    #include <rtdm/testing.h>
     
     
    #define TIME_EXP   500000000ULL  //500ms后触发timer1
    #define TIME_EXP2  500000000ULL  //500ms后触发timer2
    #define TIME_INV   1000000000ULL  //timer1间隔1000ms
    #define TIME_INV2  2000000000ULL  //timer2间隔2000ms
     
    #define DEVICE_NAME "bnis_rtdm"
     
     
    MODULE_DESCRIPTION("RTDM test helper module");
    MODULE_AUTHOR("bniss@aliyun.com");
    MODULE_VERSION("0.1.0");
    MODULE_LICENSE("GPL");
     
    struct rtdm_basic_context {
        unsigned long number;
    };
     
     rtdm_timer_t test_timer;
     long cnt = 0;
     uint64_t nanoRead;
     
     
     rtdm_timer_t test_timer2;
     long cnt2 = 0;
     
     
    static void test_timer_proc(rtdm_timer_t *timer)
    {
        uint64_t rcd = rtdm_clock_read() ;    
        if( timer == &test_timer) //定时器1
        {
            double acy = (rcd-nanoRead)*100.0/TIME_INV ;
    	    printk("#test_timer_proc,cnt1 = %lu.dif = %ld nS, accuracy = %ld \n" ,
                cnt++ ,
                rcd-nanoRead,
                (rcd-nanoRead)*10000/TIME_INV
               );
              //每次触发定时输出当前时间和上次的时间做差运算,作定时器精度计算。      
            nanoRead = rcd ;
        }else if(timer == &test_timer2){ //定时器2
            printk("#test_timer_proc,cnt2 = %lu ,current clock = %ld ",cnt2++ , rcd);
        }
    }
     
    static int rtdm_bnis_open(struct rtdm_fd *fd, int oflags)
    {
       通过用户端调用rt_dev_open(DEVICE_NAME,0);触发
        printk("#device_bnis is open .flag = %d. \n" , oflags );
        return 0;
        
    }
     
    static void rtdm_bnis_close(struct rtdm_fd *fd)
    {
      通过用户端调用rt_dev_close(DEVICE_NAME);触发
       printk("#device_bnis close. \n");
    }
     
    static struct rtdm_driver rtdm_bnis_driver = {
        .profile_info        = RTDM_PROFILE_INFO(rtdm_bnis_basic,
                                RTDM_CLASS_TESTING,
                                RTDM_SUBCLASS_RTDMTEST,
                                RTTST_PROFILE_VER),
        .device_flags        = RTDM_NAMED_DEVICE | RTDM_EXCLUSIVE,
        .device_count        = 2,
        .context_size        = sizeof(struct rtdm_basic_context),
        .ops = {
            .open        = rtdm_bnis_open,
            .close        = rtdm_bnis_close,
        },
    };
     
    static struct rtdm_device myDevice = {
        
            .driver = &rtdm_bnis_driver,
            .label = DEVICE_NAME,
     
    };
     
    static int __init rtdm_test_init(void)
    {
        printk("======init test for rtdm=========\n");
         
         rtdm_dev_register( &myDevice);
         //test_timer为定时器句柄用于启停控制
         //test_timer_proc为定时过程处理回调函数
         rtdm_timer_init(&test_timer, test_timer_proc,"rtdm-timer");
         nanoRead = rtdm_clock_read();  //获取当前Unix时间戳,用于时间对比
         rtdm_timer_start(&test_timer,TIME_EXP,TIME_INV,RTDM_TIMERMODE_RELATIVE);//采用相对时间模式
         //500ms 后触发定时器1,间隔1秒 (with define)
         rtdm_timer_init(&test_timer2, test_timer_proc,"rtdm-timer2"); //定时器2和定时器1共用回调处理
         rtdm_timer_start(&test_timer2,TIME_EXP+nanoRead,TIME_INV2,RTDM_TIMERMODE_REALTIME);//采用绝对时间戳
         
     
     
        return 0;
    }
     
    static void __exit rtdm_test_exit(void)
    {
        printk("=======exit rtdm test =========\n");
        rtdm_timer_destroy(&test_timer);//退出前销毁定时器资源
        rtdm_timer_destroy(&test_timer2);
        rtdm_dev_unregister(&myDevice); //注销设备释放资源
    }
     
    module_init(rtdm_test_init);
    module_exit(rtdm_test_exit);
    
    ##################################################

    xenomai3定时器api分析:

    1)rtdm时钟函数与cobalt时钟函数对应

    rtdm_clock_read()<=>xnclock_read_realtime()
    rtdm_clock_read_monotonic()<=>xnclock_read_monotonic();

    2)定时器启动函数原型:

    int rtdm_timer_start(rtdm_timer_t *timer, nanosecs_abs_t expiry,
    nanosecs_rel_t interval, enum rtdm_timer_mode mode);

    第1参数timer为定时器句柄,用于定时器的启停控制.

    第2参数expiry为定时器执行有效期,即从调用到首次触发执行的时长,时间单位纳秒.

    第3参数interval为定时器循环间隔,若设置为0则执行一次定时.

    第4参数interval为定时器模式,有3模式,分别为 RTDM_TIMERMODE_RELATIVE ,RTDM_TIMERMODE_ABSOLUTE ,RTDM_TIMERMODE_REALTIME.

    3)定时器模式介绍:

    RTDM_TIMERMODE_RELATIVE,此模式下首次触发执行的时间点相对于调用rtdm_timer_start().

    RTDM_TIMERMODE_ABSOLUTE ,此模式下首次触发执行的时间点基于系统运行时间,用函数rtdm_clock_read_monotonic()获取.

    RTDM_TIMERMODE_REALTIME,此模式下首次触发执行的时间点绝对的Unix时间戳,可用函数rtdm_clock_read()获取.此模式适合用于指定XX时XX分XX秒执行任务.

    4)定时器回调处理函数原型static void (*handler)(rtdm_timer_t *timer), 对于多个定时器的处理方法,在初始化定时器时可指定同一个回调函数,在回调函数里通过结构体指针timer地址来区分是哪个定时器句柄触发.

    ##########内核层Makefile文件##############################
    ————————————————
    版权声明:本文为CSDN博主「wabil」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/wabil/article/details/104022708

    点击查看代码
    ###### CONFIGURATION ######
     
    ### List of modules to be build
    MODULES = mydriver
     
    ###### KERNEL MODULE BUILD (no change required normally) ######
    ifneq ($(MODULES),)
     
    ### Default to sources of currently running kernel
    KSRC ?= /lib/modules/$(shell uname -r)/build
     
    OBJS     := ${patsubst %, %.o, $(MODULES)}
    CLEANMOD := ${patsubst %, .%*, $(MODULES)}
    PWD      := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)
     
    ### Kernel 2.6 or 3.0
    PATCHLEVEL:=$(shell sed 's/PATCHLEVEL = \(.*\)/\1/;t;d' $(KSRC)/Makefile)
    VERSION:=$(shell sed 's/VERSION = \(.*\)/\1/;t;d' $(KSRC)/Makefile)
    ifneq ($(VERSION).$(PATCHLEVEL),2.4)
     
    obj-m        := $(OBJS)
    EXTRA_CFLAGS := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/posix $(ADD_CFLAGS)
     
    all::
    	$(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules
    	@echo `date` "===========Finish-1===================="
     
    ### Kernel 2.4
    else
     
    ARCH    ?= $(shell uname -i)
    INCLUDE := -I$(KSRC)/include/xenomai -I$(KSRC)/include/xenomai/compat -I$(KSRC)/include/xenomai/posix
    CFLAGS  += $(shell $(MAKE) -s -C $(KSRC) CC=$(CC) ARCH=$(ARCH) SUBDIRS=$(PWD) modules) $(INCLUDE)
     
    all:: $(OBJS)
    	@echo `date` "===========Finish-2===================="
     
    endif
     
    ## Target for capturing 2.4 module CFLAGS
    modules:
    	@echo "$(CFLAGS)"
     
    clean::
    	$(RM) $(CLEANMOD) *.o *.ko *.mod.c Module*.symvers Module.markers modules.order
    	$(RM) -R .tmp*
     
    endif
    
    posted @   相对维度  阅读(253)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
    · 地球OL攻略 —— 某应届生求职总结
    · 周边上新:园子的第一款马克杯温暖上架
    · 提示词工程——AI应用必不可少的技术
    · Open-Sora 2.0 重磅开源!
    点击右上角即可分享
    微信分享提示