⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpio_driv.c~

📁 s3c2410芯片GPIO驱动程序源代码 已经在多款2410开发板上跑通
💻 C~
字号:
#include <linux/fs.h> //FILE: gpio_driv.c
#include <linux/iobuf.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/capability.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/arch/cpu_s3c2440.h>
#include <asm/io.h>
#include <linux/vmalloc.h>
#define IOPORT_MAJOR 220 //定义主设备号,和前面的mknod/dev/gpiotestc 220 0匹配
typedef char ioport_device_t; long port_addr;
static ioport_device_t gpio_devices[257];
int gpio_open(struct inode*, structfile *);
int gpio_release(struct inode*, structfile *);
int gpio_ctl_ioctl(struct inode *, struct file *, unsigned int, unsigned long);

static structfile_operations gpio_ctl_fops = { 
	ioctl: gpio_ctl_ioctl,
	open: gpio_open,
	release: gpio_release,
};
//所有的操作系统将硬件设备当作文件处理,所有外设的操作就封装在这个file_operations 结构体里面
//就是文件的open/read/write/close等操作,剩余的都放到一个ioctl函数里面做处理。

int__init gpio_init(void)
{
	inti;
	//可以看到下面这句向操作系统注册的函数里面和前面我们在minicom里面手工创建的设备文件是
	//要完全匹配的:mknod/dev/gpiotestc 220 0,这表明创建的是一个字符设备(chrdev),
	//主设备号220,次设备号0,因为操作系统不理会“gpiotest”这个设备名字符串的,它只认数字的主次
	//设备号,而应用程序到时是open(“/dev/gpiotest”,xx)的,中间就是通过这两个数字联系起来的。
	register_chrdev(IOPORT_MAJOR, "gpiotest", &gpio_ctl_fops);
	return 0;
}

module_init(gpio_init); 
//用户加载该驱动时执行insmod gpio_driv.o就会自动调用gpio_init函数,它是驱动
//的入口点,相当于应用程序的main函数。

module_exit(gpio_release); 
//用户卸载该驱动rmmod gpio_driv时执行


int gpio_open(struct inode*inode, structfile *filp)
{
	intminor;
	minor = MINOR(inode->i_rdev);
#if 0 //这里是通常的做法,因为S3C2410的LINUX内核提供了set_gpio_ctrl专用函数,所以不要下面这样做了,但2440有没有呢?
	(void *)(port_addr) = ioremap(0x56000020,0x8);
	*(volatile unsigned int*)(port_addr)|=0x00008000;
#endif
	//驱动里面在open这个设备的时候设置这个口为输出(因为GPIO必须设置方向,做输入还是输出)
	set_gpio_ctrl(GPIO_MODE_OUT | GPIO_C6);
	gpio_devices[minor]++;
	return 0;
}


int gpio_release(struct inode*inode, structfile *filp)
{ 	intminor;
	minor = MINOR(inode->i_rdev);
	if (gpio_devices[minor])
	gpio_devices[minor]--;
	return 0;
}
int gpio_ctl_ioctl(struct inode*inode,structfile *flip,unsigned intcommand,unsigned long arg)
{
	int err = 0;
	intminor = MINOR(inode->i_rdev);
	switch (command) 	{
		case IOWRITE:
			write_gpio_bit(GPIO_MODE_OUT | GPIO_C6,1); //输出3.3V电平
			return 0;
		case IOCLEAR:
			write_gpio_bit(GPIO_MODE_OUT | GPIO_C6,0); //输出0电平
			return 0;
	}
	return err;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -