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

原创文章,作者:254126420,如若转载,请注明出处:https://blog.ytso.com/tech/aiops/271878.html

(0)
上一篇 2022年7月8日 04:50
下一篇 2022年7月8日 04:51

相关推荐

发表回复

登录后才能评论