led驱动程序编写
本文主要包含三部分,led驱动程序led.c编写,编译驱动程序的makefile的编写,以及使用驱动程序的应用程序led_app的编写
一、led.c编写
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "led.h"
#define GPMCON 0x7f008820
#define GPMDAT 0x7f008824 unsigned int *led_config;
unsigned int *led_data; struct cdev cdev; //静态分配描述符
dev_t devno; int led_open (struct inode *node, struct file *filp)
{
led_config = ioremap(GPMCON,); //地址转化为虚拟地址
writel(0x1111,led_config); //为虚拟地址写入值 led_data = ioremap(GPMDAT,); //物理地址转化为虚拟地址
return ;
} //响应系统调用函数的驱动函数
long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
switch (cmd) //通过不同命令执行控制命令
{
case LED_ON:
writel(0x00,led_data);
return ; case LED_OFF:
writel(0xff,led_data);
return ; default:
return -EINVAL;
}
} static struct file_operations led_fops =
{
.open = led_open,
.unlocked_ioctl = led_ioctl,
}; static int led_init()
{
cdev_init(&cdev,&led_fops); //初始化设备描述
alloc_chrdev_region(&devno, , , "myled"); //设备号分配
cdev_add(&cdev, devno, ); //注册字符设备
return ;
} static void led_exit()
{
cdev_del(&cdev); //驱动注销
unregister_chrdev_region(devno,); //设备号释放
} module_init(led_init);
module_exit(led_exit);
1.1控制led命令的编写---->led.h
#define LED_MAGIC 'L'
#define LED_ON _IO(LED_MAGIC,0)
#define LED_OFF _IO(LED_MAGIC,1)
二、编译led.c的Makefile的编写
obj-m := led.o
KDIR :=/home/kernel/kernel/linux-ok6410
all:
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
clean:
rm -f *.ko *.o *.order *.symvers *.mod.c *~
三、应用程序的编写
#include "led.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h> int main(int argc,char *argv[])
{
int fd;
int cmd;
if(argc<)
{
printf("please enter the secnod para!\n");
}
cmd = atoi(argv[]); //字符参数转化为整形
fd = open("/dev/myled",O_RDWR);
if(cmd==)
{
ioctl(fd,LED_ON);
printf ("led on!!!\n");
}
else
ioctl(fd,LED_OFF);
}
在完成以上步骤之后就可以安装内核模块并且运行应用程序了
运行过程如下:
首先安装内核模块:insmod led.ko
接着查看注册的设备号:cat /proc/devices
可以看出我注册的led驱动对应的设备号是252
所以接着创建字符设备文件:mknod /dev/myled c 252 0
紧接着运行应用程序:
可以看到开发板上面的所有灯都亮了!!!!!!!
四、出现的问题解决
在运行时候莫名奇妙的出现了一个Segmentation fault,后来查找了很久居然发现是应为在编写led.c的代码时候在
int led_open (struct inode *node, struct file *filp)
{
led_config = ioremap(GPMCON,); //地址转化为虚拟地址
writel(0x1111,led_config); //为虚拟地址写入值 led_data = ioremap(GPMDAT,); //物理地址转化为虚拟地址
return ;
}
这个函数里面缺少了return 0这句差点酿成大祸了。。。。。。。。。。