#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;
}