大多数的内核里面都有会对GPIO的操作,而且内核里面对GPIO进行配置也很方便,要什么功能就配置成什么就可以了。

还有一些寄存器是内核没有配置到的,但是我们要操作怎么办,内核里面也定义了相关的接口函数。

在u-boot中操作某个寄存器:

  1. reg = readl(IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1);
  2. reg &= ~IOMUXC_REG_GPR1_ACTCS0_MASK;
  3. writel(reg, IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1);

其中IOMUXC_BASE_ADDR是物理地址,跟踪代码发现writel操作如下:

#define writel(v,a) __arch_putl(v,a)

#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))

所以在uboot里面配置寄存相当于是给物理地址直接赋值,volatile的意思是提醒编译器需要存储或读取这个变量的时候,都会直接从变量地址中读取数据

而在内核中,上面的写法是无法运行的,会提示虚拟地址错误。在内核中通常是通过虚拟地址来给物理地址赋值,所以需要将物理地址转换成虚拟地址

  1. reg = __raw_readl(ioremap(IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1,4));
  2. reg &= ~IOMUXC_REG_GPR1_ACTCS0_MASK;
  3. reg &= ~IOMUXC_REG_GPR1_ADDRS0_MASK;
  4. reg |= ((CS0_NORFLASH_SIZE | IOMUXC_REG_GPR1_ACTCS0));
  5. __raw_writel(reg, ioremap(IOMUXC_BASE_ADDR + IOMUXC_REG_GPR1,4));

这里的ioremap是将物理地址IOMUXC_BASE_ADDR转换得到对应的虚拟地址,4表示4个字节,即32位的地址。

u-boot下读写gpio:

与读写寄存器类似,u-boot下读写GPIO口是直接给GPIO赋值:

  1. mxc_request_iomux(MX53_PIN_GPIO_8, IOMUX_CONFIG_ALT1);
  2. mxc_iomux_set_pad(MX53_PIN_GPIO_8, 0x1E4);
  3. reg = readl(GPIO1_BASE_ADDR + 0x0);
  4. <span style="white-space:pre"> </span>reg |= 0x100;
  5. writel(reg, GPIO1_BASE_ADDR + 0x0);
  6. // Set pin direction as output
  7. reg = readl(GPIO1_BASE_ADDR + 0x4);
  8. reg |= 0x100;
  9. writel(reg, GPIO1_BASE_ADDR + 0x4);

GPIO_8 是GPIO1_8,前面两个配置GPIO_8的功能。

查看datasheet可以看到GPIO1的地址配置

53F8_4000 GPIO data register (GPIO-1_DR) 32 R/W 0000_0000h 
53F8_4004 GPIO direction register (GPIO-1_GDIR) 32 R/W 0000_0000h 
53F8_4008 GPIO pad status register (GPIO-1_PSR) 32 R 0000_0000h 
53F8_400C GPIO interrupt configuration register1 (GPIO-1_ICR1) 32 R/W 0000_0000h 
53F8_4010 GPIO interrupt configuration register2 (GPIO-1_ICR2) 32 R/W 0000_0000h
53F8_4014 GPIO interrupt mask register (GPIO-1_IMR) 32 R/W 0000_0000h 
53F8_4018 GPIO interrupt status register (GPIO-1_ISR) 32 w1c 0000_0000h
53F8_401C GPIO edge select register (GPIO-1_EDGE_SEL) 32 R/W 0000_0000h

可以看到它的数据寄存器的偏移地址是0x0,输入输出寄存器的偏移地址是0x4。而reg |= 0x100;是GPIO_8的所在的偏移,即(0x1 << 8)。

读取一个gpio的值,只需要读取它的状态寄存器就可以了,

reg = readl( GPIO1_BASE_ADDR + 0x08 );

if(reg & (0x1 << 8))

printf("it is high\n");

else

printf("it is low\n");

