微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > IO端口映射和IO内存映射(详解S3C24XX_GPIO驱动)

IO端口映射和IO内存映射(详解S3C24XX_GPIO驱动)

时间:11-09 来源:互联网 点击:

(2)inb和outb:

在Linux设备驱动中,宜使用Linux内核提供的函数来访问定位于I/O空间的端口,这些函数包括:
·读写字节端口(8位宽)
unsigned inb(unsigned port);
void outb(unsigned char byte, unsigned port);
·读写字端口(16位宽)
unsigned inw(unsigned port);
void outw(unsigned short word, unsigned port);
·读写长字端口(32位宽)
unsigned inl(unsigned port);
void outl(unsigned longword, unsigned port);
·读写一串字节
void insb(unsigned port, void *addr, unsigned long count);
void outsb(unsigned port, void *addr, unsigned long count);
· insb()从端口port开始读count个字节端口,并将读取结果写入addr指向的内存;outsb()将addr指向的内存的count个字节连续地写入port开始的端口。
·读写一串字
void insw(unsigned port, void *addr, unsigned long count);
void outsw(unsigned port, void *addr, unsigned long count);
·读写一串长字
void insl(unsigned port, void *addr, unsigned long count);
void outsl(unsigned port, void *addr, unsigned long count);
上述各函数中I/O端口号port的类型高度依赖于具体的硬件平台,因此,只是写出了unsigned。

以上知识点摘自:http://www.embeddedlinux.org.cn/html/yingjianqudong/201304/20-2556.html

这儿我不献丑了,因为上面的已经写的很好了。

(四)Linux下的IO端口和IO内存

由于我本人对IMX257的IO内存分配不太了解,曾经询问过很多周立功公司那些所谓的技术人员,每个人回答的答案都是,"你好,我们提供的资料就只是官网上的光盘资料了哦",每次碰到这种话,我真的很无语,我只能说,好吧,只能说是我智商太低了,那些资料太高深了。

好了,废话也不多说了,这次,我就针对S3C24XX的gpio驱动程序来讲解io端口的分配。

1. 定义一些寄存器(数据寄存器,配置寄存器)

上图中,gpio_va就是我们GPIO的基址,是用来确定GPFCON配置寄存器和GPFDAT数据寄存器的指针地址的

,其初始化我们在init函数中会讲解。

2.在init函数中确定gpio基址

前面我们寄存器的正常作用的前提就是gpio_va这个基址,所以我们在init函数中分配IO端口

如图所示,将gpio的地址0x56这个io端口分配为gpio_va,这样也就确定了,前面的配置寄存器和数据寄存器。

3.在open函数中配置GPIO

单片机程序一样,使用GPIO都要先配置GPIO,原理一样:

给GPIO引脚赋初值,以后对GPIO引脚的操作,直接用这个寄存器赋值就可以了

4.在exit函数中释放IO端口

使用完GPIO引脚后,要将我们申请的IO端口释放掉。

总结一下,很简单,申请,配置,释放

申请IO端口à配置GPIO端口为输出(入)à给数据寄存器赋值(读取)à释放IO端口

附上驱动程序:



