OK6410A学习笔记四:嵌入式Linux驱动之LED驱动进阶
作为上一篇介绍的LED驱动的续篇,主要的改动之处在于实现了利用Linux系统支持的mdev机制在驱动加载的过程中自动创建设备节点的功能,另外,对write函数有了比较大的改进。
//s3c6410_led.c – driver file
#include
#include
#include
#include
#include
#include
#include
#include
#define DEV_MAJOR 176
#define DEV_NAME "s3c6410_leds"
#define GPMCON 0x7F008820
#define GPMDAT 0x7F008824
#define GPMPUD 0x7F008828
volatile unsigned long *gpmcon = NULL;
volatile unsigned long *gpmdat = NULL;
volatile unsigned long *gpmpud = NULL;
static struct class *s3c6410_led_class;
static struct class_device *s3c6410_led_class_dev;
static int s3c6410_led_open(struct inode *inode, struct file *filp)
{
//int ret;
printk(KERN_ALERT "This is open function of s3c6410 led driver.n");
*gpmpud &= 0xffffffaa; //set GPM0~3 as pull up enabled
*gpmcon &= 0xffff1111; //set GPM0~3 as output
*gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds
return 0;
}
static ssize_t s3c6410_led_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
char val;
copy_from_user(&val,buf,count);
//printk("val is %cn",val);
printk(KERN_ALERT "This is write function of s3c6410 led driver.n");
*gpmpud &= 0xffffffaa;
*gpmcon &= 0xffff1111;
if((int)val){
//turn on leds
printk(KERN_ALERT "Turn on the leds.n");
*gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds
}else{
printk(KERN_ALERT "Turn off the leds.n");
*gpmdat |= 0x0000000f; //set GPM0~3 to low level, which turn off leds
}
return count;
}
struct file_operations s3c6410_led_flops = {
.owner = THIS_MODULE,
.open = s3c6410_led_open,
.write = s3c6410_led_write,
};
static int __init s3c6410_led_init(void)
{
int ret;
//register led device driver into kernel
ret = register_chrdev(DEV_MAJOR,DEV_NAME,&s3c6410_led_flops);
//retriver the vritual address by ioremap
gpmcon = (volatile unsigned long *)ioremap(GPMCON,4); //32-bit reg
gpmdat = gpmcon + 1;
gpmpud = gpmcon + 2;
//create led device node
s3c6410_led_class = class_create(THIS_MODULE,"s3c6410_led");
s3c6410_led_class_dev = device_create(s3c6410_led_class,NULL,MKDEV(DEV_MAJOR,0),
NULL,DEV_NAME);
return 0;
}
static void __exit s3c6410_led_exit(void)
{
//unregister led device dirver from kernel
unregister_chrdev(DEV_MAJOR,DEV_NAME);
//iounmap
iounmap(gpmcon);
//delete led driver node
device_unregister(s3c6410_led_class_dev);
class_destroy(s3c6410_led_class);
}
module_init(s3c6410_led_init);
module_exit(s3c6410_led_exit);
MODULE_DESCRIPTION("This is led driver sample for OK6410A board.");
MODULE_VERSION("1.0");
MODULE_AUTHOR("");
MODULE_LICENSE("Dual BSD/GPL");
//s3c6410_led_test.c – test file
#include
#include
#include
#include
int main(int argc,char* argv[])
{
int fd;
int val;
if(argc != 2){
printf("Usage: n");
printf("%s n",argv[0]);
return 0;
}
else{
if(strcmp(argv[1],"on") == 0) val = 1;
else if(strcmp(argv[1],"off") == 0) val = 0;
else{
printf("Usage: n");
printf("%s ",argv[0]);
return 0;
}
}
fd = open("/dev/s3c6410_leds",O_RDWR);
write(fd,&val,1);
return 0;
}
操作过程:

//s3c6410_led.c – driver file
#include
#include
#include
#include
#include
#include
#include
#include
#define DEV_MAJOR 176
#define DEV_NAME "s3c6410_leds"
#define GPMCON 0x7F008820
#define GPMDAT 0x7F008824
#define GPMPUD 0x7F008828
volatile unsigned long *gpmcon = NULL;
volatile unsigned long *gpmdat = NULL;
volatile unsigned long *gpmpud = NULL;
static struct class *s3c6410_led_class;
static struct class_device *s3c6410_led_class_dev;
static int s3c6410_led_open(struct inode *inode, struct file *filp)
{
}
static ssize_t s3c6410_led_write(struct file *filp, const char __user *buf,
{
}
struct file_operations s3c6410_led_flops = {
};
static int __init s3c6410_led_init(void)
{
NULL,DEV_NAME);
}
static void __exit s3c6410_led_exit(void)
{
}
module_init(s3c6410_led_init);
module_exit(s3c6410_led_exit);
MODULE_DESCRIPTION("This is led driver sample for OK6410A board.");
MODULE_VERSION("1.0");
MODULE_AUTHOR("");
MODULE_LICENSE("Dual BSD/GPL");
//s3c6410_led_test.c – test file
#include
#include
#include
#include
int main(int argc,char* argv[])
{
}
操作过程:

关键词: OK6410ALinux驱动LED驱动进

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码