码迷,mamicode.com
首页 > 其他好文 > 详细

实现自己的RPi.GPIO(二)-mmap 直接访问硬件

时间:2015-05-24 17:11:39      阅读:339      评论:0      收藏:0      [点我收藏+]

标签:

通过驱动访问硬件是很方便简洁的事,但是我想直接操作硬件外设的寄存器。好在Linux提供了mmap函数,可以绕过驱动,直接操作外设的寄存器。

mmap可以实现外设的物理地址到Linux虚拟地址的映射,这样就可以通过操作虚拟地址来操作物理地址。

file = open("/dev/mem", O_RDWR|O_SYNC);

mem_viraddr = mmap(NULL, GPIO_REG_ADDR_4KB, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, file, TI81XX_GPIO_BASE);
mem_viraddr:物理地址映射后的虚拟地址。
GPIO_REG_ADDR_4KB:映射的地址块大小。
TI81XX_GPIO_BASE:DM8148的GPIO模块的物理地址。

下面是通过mmap实现直接操作GPIO,点亮LED的DEMO:
技术分享
  1 /*
  2  * PyGPIO.h
  3  *
  4  *  Created on: 2015年5月19日
  5  *      Author: jugg
  6  */
  7 
  8 #ifndef SRC_PYGPIO_H_
  9 #define SRC_PYGPIO_H_
 10 
 11 #include <errno.h>
 12 #include <string.h>
 13 #include <stdio.h>
 14 #include <stdlib.h>
 15 #include <unistd.h>
 16 #include <fcntl.h>
 17 #include <sys/mman.h>
 18 #include <sys/ioctl.h>
 19 #include <sys/stat.h>
 20 
 21 // Ti DM8168/DM8148 GPIO Reg base addr
 22 #define TI81XX_GPIO0_BASE    0x48032000
 23 #define TI81XX_GPIO1_BASE    0x4804C000
 24 
 25 // Pin mux reg base addr
 26 #define PIN_CTRL_AE28        0x481409A8
 27 
 28 #define GPIO_SYSCONFIG        0x10
 29 #define GPIO_SYSSTATUS        0x114
 30 #define GPIO_CTRL        0x130
 31 #define GPIO_OE            0x134
 32 #define GPIO_DATAIN        0x138
 33 #define GPIO_DATAOUT        0x13C
 34 
 35 // GPIO Reg size
 36 #define GPIO_REG_ADDR_4KB    0x1000
 37 
 38 #define GPIO_P0            0x00000001
 39 #define GPIO_P1            0x00000002
 40 #define GPIO_P2            0x00000004
 41 #define GPIO_P3            0x00000008
 42 #define GPIO_P4            0x00000010
 43 #define GPIO_P5            0x00000020
 44 #define GPIO_P6            0x00000040
 45 #define GPIO_P7            0x00000080
 46 #define GPIO_P8            0x00000100
 47 #define GPIO_P9            0x00000200
 48 #define GPIO_P10        0x00000400
 49 #define GPIO_P11        0x00000800
 50 #define GPIO_P12        0x00001000
 51 #define GPIO_P13        0x00002000
 52 #define GPIO_P14        0x00004000
 53 #define GPIO_P15        0x00008000
 54 #define GPIO_P16        0x00010000
 55 #define GPIO_P17        0x00020000
 56 #define GPIO_P18        0x00040000
 57 #define GPIO_P19        0x00080000
 58 #define GPIO_P20        0x00100000
 59 #define GPIO_P21        0x00200000
 60 #define GPIO_P22        0x00400000
 61 #define GPIO_P23        0x00800000
 62 #define GPIO_P24        0x01000000
 63 #define GPIO_P25        0x02000000
 64 #define GPIO_P26        0x04000000
 65 #define GPIO_P27        0x08000000
 66 #define GPIO_P28        0x10000000
 67 #define GPIO_P29        0x20000000
 68 #define GPIO_P30        0x40000000
 69 #define GPIO_P31        0x80000000
 70 
 71 
 72 typedef union {
 73     struct {
 74       unsigned int P0 : 1;
 75       unsigned int P1 : 1;
 76       unsigned int P2 : 1;
 77       unsigned int P3 : 1;
 78       unsigned int P4 : 1;
 79       unsigned int P5 : 1;
 80       unsigned int P6 : 1;
 81       unsigned int P7 : 1;
 82       unsigned int P8 : 1;
 83       unsigned int P9 : 1;
 84       unsigned int P10 : 1;
 85       unsigned int P11 : 1;
 86       unsigned int P12 : 1;
 87       unsigned int P13 : 1;
 88       unsigned int P14 : 1;
 89       unsigned int P15 : 1;
 90       unsigned int P16 : 1;
 91       unsigned int P17 : 1;
 92       unsigned int P18 : 1;
 93       unsigned int P19 : 1;
 94       unsigned int P20 : 1;
 95       unsigned int P21 : 1;
 96       unsigned int P22 : 1;
 97       unsigned int P23 : 1;
 98       unsigned int P24 : 1;
 99       unsigned int P25 : 1;
100       unsigned int P26 : 1;
101       unsigned int P27 : 1;
102       unsigned int P28 : 1;
103       unsigned int P29 : 1;
104       unsigned int P30 : 1;
105       unsigned int P31 : 1;
106     } port;
107     unsigned int port_val;
108 } GPIO_PORT;
109 
110 typedef enum {
111     GPIO_PORT0,
112     GPIO_PORT1
113 } GPIO_NUM;
114 
115 
116 typedef enum {
117     GPIO_WRITE,    //GPIO output
118     GPIO_READ    //GPIO input
119 } GPIO_MODE;
120 
121 typedef enum {
122     GPIO_VAL_LOW,
123     GPIO_VAL_HIGH
124 } GPIO_VAL;
125 
126 int pyGPIO_init(GPIO_NUM gpio, unsigned int gpio_port, GPIO_MODE gpio_mode);
127 int pyGPIO_write(GPIO_NUM gpio, unsigned int gpio_port, GPIO_VAL gpio_val);
128 
129 #endif /* SRC_PYGPIO_H_ */
PyGPIO.h
技术分享
 1 /*
 2  * PyGPIO.c
 3  *
 4  *  Created on: 2015年5月19日
 5  *      Author: jugg
 6  */
 7 #include <python2.6/Python.h>
 8 
 9 #include "PyGPIO.h"
10 
11 
12 int pyGPIO_init(GPIO_NUM gpio, unsigned int gpio_port, GPIO_MODE gpio_mode)
13 {
14   int file;
15   unsigned int TI81XX_GPIO_BASE;
16   unsigned int *mem_viraddr = NULL;
17   file = open("/dev/mem", O_RDWR|O_SYNC);
18   if(file < 0){
19       printf(" ERROR: /dev/mem open failed !!!\n");
20       return -1;
21   }
22 
23   TI81XX_GPIO_BASE = gpio ? TI81XX_GPIO1_BASE:TI81XX_GPIO0_BASE;
24   mem_viraddr = mmap(NULL, GPIO_REG_ADDR_4KB, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, file, TI81XX_GPIO_BASE);
25 
26   mem_viraddr[GPIO_SYSCONFIG >> 2] = 0x10;    // No idle
27   mem_viraddr[GPIO_OE >> 2] = gpio_mode ? gpio_port:~gpio_port;     // GPIO mode setting
28   munmap((void *)mem_viraddr, GPIO_REG_ADDR_4KB);
29 
30   //mem_viraddr = mmap(NULL, 0x10, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, file, PIN_CTRL_AE28);
31   // MUXMODE = GP1_13
32   //mem_viraddr[0] = 0x00050080;
33   //munmap((void *)mem_viraddr, 0x10);
34   close(file);
35 
36   return 0;
37 }
38 
39 int pyGPIO_write(GPIO_NUM gpio, unsigned int gpio_port, GPIO_VAL gpio_val)
40 {
41   int file;
42   unsigned int TI81XX_GPIO_BASE;
43   unsigned int *mem_viraddr = NULL;
44   file = open("/dev/mem", O_RDWR|O_SYNC);
45   if(file < 0){
46       printf(" ERROR : /dev/mem open failed write!!!\n");
47       return -1;
48   }
49 
50   TI81XX_GPIO_BASE = gpio ? TI81XX_GPIO1_BASE:TI81XX_GPIO0_BASE;
51   mem_viraddr = mmap(NULL, GPIO_REG_ADDR_4KB, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, file, TI81XX_GPIO_BASE);
52 
53   mem_viraddr[GPIO_DATAOUT >> 2] = gpio_val ? gpio_port:~gpio_port;
54 
55   munmap((void *)mem_viraddr, GPIO_REG_ADDR_4KB);
56   close(file);
57 
58   return 0;
59 }
PyGPIO.c
技术分享
 1 /*
 2  * main.c
 3  *
 4  *  Created on: 2015年5月18日
 5  *      Author: jugg
 6  */
 7 #include "PyGPIO.h"
 8 /*
 9 static PyObject *helloworld(PyObject *self)
10 {
11   return Py_BuildValue("s", "Hello, Python extensions!!");
12 }
13 
14 static char helloworld_docs[] = "helloworld():Any message you want to put hele!\n";
15 
16 static PyMethodDef helloworld_funcs[] = {
17     {"helloworld", (PyCFunction)helloworld, METH_NOARGS, helloworld_docs},
18     {NULL}
19 };
20 
21 void inithelloworld(void)
22 {
23   Py_InitModule3("helloworld", helloworld_funcs, "Extension module example!");
24 }
25 */
26 
27 int main()
28 {
29   pyGPIO_init(GPIO_PORT1, GPIO_P13, GPIO_WRITE);
30   printf("GPIO init done!\n");
31   pyGPIO_write(GPIO_PORT1, GPIO_P13, GPIO_VAL_HIGH);
32   printf("GPIO write 1 \n");
33   sleep(1);
34   pyGPIO_write(GPIO_PORT1, GPIO_P13, GPIO_VAL_LOW);
35   printf("GPIO write 0 \n");
36   sleep(1);
37   pyGPIO_write(GPIO_PORT1, GPIO_P13, GPIO_VAL_HIGH);
38   printf("gpio write 1 \n");
39   return 0;
40 }
main.c

编译之后得到PyGPIO,tftp到网络文件系统中执行:

技术分享

由于DM8148的GPIO1.13引脚是复用引脚,且默认不是作为GPIO引脚,需要在Kernel中对复用引脚进行配置才能作为GPIO使用。但是Kernel重新配置后,驱动都需要重新编译,太麻烦了。所以我就在uboot中直接操作寄存器,将GPIO1.13引脚配置为GPIO。

技术分享

这样LED灯就可以亮灭了。

实现自己的RPi.GPIO(二)-mmap 直接访问硬件

标签:

原文地址:http://www.cnblogs.com/ipirate/p/4525882.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!