linux下uboot kernel操作cpu寄存器的更多相关文章

  1. linux下通过sysfs操作GPIO

    linux下通过sysfs操作GPIO 在嵌入式设备中对GPIO的操作是最基本的操作.一般的做法是写一个单独驱动程序,网上大多数的例子都是这样的.其实linux下面有一个通用的GPIO操作接口,那就是 ...

  2. Linux下读写芯片的I2C寄存器

    要想在Linux下读写芯片的I2C寄存器,一般需要在Linux编写一份该芯片的I2C驱动,关于Linux下如何编写I2C驱动,前一篇文章<手把手教你写Linux I2C设备驱动>已经做了初 ...

  3. 性能测试分析过程(三)linux下查看最消耗CPU/内存的进程

    linux下查看最消耗CPU  内存的进程 1.CPU占用最多的前10个进程:  ps auxw|head -1;ps auxw|sort -rn -k3|head -10  2.内存消耗最多的前10 ...

  4. Linux下查看内核、CPU、内存及各组件版本的命令和方法

    Linux下查看内核.CPU.内存及各组件版本的命令和方法 Linux查看内核版本: uname -a                        more /etc/*release       ...

  5. linux下的shell操作mysql

    (1)MySQL的启动 重启了一次服务器后,使用> mysql -u root -p登陆是出现下面的错误: ERROR 2002 (HY000): Can't connect to local ...

  6. Linux下分析某个进程CPU占用率高的原因

      Linux下分析某个进程CPU占用率高的原因 通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用  1.top 查到占用cpu高的进程pid 2.查看该pid的线程 ...

  7. linux下的文本操作之 文本查找——grep

    摘要:你有没有这样的应用场景:调试一个程序,出现debug的提示信息,现在你需要定位是哪个文件包含了这个debug信息,也就是说,你需要在一个目录下的多个文件(可能包含子目录)中查找某个字符串的位置: ...

  8. Linux下常用的操作

    Linux下常用的操作 文件定位 locate filename 有些版本的linux会出现 -bash: locate: command not found错误,不要慌,安装一下mlocate包就好 ...

  9. Linux下mysql相关操作

    Linux下mysql相关操作 1.创建MySQL mysql -u root -p create user 'username'@'%' identified by 'password'; %可以选 ...

随机推荐

  1. HDFS 文件系统流程图。PB级文件存储时序图。

    大小文件通吃, 热点hash功能. 全局唯一KV索引. 百度网盘模式.断点续传功能.MR分析功能. 来自为知笔记(Wiz)

  2. hadoop1.0.3学习笔记

    回 到 目 录 最近要从网上抓取数据下来,然后hadoop来做存储和分析. 呆毛王赛高 月子酱赛高 小唯酱赛高 目录 安装hadoop1.0.3 HDFS wordcount mapreduce去重 ...

  3. struts2登录后返回登录前的页面

    在Action中添加 String getUrl() { return ServletActionContext.getRequest().getHeader("referer") ...

  4. ti-sdk-evm-am335x-05.07 uboot分析(MLO跳转到u-boot之前)

    --------------------------------------------------------------------------------                     ...

  5. 【Oracle错误集锦】:ORA-00119 &amp; ORA-00132

    有时候老天就是爱和你开玩笑,昨天好不easy配置好Oracle.可以用PL/SQL正常登录使用,今天突然就不行了.而且错误十分诡异,没有提示什么错误代码.输入usernamepassword,点击登录 ...

  6. To new is C++; To malloc is C; To mix them is sin (混淆C++中的new和C中的malloc是一种犯罪)

    Introduction One of the most common questions that get asked during interviews for C++ programmers i ...

  7. Codeforces--602A--Two Bases(水)

    Two Bases Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Submit St ...

  8. html 下载文件代码

    首先在html中加个a标签 <a class="menu" href="/cmdb/file_down" download="ljctest.t ...

  9. 常见的C字符串处理函数的源代码

    #include <stdio.h> #include <assert.h> char *strcpy(char *strDest,const char *strSrc) // ...

  10. HDU 5446 Unknown Treasure Lucas+中国剩余定理+按位乘

    HDU 5446 Unknown Treasure 题意:求C(n, m) %(p[1] * p[2] ··· p[k])     0< n,m < 1018 思路:这题基本上算是模版题了 ...