1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 9 #include 10 #include 11 12 #define DEVICE_NAME     "leds"  13 /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */14 #define LED_MAJOR       231     /* 主设备号 */15 16 static struct class *leds_class;17 static struct class_device    *leds_class_devs[4];18 19 /* bit0<=>D10, 0:亮, 1:灭 20  *  bit1<=>D11, 0:亮, 1:灭 21  *  bit2<=>D12, 0:亮, 1:灭 22  */ 23 static char leds_status = 0x0;  24 static DECLARE_MUTEX(leds_lock); // 定义赋值25 26 //static int minor;27 static unsigned long gpio_va;  //gpio基址28 #define GPIO_OFT(x) ((x) - 0x56)29 //GPIO 配置寄存器30 #define GPFCON  (*(volatile unsigned long *)(gpio_va + GPIO_OFT(0x56050)))31 //GPIO 数据寄存器32 #define GPFDAT  (*(volatile unsigned long *)(gpio_va + GPIO_OFT(0x56054)))33 /* 应用程序对设备文件/dev/leds执行open(...)时,34  * 就会调用s3c24xx_leds_open函数35  */36 static int s3c24xx_leds_open(struct inode *inode, struct file *file)37 {38     int minor = MINOR(inode->i_rdev); //MINOR(inode->i_cdev);39     switch(minor)40     {41         case 0: /* /dev/leds */42         {43             // 配置3引脚为输出44             //s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);45             GPFCON &= ~(0x3<(4*2));46             GPFCON = (1<(4*2));47             48             //s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);49             GPFCON &= ~(0x3<(5*2));50             GPFCON = (1<(5*2));51 52             //s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);53             GPFCON &= ~(0x3<(6*2));54             GPFCON = (1<(6*2));55 56             // 都输出057             //s3c2410_gpio_setpin(S3C2410_GPF4, 0);58             GPFDAT &= ~(1<4);59             60             //s3c2410_gpio_setpin(S3C2410_GPF5, 0);61             GPFDAT &= ~(1<5);62             //s3c2410_gpio_setpin(S3C2410_GPF6, 0);63             GPFDAT &= ~(1<6);64 65             down(&leds_lock);66             leds_status = 0x0;67             up(&leds_lock);68                 69             break;70         }71 72         case 1: /* /dev/led1 */73         {74             s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);75             s3c2410_gpio_setpin(S3C2410_GPF4, 0);76             77             down(&leds_lock);78             leds_status &= ~(1<0);79             up(&leds_lock);80             81             break;82         }83 84         case 2: /* /dev/led2 */85         {86             s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);87             s3c2410_gpio_setpin(S3C2410_GPF5, 0);88             leds_status &= ~(1<1);89             break;90         }91 92         case 3: /* /dev/led3 */93         {94             s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);95             s3c2410_gpio_setpin(S3C2410_GPF6, 0);96 97             down(&leds_lock);98             leds_status &= ~(1<2);99             up(&leds_lock);100             101             break;102         }103     }    104     return 0;105 }106 static int s3c24xx_leds_read(struct file *filp, char __user *buff, 107                                          size_t count, loff_t *offp)108 {109     int minor = MINOR(filp->f_dentry->d_inode->i_rdev);110     char val;112     switch (minor)113     {114         case 0: /* /dev/leds */115         {116             copy_to_user(buff, (const void *)&leds_status, 1);117             break;118         }119         case 1: /* /dev/led1 */120         {121             down(&leds_lock);122             val = leds_status & 0x1;123             up(&leds_lock);124             copy_to_user(buff, (const void *)&val, 1);125             break;126         }127         case 2: /* /dev/led2 */128         {129             down(&leds_lock);130             val = (leds_status>>1) & 0x1;131             up(&leds_lock);132             copy_to_user(buff, (const void *)&val, 1);133             break;134         }135         case 3: /* /dev/led3 */136         {137             down(&leds_lock);138             val = (leds_status>>2) & 0x1;139             up(&leds_lock);140             copy_to_user(buff, (const void *)&val, 1);141             break;142         }143     }144     return 1;145 }146 static ssize_t s3c24xx_leds_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)147 {148     //int minor = MINOR(inode->i_rdev); //MINOR(inode->i_cdev);149     int minor = MINOR(file->f_dentry->d_inode->i_rdev);150     char val;151     copy_from_user(&val, buf, 1);152     switch (minor)153     {154         case 0: /* /dev/leds */155         {            156             s3c2410_gpio_setpin(S3C2410_GPF4, (val & 0x1));157             s3c2410_gpio_setpin(S3C2410_GPF5, (val & 0x1));158             s3c2410_gpio_setpin(S3C2410_GPF6, (val & 0x1));159             down(&leds_lock);160             leds_status = val;161             up(&leds_lock);162             break;163         }164         case 1: /* /dev/led1 */165         {166             s3c2410_gpio_setpin(S3C2410_GPF4, val);167             if (val == 0)168             {169                 down(&leds_lock);170                 leds_status &= ~(1<0);171                 up(&leds_lock);172             }173             else174             {175                 down(&leds_lock);176                 leds_status = (1<0);                177                 up(&leds_lock);178             }179             break;180         }181         case 2: /* /dev/led2 */182         {183             s3c2410_gpio_setpin(S3C2410_GPF5, val);184             if (val == 0)185             {186                 down(&leds_lock);187                 leds_status &= ~(1<1);188                 up(&leds_lock);189             }190             else191             {192                 down(&leds_lock);193                 leds_status = (1<1);                194                 up(&leds_lock);195             }196             break;197         }198         case 3: /* /dev/led3 */199         {200             s3c2410_gpio_setpin(S3C2410_GPF6, val);201             if (val == 0)202             {203                 down(&leds_lock);204                 leds_status &= ~(1<2);205                 up(&leds_lock);206             }207             else208             {209                 down(&leds_lock);210                 leds_status = (1<2);                211                 up(&leds_lock);212             }213             break;214         }215     }216     return 1;217 }218 /* 这个结构是字符设备驱动程序的核心219  * 当应用程序操作设备文件时所调用的open、read、write等函数,220  * 最终会调用这个结构中指定的对应函数221  */static struct file_operations s3c24xx_leds_fops = {223     .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */224     .open   =   s3c24xx_leds_open,     225     .read    =    s3c24xx_leds_read,       226     .write    =    s3c24xx_leds_write,       227 };228 229 /*230  * 执行insmod命令时就会调用这个函数 231  */232 static int __init s3c24xx_leds_init(void)233 {234     int ret;235     int minor = 0;236 237     gpio_va = ioremap(0x56, 0x100);238     if (!gpio_va) {239         return -EIO;240     }241     /* 注册字符设备242      * 参数为主设备号、设备名字、file_operations结构;243      * 这样,主设备号就和具体的file_operations结构联系起来了,244      * 操作主设备为LED_MAJOR的设备文件时,就会调用s3c24xx_leds_fops中的相关成员函数245      * LED_MAJOR可以设为0,表示由内核自动分配主设备号246      */247     ret = 

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top