[linux]定时器异步通知

—————————–驱动————————————
/*
*file name: misc_device.c
*/

#include #include #include #include #include #include #include #include #include #include #include #include

#include #include

#include #include

#define MISC_MINOR 255

/* imx6uirq设备结构体 */
struct imx6uirq_dev{
struct fasync_struct *async_queue; /* 异步相关结构体 */
};

struct imx6uirq_dev imx6uirq; /* irq设备 */

// 定义定时器
static struct timer_list my_timer;

void my_timer_handler(struct timer_list *t) {

if(imx6uirq.async_queue)
{
// printk(KERN_INFO “timenow =: %ld\n”, jiffies);
kill_fasync(&imx6uirq.async_queue, SIGIO, POLL_IN); /* 释放SIGIO信号 */

}

mod_timer(&my_timer, jiffies + msecs_to_jiffies(1999));
// 重新启动定时器,例如每2秒触发一次

}

static int my_timer_init(void) {
// 初始化定时器
timer_setup(&my_timer, my_timer_handler, 0);

// 设置定时器的首次触发时间,例如 1 秒后
mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000));

printk(KERN_INFO “定时器模块已初始化。\n”);
return 0;
}

static void my_timer_exit(void) {
// 删除定时器,防止再次触发
del_timer(&my_timer);
printk(KERN_INFO “定时器模块已卸载。\n”);
}

static int hello_open(struct inode *inode, struct file *filp)
{
printk(“misc open!\n”);
return 0;
}

static ssize_t hello_write(struct file *filp, const char __user *buf,size_t cnt, loff_t *offt)
{
int ret = 0;
unsigned char data[16];

printk(“misc write\n”);
ret = copy_from_user(data, buf, cnt);
if(ret != 0)
printk(“hello misc write failed\n”);

return ret;
}

static ssize_t hello_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
int ret = 0;
unsigned char data[4] = {0x12, 0x03, 0x56, 0x11};

printk(“misc read\n”);

ret = copy_to_user(buf, &data, sizeof(data));
if(ret != 0)
printk(“hello misc read failed\n”);

return ret;
}

int imx6uirq_fasync(int fd, struct file *filp, int on)
{
return fasync_helper(fd, filp, on, &imx6uirq.async_queue);
}

static int imx6uirq_release(struct inode *inode, struct file *filp)
{
return imx6uirq_fasync(-1, filp, 0);
}

/*
* file operations
*/
struct file_operations hello_fops = {

.owner = THIS_MODULE,
.write = hello_write,
.read = hello_read,
.open = hello_open,
.fasync = imx6uirq_fasync,
.release = imx6uirq_release,
};

/*
* misc description
*/
struct miscdevice hello_misc = {
.minor = MISC_MINOR,
.name = “my-timer”,
.fops = &hello_fops,
};

static int hello_init(void)
{
int ret = 0;

printk(” Hello World enter\n”);

ret = misc_register(&hello_misc);
if(ret != 0)
printk(“hello misc register failed!”);

my_timer_init();
return 0;
}

static void hello_exit(void)
{
my_timer_exit();
printk(” Hello World exit\n “);
misc_deregister(&hello_misc);
}

module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE(“Dual BSD/GPL”);
MODULE_DESCRIPTION(“A simple Hello World Module”);

—————————–应用—————————————–

#include “stdio.h”
#include “unistd.h”
#include “sys/types.h”
#include “sys/stat.h”
#include “fcntl.h”
#include “stdlib.h”
#include “string.h”
#include “poll.h”
#include “sys/select.h”
#include “sys/time.h”
#include “linux/ioctl.h”
#include “signal.h”

static int fd = 0; /* 文件描述符 */

/*
* SIGIO信号处理函数
* @param – signum : 信号值
* @return : 无
*/
static void sigio_signal_func(int signum)
{
int err = 0;
unsigned int keyvalue = 0;
printf(“sigio signal!\r\n”);
}

/*
* @description : main主程序
* @param – argc : argv数组元素个数
* @param – argv : 具体参数
* @return : 0 成功;其他 失败
*/
int main(int argc, char *argv[])
{
int flags = 0;
char *filename;

if (argc != 2) {
printf(“Error Usage!\r\n”);
return -1;
}

filename = argv[1];
fd = open(filename, O_RDWR);
if (fd < 0) { printf("Can't open file %s\r\n", filename); return -1; } /* 设置信号SIGIO的处理函数 */ signal(SIGIO, sigio_signal_func); fcntl(fd, F_SETOWN, getpid()); /* 设置当前进程接收SIGIO信号 */ flags = fcntl(fd, F_GETFL); /* 获取当前的进程状态 */ fcntl(fd, F_SETFL, flags | FASYNC); /* 设置进程启用异步通知功能 */ while(1) { sleep(2); } close(fd); return 0; }

发表评论

邮箱地址不会被公开。 必填项已用*标注