class="markdown_views prism-github-gist">
嵌入式Linux驱动 GPIO操作
这里记录的是嵌入式linux驱动对gpio的基本操作。但是并不是规范的驱动编写方式,在后面的学习中还要进行改进。
改进过后点击这里
实现的内容是:gpio驱动编写>>>>应用编写(闪烁灯)。
目标板是iTOP4412。CPU为 Exynos4412。
代码
代码部分包括 驱动层代码对GPIO寄存器的直接操作。然后是应用层对驱动的测试代码以验证驱动的正确性。再是Makefile文件规定文件的编译规则。
代码有详细注释。
驱动代码
#include
#include
#include
#include
#include
#include
#include
#define GPIOL2_CON 0x11000000+0x0100
#define LEN 8
volatile unsigned long *gpiol20_cof;
volatile unsigned long *gpiol20_dat;
static int DEV_MAJOR=300;
static int DEV_MINIOR=0;
dev_t dev_num ;
static struct class *devcls;
static struct device * dev;
ssize_t chr_drv_read (struct file *filp, char __user *buffer, size_t count, loff_t *fpos)
{
printk("-------%s-------
",__FUNCTION__);
return 0 ;
}
ssize_t chr_drv_write (struct file *flip, const char __user *buffer, size_t count, loff_t *fpos)
{
int ret;
int value;
static int num=0;
printk("write:%d ",num++);
ret = copy_from_user(&value, buffer, count);
if(value == 1)
{
printk("vaule:%d
",value);
*gpiol20_dat |=1<<0;
}
else
{
printk("vaule:%d
",value);
*gpiol20_dat &=~(1<<0);
}
return 0;
}
int chr_drv_open (struct inode *inode, struct file *filp)
{
printk("-------%s-------
",__FUNCTION__);
return 0;
}
int chr_drv_release (struct inode *inode, struct file *filp)
{
printk("-------%s-------
",__FUNCTION__);
return 0;
}
static struct file_operations file_ops={
.owner = THIS_MODULE,
.open = chr_drv_open,
.read = chr_drv_read,
.write = chr_drv_write,
.release = chr_drv_release,
};
static int __init chr_io_init(void)
{
int ret;
printk("-----------%s--------
",__FUNCTION__);
dev_num= MKDEV(DEV_MAJOR, DEV_MINIOR);
ret = register_chrdev(DEV_MAJOR , "io",&file_ops);
if(ret)
goto reg_err;
devcls = class_create(THIS_MODULE, "io_cls");
dev = device_create(devcls, NULL, dev_num, NULL, "io");
gpiol20_cof= ioremap(GPIOL2_CON, LEN);
gpiol20_dat = gpiol20_cof+1;
*gpiol20_cof &=~(1<<0);
*gpiol20_cof |=1<<0;
return 0;
reg_err:
return ret;
}
static void __exit chr_io_exit(void)
{
unregister_chrdev(DEV_MAJOR, "io");
device_destroy(devcls, dev_num);
class_destroy(devcls);
printk("-----------%s--------
",__FUNCTION__);
}
MODULE_LICENSE("GPL");
module_init(chr_io_init);
module_exit(chr_io_exit);
应用层代码 测试驱动
#include
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
int fd;
int buf=0;
fd = open("/dev/io",O_RDWR);
if(fd<0)
{
printf("open /dev/io failed!
fd:%d
",fd);
return fd;
}
while(1)
{
buf =0;
write(fd,&buf,4);
sleep(1);
buf =1;
write(fd,&buf,4);
sleep(1);
}
close(fd);
return 0;
}
Makefile
#!/bin/bash
obj-m +=io.o
KDIR :=/home/topeet/linux_dirver_learning/iTop4412_Kernel_3.0
PWD ?=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
arm-none-linux-gnueabi-gcc -o chr_test chr_test.c
clean:
rm -rf *.o *.order *.mod.c *.mod.o *.symvers
install:
cp *.ko chr_test /home/topeet/tftpboot