6410之点灯驱动

来源:互联网 发布:苹果手机充电问题知乎 编辑:程序博客网 时间:2024/05/22 07:46
写一个点LED的驱动分为下面几个步骤:
1.框架
2.完善硬件的操作
a.看原理图
b.看6410手册
c.写代码:
单片机:操作物理地址

驱动:操作虚拟地址:ioremap来进行映射。


查看6410原理图LED SCH如下:


从上图可以看到,要使得LED点亮,需要使得nLEDx输出的电平为低电平,继续查看SCH,可以看到nLEDx连接到主核心板的GPM 引脚,如下所示:


所以要操作的工作有:

1.设置GPM0 - GPM3为输出引脚 

2.点灯或者灭灯,对GPMDAT 进行操作即可。

3.使用ioremap和iounmap对物理地址进行映射和取消映射。


具体代码如下:

#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/init.h>#include <asm/uaccess.h>#include <linux/device.h>#include <asm/io.h>struct class *first_dev_class;struct device *first_dev;volatile unsigned long *gpmcon = NULL;volatile unsigned long *gpmdat = NULL;static int first_drv_open(struct inode *inode, struct file *file) //设备节点的相关操作函数{printk("first_drv_open!!\n");//设置gpio为输出引脚*gpmcon &= ~(0x3 | 0x3 << 4 | 0x3 << 8 | 0x3 << 12);      *gpmcon |= (0x1 | 0x1 << 4 | 0x1 << 8 | 0x1 << 12);  return 0;}static int first_drv_read(struct file *filp, char __user *buff,                                          size_t count, loff_t *offp){printk("first_drv_read!!\n");return 0;}ssize_t first_drv_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos){printk("first_drv_write!!\n");int val;copy_from_user(&val,buf,len);if(val == 1){//点灯          *gpmdat &= ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3);}else if(val == 0){//灭灯*gpmdat |= (1 << 0 | 1 << 1 | 1 << 2 | 1 << 3);  }return sizeof(buf);}static struct file_operations first_drv_fops = {  //填充file_operations结构体    .owner   =   THIS_MODULE,        .open    =   first_drv_open,    .read    =   first_drv_read,    .write   =   first_drv_write,};int major;static int __init first_drv_init(void)//入口函数{printk("first_drv_init\n");major = register_chrdev(0,"first_drv",&first_drv_fops);//告诉内核设备的操作,将first_drv_fops挂接到主设备为123的索引节点上从而让app可以找到first_dev_class = class_create(THIS_MODULE,"first_class");first_dev = device_create(first_dev_class,NULL,MKDEV(major,0),NULL,"shanl");gpmcon = (volatile unsigned long *)ioremap(0x7F008820, 16);//地理地址转换为虚拟地址gpmdat = gpmcon + 1;return 0;}static void __exit first_drv_exit(void){printk("first_drv_exit\n");device_destroy(first_dev_class,MKDEV(major,0));class_destroy(first_dev_class);unregister_chrdev(major,"first_drv");iounmap(0x7F008820);}module_init(first_drv_init);//入口修饰函数module_exit(first_drv_exit);MODULE_LICENSE("GPL"); //证书

测试代码:

#include <stdio.h>#include <fcntl.h>int main(int argc , char **argv){int fd ;int val;if(argc < 2){        printf("Usage : %s <on/off> \n",argv[0]);return -1;}if(!strcmp(argv[1],"on")){val = 1;}else if(!strcmp(argv[1],"off")){val = 0;}fd = open("/dev/shanl",O_RDWR); //打开设备节点/dev/shanlif(fd < 0){printf("Can not open devices\n");return -1;}write(fd,&val,4);//向设备节点做写操作return 0;}
	
				
		
原创粉丝点击