driver
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/major.h>
#include <linux/string.h>
#include <linux/blkdev.h>
#include <linux/completion.h>
#include <linux/compat.h>
#include <linux/chio.h>
#include <linux/mutex.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/timer.h>
#include "cmd.h"
static int major;
static struct class *led_class;
static struct device *led_device;
spinlock_t lock;
static int timeperiod;
struct timer_list timer;
int led_open (struct inode *inode, struct file *file)
{
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
return 0;
}
int led_release (struct inode *inode, struct file *file)
{
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
del_timer_sync(&timer);
return 0;
}
long led_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned long flags;
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
if(_IOC_TYPE(cmd)!='k'){
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
return -EINVAL;
}
if(arg<0)
{
printk(KERN_ERR "ioctrl arg error!\n");
return -1;
}
switch(arg){
case 1:
mod_timer(&timer, jiffies+msecs_to_jiffies(timeperiod));
break;
case 0:
del_timer_sync(&timer);
break;
default :
timeperiod = arg;
spin_lock_irqsave(&lock, flags);
mod_timer(&timer, jiffies+msecs_to_jiffies(timeperiod));
spin_unlock_irqrestore(&lock, flags);
break;
}
return 0;
}
static struct file_operations led_ops = {
.open = led_open,
.unlocked_ioctl = led_ioctl,
.release = led_release,
.owner = THIS_MODULE,
};
void timer_function(struct timer_list *t);
void Timer_init(void)
{
timer_setup(&timer,timer_function,0);
timeperiod = 1000;
}
static int __init timer_init(void)
{
int ret;
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
major = register_chrdev(0, "Atom_Led", &led_ops);
if(major<0){
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
return -EINVAL;
}
led_class = class_create(THIS_MODULE,"Led_class");
if (IS_ERR(led_class)) {
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
return -PTR_ERR(led_class);
}
led_device = device_create(led_class, NULL, MKDEV(major,0), NULL,"Atom_Led");
if (IS_ERR(led_device)) {
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
return -PTR_ERR(led_device);
}
Timer_init();
return ret;
}
void timer_function(struct timer_list *t)
{
printk("timer_function runing!\n");
mod_timer(&timer, jiffies+msecs_to_jiffies(timeperiod));
}
static void __exit timer_exit(void)
{
printk("%s %s %d\n", __FILE__,__FUNCTION__,__LINE__);
del_timer_sync(&timer);
device_destroy(led_class, MKDEV(major, 0));
class_destroy(led_class);
unregister_chrdev(major, "Atom_Led");
}
module_init(timer_init);
module_exit(timer_exit);
MODULE_LICENSE("GPL");
test
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "linux/ioctl.h"
#include <stdlib.h>
#include <sys/ioctl.h>
#include "cmd.h"
int main(int argc, char **argv)
{
int cnt;
int fd;
unsigned int arg;
int ret;
if(argc!=2||argc!=3)
{
printf("input error\n");
return -1;
}
fd = open("/dev/Atom_Led", O_RDWR);
if (fd == -1)
{
printf("can not open file\n");
return -1;
}
if(strcmp(argv[1],"ON")==0)
{
arg = 1;
ioctl(fd,MY_CTRL,arg);
}
else if(strcmp(argv[1],"OFF")==0)
{
arg = 0;
ioctl(fd,MY_CTRL,arg);
}
else if(strcmp(argv[1],"RESET")==0)
{
arg = atoi(argv[2]);
ioctl(fd,MY_CTRL,arg);
}
while(cnt < 5){
sleep(5);
cnt++;
printf("APP is Runing\r\n");
}
ret = close(fd);
if(ret<0){
printf("close error!\r\n");
return -1;
}
return 0;
}
cmd.h
#ifndef __CMD_H
#define __CMD_H
#define DEV_FIFO_TYPE 'k'
#define MY_CTRL _IOW(DEV_FIFO_TYPE,2,int)
#endif
程序讲解
1.功能
1. ./test ON(开始执行定时器,默认给了1s定时。)
在中断函数中
1.打印信息
2.继续填入下一次的延时时间
2. ./test OFF(关闭定时器)
3. ./test RESET Xs设置下一次将会在x/1000s之后进入中断
2.版本差别:
4.14之前:
1.init_timer(&timer)
timer.function = GetIntrTimerCallback;
2.void GetIntrTimerCallback(unsigned long devAddr)
4.14之后:
1.timer_setup(&timer, GetIntrTimerCallback, 0);
void timer_function(struct timer_list *t)