STB02500是一款嵌入IBM PPC405 CPU的面向视频,音频应用的SOC芯片,集成外围丰富,特别适合用户构建IPTV机顶盒系统。由于笔者以前惯用ARM系统,初次使用powerpc大端cpu还真是有点不适应,还有就是IBM的PPC系统GPIO操作起来要比起ARM系统要复杂些,这些新的特点给笔者的初次power pc之旅带来些额外的烦恼,好在经过一番研究笔者已经对PPC405的GPIO有了初步的熟悉,并顺利的完成控制任务,下面就将笔者对PPC405 GPIO的肤浅理解一一抛出。
一. GPIO物理起始地址: 对于要控制GPIO的嵌入式编程人员来讲,GPIO的物理地址是必须要搞清楚的。STB02500SOC中GPIO的物理基本地址是:0x4006 0000空间长度是:0x44。(gpio_base = 0x4006 0000 len = 0x44)
二. GPIO寄存器:
GPIO共有 9个寄存器分别是:
1. GPO: GPO(32bit)寄存器用于设置或清除对应的GPIO引脚值(高,或者低)。具体控制时需要先读出GPIO引脚的值,然后再用”或”,”与”进行相应的逻辑设置和清除操作,很显然这是非原子的操作,在多任务系统里,是有可能发生意外的,需要程序员在软件上实现相应的原子操作,这和ARM系统的 I/O操作相比应该是比较落后的)。
2. GPTC: GPTC(32bit)寄存器用于设置对应的GPIO引脚是输出还是输入(这样比较好理解些)程序设置相应的bit为1对应的GPIO引脚就是输出否则就是输入(呵呵,这里还要声明一下下,该寄存器要起作用还要设置好GPTS寄存器)。
3. GPOS: GPOS(64bit)寄存器用于控制GPIO相应的引脚是由GPO驱动还是有Alt_Output_x(1,2,3)驱动(就这样简单的理解吧,嘿嘿)。
4. GPTS: GPTS(64bit)这个寄存器功能还是比较难说清楚的呀,简单的讲如果需要用GPO驱动GPIO寄存器,就需要设置对应2bit为00选择GPTC作为输出使能控制器,这样GPTC寄存器才能够起作用的。
5. GPOD: GPOD(32bit)这个寄存器是比较单纯的,如果对应位设置1相应的GPIO引脚就处于漏极开路状态,这样可以适应多电压系统,和多输出驱动单输入系统。
6. GPI: GPI(32bit) 就是相应GPIO引脚的值(高电平,还是低电平)。
7. GPIS1:我暂时还没有研究。
8. GPIS2: 我暂时还没有研究。
9. GPIS3: 我暂时还没有研究。
注意:这里要特别声明:这里的GPIO0对应GPO的bit0,GPO的bit0实际是32位GPOd的bit31(以ARM系统来看)。
三. Linux 下操作gpio:
对于在不支持虚拟内存的操作系统和根本就没有使用操作系统的系统里操作GPIO直接读写对应的GPIO寄存器就可以啦,但是在linux这样的操作系统下,你必须编写一个操作GPIO的驱动,或者是使用一些变通的技巧来操作GPIO.
目前我所知道的在linux下操作GPIO有两种方法:
1. 编写驱动,这当然要熟悉linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据ioctl命令进行GPIO寄存器的读写,并把结果回送到应用层。这里提供一点程序片断供大家参考:
int init_module(void){
printk(KERN_ALERT "ioctl load./r/n");
register_chrdev(254,"ioreg",&fops);
stb_gpio = (STBX25XX_GPIO_REG *)ioremap(GPIO_BASE,GPIO_LEN);
if(stb_gpio == NULL){
printk(KERN_ALERT "can't get io base./r/n");
return -1;
}
return 0;
}
int io_ioctl (struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg){
unsigned long uGpio;
printk(KERN_ALERT "io_ioctl cmd=%04x,arg=%04x./r/n",cmd,(int)arg);
switch(cmd){
case SET_IO_DIR:{
printk(KERN_ALERT "SET_IO_DIR/r/n");
break;
}
case SET_IO_VALUE:{
printk(KERN_ALERT "SET_IO_VALUE/r/n");
break;
}
case GET_IO_VALUE:{
printk(KERN_ALERT "GET_IO_VALUE/r/n");
uGpio = stb_gpio->GPI;
printk(KERN_ALERT "GPIO = %08x",(int)uGpio);
copy_to_user((void *)arg,(const void *) &uGpio,sizeof(uGpio));
break;
}
case GET_IO_DIR:{
printk(KERN_ALERT "GET_IO_DIR/r/n");
break;
}
}
return 0;
}
2. 在应用层使用mmap函数在应用层获得GPIO物理基地址对应的虚拟地址指针,然后使用这个指针来读写GPIO寄存器,这里提供一点程序片断供大家参考:
char dev_name[] = "/dev/mem";
GPIO_REGISTER *gpio_base;
fd = open(dev_name,O_RDWR);
if(fd<0){
printf("open %s is error/n",dev_name);
return -1 ;
}
gpio_base = (GPIO_REGISTER *)mmap( 0, 0x32, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0x40060000 );
if(gpio_base == NULL){
printf("gpio base mmap is error/n");
close(fd);
return -1;
}
gpio_base->or = (gpio_base->or & 0x7fffffff);
3.
4.
四. 总结:
虽然GPIO寄存器很多但是熟悉后,使用起来也很简单的,关键是要理解透每个GPIO引脚的功能,和个寄存器的功能特点。其实如果只是做简单的I/O输入输出控制(大多数单片机开发人员最常用用到),只要熟悉 GPO,GPI,GPTC就可以啦。
附:IBM GPIO系统原理框图
<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype>
分享到:
相关推荐
飞腾CPU Linux下gpio使用方法
powerpc gpio驱动少有的资料, linux驱动开发
linux下应用层操作gpio口,包括读写,直接可以使用
嵌入式arm+linux环境GPIO (通用输入/输出)测试驱动代码
嵌入式Linux下GPIO驱动程序的开发及应用.pdf
里面 是两个版本,一个是带工程的,基于Linux开发板的GPIO子系统,使用poll()函数监听io口的实时电平变化,使用示例: GpioApi ioTest = new GpioApi(this); ioTest->addOutIO(GpioApi::IO_C_0);//添加输出口 ...
基于Linux开发板的GPIO子系统,使用poll()函数监听io口的实时电平变化,使用示例: GpioApi ioTest = new GpioApi(this); ioTest->addOutIO(GpioApi::IO_C_0);//添加输出口 ioTest->addInIO(GpioApi::IO_G_11);//...
Linux系统中控制GPIO,编译内核时使能GPIO,系统中使用GPIO,操作例子,给出典型的命令,一个小例子
在linux下的一个测试GPIO接口功能的测试程序
linux(GPIO)部分源码,源码适用于A8芯片,压缩包内包含Makefile文件,可以编译通过并且调试成功
6410 linux下 GPIO的驱动分析 初学很有用
详细说明Linux的gpio接口,深入了解什么是GPIO
在ARM Linux下使用GPIO模拟SPI时序详解.pdf
方法一:采用iomux的方法 在设备树中iomux中添加复用gpio引脚如下: 查询gpio的base: for i in /sys/class/gpio/* ; do cat $i/label; cat $i/base; echo; done 一般可以这样计算GPIOn_IOx = (n-1)*32 + x
linux下通过GPIO驱动点阵LCD,通过GPIO模拟的LCD数据总线
包含一个C语言库, 适用于在Linux下操作GPIO(读、写、设置等)
嵌入式Linux下的GPIO中断测试程序
基于linux和s3c2440的gpio驱动程序,同时包含了应用程序例子,能够访问任意的单个IO管脚,设置为输入、输出等
s3c2410的GPIO驱动程序和测试程序,linux2.6.14下的
嵌入式Linux中在用户态中操作GPIO接口的代码及相应的测试程序