免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5668 | 回复: 3
打印 上一主题 下一主题

在linux下操作p5的GPIO(ZF) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-07 09:39 |只看该作者 |倒序浏览
STB02500是一款嵌入IBM PPC405 CPU的面向视频,音频应用的SOC芯片
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系统原理框图

cqs.gif (12.62 KB, 下载次数: 52)

cqs.gif

论坛徽章:
0
2 [报告]
发表于 2008-01-07 12:50 |只看该作者
Eric原创技术文章之——Powerpc-linux-x86交叉编译链的构建

把operncv在pc-windows环境下跑通后,接下来需要移植,而移植的第一步,就是要交叉编译。

所谓交叉编译,先要交待两个概念,一个是开发机,也叫host, 另一个是target,也就是目标机。因为嵌入式开发中,最终的程序肯定是要在某个开发板上跑的,但是编程这个过程一般不太可能在开发板上进行,所以一般都是在pc机上写源程序,一般都是c。然后用交叉编译工具,编译成目标板上的cpu可以识别的二进制代码。这个过程就称为交叉编译。

其实所谓开发机和目标机,除去硬件上的差别外,其实还有操作系统的差别,在不同操作系统下,交叉编译工具是不同的,我们这次选择是在linux环境下,用GNU搭建交叉编译环境。

所谓交叉编译环境,就是把GNU中所包含的一些工具,比如gcc, binutils等连接起来,使得他们可以把编译这项工作从上到下串起来,形成一个编译链。

如果自己一项一项连接各个工具,是一项相当麻烦,工作量很大的事情,我尝试了两天,发现编译这些工具的源代码时出现的错误实在太多,暂时先换个办法,找到了一个别人写好的脚本,,先把编译链工作起来,毕竟我们的主要目标是用它去编译别人。这就是crosstool。

首先请到http://www.kegel.com/crosstool/下载crosstool-0.43.tar.gz,

linux下 tar zxvf crosstool-0.43.tar.gz 解压缩。



理论上讲,crosstool是个全自动的工具,它的执行过程如下:

$ sudo mkdir /opt/crosstool

$ sudo chown $USER /opt/crosstool

$ ./ demo-powerpc-405.sh

前两步要用sudo是为了要获得root权限,其中第二步是你的目前的用户名,而第三步最好不要用root权限,不然有可能出错。所以请登陆系统的时候不要用root登录。

/opt/crosstool是最终交叉编译工具生成的地方,那是一些可执行的程序,就像gcc一样,可以执行。后面会看到crosstool这个目录是可以改地方的。

因为前面讲过,crosstool实际就是把GNU的各个工具连接起来,所以,crosstool就像一位厨师,把各种原材料做成美食,但下载到的crosstool源码里是没有gcc,glibc等这些原材料的,那么这些原材料从哪来呢?其实,crosstool会自动通过网络连到ftp.gnu.org去下载所需的文件,但是,速度会很慢。手工下载也很方便,下载下来放到一个downloads文件夹中,这个文件夹的位置下面来讲



进入到crosstool-0.43文件夹,找到demo-powerpc-405.sh 文件,这是一个脚本,前面就定义了两个文件夹的位置:

TARBALLS_DIR=$HOME/downloads

这个downloads文件夹就是你用来放gcc,glibc等的地方,你可以用echo $HOME看一下你的HOME这个环境变量的指向,或者你也可以用绝对路径,反正把downloads放到一个你方便的地方就行了。

接下来RESULT_TOP=/opt/crosstool

这是最终生成工具的地方,也可以更改,如果你更改了,那么请在前面执行chown的地方也要相应变化。

再下来,GCC_LANGUAGES="c,c++" ,是最终编译工具所支持的语言,你也可以加上java。

再往下,可以看到很多用#注释掉的行,像这样:

#eval `cat powerpc-405.dat gcc-4.1.0-glibc-2.3.2.dat` sh all.sh –notest

这是编译链里把那个版本的gcc和哪个版本的glibc连接起来。

你也可以自己修改,最终,没有用#注释掉的那行,就是编译链的生成规则。

但是,请注意,编译链的搭配不是任意的,比如,你想要gcc-4.0.0和 glibc02.3.6,那就就要看当前这个文件夹下有没有相应的gcc4.0.0-glibc2.3.6这个data文件,如果有,这条编译链就可以生成,如果没有,那么就是crosstool不支持。

再下来,执行 ./demo-powerpc-405.sh 就行了 ,注意最好用bash,不要用dash

这是一个漫长的编译过程,我跑了1个小时左右。请耐心等待。



接下来说一说遇到的问题,我遇到了n多问题,我在ubuntu(7.04)下,错误太多(顺便说一句,感觉ubuntu不是很适合作开发),相应的经验是,你选择的交叉编译链,最好和你本机目前的软件版本相同!比如你选择gcc4.40.4-glibc2.3.5,那么最好你目前本机的编译环境就是gcc4.0.0 和glibc2.3.5。查看gcc版本的方法是: gcc –v  .查看glibc版本的方法是,进入/lib文件夹, file libc.so.6 。



我在ubuntu下失败后,换到Fedora 4 下,我选择的交叉编译链是:gcc-4.0.0-glibc-2.3.5

其他工具在编译过程中,会自动去下载,如果太慢,看他在下什么,中断了自己去下,放到downloads里面就是了。

我所用到的工具是:

binutils-2.16.1  

linux-2.6.15.4

linux-libc-headers-2.6.12.0

一般应该不会有太多问题。

建议不要用太高版本的。



编译完成后,你就能在你事先指定的crosstool文件夹中,找到你的交叉编译工具了

进入crosstool\gcc-4.0.0-glibc-2.3.5\powerpc-405-linux-gnu\bin

powerpc-405-linux-gnu-gcc就是编译工具。



试验一下,写一个最简单的hello.c

#include <stdio.h>

int main(int argc, char *argv[])

{

        printf("Hello, world.\n");

        return 0;

}

编译:

$ powerpc-405-linux-gnu-gcc hello.c -o hello

如果需要静态库链接:

$ powerpc-750-unknown-gnu-gcc -static hello.c -o hello







执行:

$ file hello

如果能看到:

hello: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV),

for GNU/Linux 2.4.3, statically linked, not stripped

那就是大功告成了!

论坛徽章:
0
3 [报告]
发表于 2008-06-18 22:10 |只看该作者

回复 #3 T-bagwell 的帖子

T-bag兄所言即是啊,呵呵

论坛徽章:
3
CU大牛徽章
日期:2013-03-13 15:32:35CU大牛徽章
日期:2013-03-13 15:38:15CU大牛徽章
日期:2013-03-13 15:38:52
4 [报告]
发表于 2008-06-23 23:16 |只看该作者
好久没来,忙了点,WHEEL大哥出品的好多都是经典
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP