📄 ms_relay.c.bak
字号:
#include <linux/fs.h>
#include <linux/iobuf.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/capability.h>
#include <linux/smp_lock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#define ON 0
#define OFF 1
#define RELAY1 GPIO_B10
#define RELAY2 GPIO_B0
#define RELAY3 GPIO_B8
#define RELAY4 GPIO_B1
#define RELAY1_ON_PLUSE 1
#define RELAY1_ON 2
#define RELAY1_OFF 3
#define RELAY2_ON_PLUSE 4
#define RELAY2_ON 5
#define RELAY2_OFF 6
#define RELAY3_ON_PLUSE 7
#define RELAY3_ON 8
#define RELAY3_OFF 9
#define RELAY4_ON_PLUSE 10
#define RELAY4_ON 11
#define RELAY4_OFF 12
static int RELAY_MAJOR=0;
static devfs_handle_t devfs_handle;
static struct timer_list relay1_timer;
static struct timer_list relay2_timer;
static struct timer_list relay3_timer;
static struct timer_list relay4_timer;
int relay_open(struct inode*, struct file *);
int relay_release(struct inode*, struct file *);
int relay_ctl_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
static struct file_operations gpio_ctl_fops= {
ioctl: relay_ctl_ioctl,
open: relay_open,
release: relay_release,
};
int __init gpio_init(void)
{
int result;
result = register_chrdev(0, "relaydriver", &gpio_ctl_fops);
if (result < 0) {
printk("Driver register error!\n");
return result;
}
RELAY_MAJOR=result;
devfs_handle = devfs_register(NULL, "relaydriver", DEVFS_FL_DEFAULT,RELAY_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR,&gpio_ctl_fops, NULL);
return 0;
}
int gpio_release(struct inode*inode, struct file *filp)
{
devfs_unregister(devfs_handle);
unregister_chrdev(RELAY_MAJOR, "relaydriver");
}
int relay_open(struct inode*inode, struct file *filp)
{
set_gpio_ctrl(GPIO_MODE_OUT | RELAY1);
set_gpio_ctrl(GPIO_MODE_OUT | RELAY2);
set_gpio_ctrl(GPIO_MODE_OUT | RELAY3);
set_gpio_ctrl(GPIO_MODE_OUT | RELAY4);
set_gpio_pullup(RELAY1);
set_gpio_pullup(RELAY2);
set_gpio_pullup(RELAY3);
set_gpio_pullup(RELAY4);
write_gpio_bit(GPIO_MODE_OUT | RELAY1,OFF);
write_gpio_bit(GPIO_MODE_OUT | RELAY2,OFF);
write_gpio_bit(GPIO_MODE_OUT | RELAY3,OFF);
write_gpio_bit(GPIO_MODE_OUT | RELAY4,OFF);
MOD_INC_USE_COUNT;
return 0;
}
int relay_release(struct inode*inode, struct file *filp)
{
write_gpio_bit(GPIO_MODE_OUT | RELAY1,OFF);
write_gpio_bit(GPIO_MODE_OUT | RELAY2,OFF);
write_gpio_bit(GPIO_MODE_OUT | RELAY3,OFF);
write_gpio_bit(GPIO_MODE_OUT | RELAY4,OFF);
MOD_DEC_USE_COUNT;
return 0;
}
void relay_set(int port)
{
write_gpio_bit(GPIO_MODE_OUT | port,ON);
}
void relay_clr(int port)
{
write_gpio_bit(GPIO_MODE_OUT | port,OFF);
}
void wait_for_off_relay1(void)
{
relay_clr(RELAY1);
del_timer(&relay1_timer);
}
void wait_for_off_relay2(void)
{
relay_clr(RELAY2);
del_timer(&relay2_timer);
}
void wait_for_off_relay3(void)
{
relay_clr(RELAY3);
del_timer(&relay3_timer);
}
void wait_for_off_relay4(void)
{
relay_clr(RELAY4);
del_timer(&relay4_timer);
}
int relay_ctl_ioctl(struct inode*inode,struct file *flip,unsigned int command,unsigned long arg)
{
int ret=0;
unsigned long arg_time;
unsigned int ms;
switch(command)
{
case RELAY1_ON_PLUSE:
ms=(unsigned int *)arg;
arg_time=(ms*HZ)/1000;
init_timer(&relay1_timer);
relay1_timer.function=wait_for_off_relay1;
relay1_timer.expires = jiffies + arg_time;
relay_set(RELAY1);
add_timer(&relay1_timer);
break;
case RELAY1_ON:
relay_set(RELAY1);
break;
case RELAY1_OFF:
relay_clr(RELAY1);
break;
case RELAY2_ON_PLUSE:
ms=(unsigned int *)arg;
arg_time=(ms*HZ)/1000;
init_timer(&relay2_timer);
relay2_timer.function=wait_for_off_relay2;
relay2_timer.expires = jiffies + arg_time;
relay_set(RELAY2);
add_timer(&relay2_timer);
case RELAY2_ON:
relay_set(RELAY2);
break;
case RELAY2_OFF:
relay_clr(RELAY2);
break;
case RELAY3_ON_PLUSE:
ms=(unsigned int *)arg;
arg_time=(ms*HZ)/1000;
init_timer(&relay3_timer);
relay3_timer.function=wait_for_off_relay3;
relay3_timer.expires = jiffies + arg_time;
relay_set(RELAY3);
add_timer(&relay3_timer);
break;
case RELAY3_ON:
relay_set(RELAY3);
break;
case RELAY3_OFF:
relay_clr(RELAY3);
break;
case RELAY4_ON_PLUSE:
ms=(unsigned int *)arg;
arg_time=(ms*HZ)/1000;
init_timer(&relay4_timer);
relay4_timer.function=wait_for_off_relay4;
relay4_timer.expires = jiffies + arg_time;
relay_set(RELAY4);
add_timer(&relay4_timer);
case RELAY4_ON:
relay_set(RELAY4);
break;
case RELAY4_OFF:
relay_clr(RELAY4);
break;
default:
ret=-1;
break;
}
return ret;
}
module_init(gpio_init); //用户加载该驱动时执行insmod gpio_driv.o就会自动调用gpio_init函数,它是驱动
//的入口点,相当于应用程序的main函数。
module_exit(gpio_release); //用户卸载该驱动rmmod gpio_driv时执行
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -