码迷,mamicode.com
首页 > 编程语言 > 详细

实现自己的RPi.GPIO(三)-Python C API

时间:2015-05-24 16:56:51      阅读:346      评论:0      收藏:0      [点我收藏+]

标签:

Python C 的扩展按照模板来就行了,其实就4步:参数传递,返回值传递,函数注册,初始化。

直接上代码:

技术分享
  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 GPIO_init(GPIO_NUM gpio, unsigned int gpio_port, GPIO_MODE gpio_mode);
127 int GPIO_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 GPIO_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   
 31 
 32   close(file);
 33 
 34   return 0;
 35 }
 36 
 37 int GPIO_write(GPIO_NUM gpio, unsigned int gpio_port, GPIO_VAL gpio_val)
 38 {
 39   int file;
 40   unsigned int TI81XX_GPIO_BASE;
 41   unsigned int *mem_viraddr = NULL;
 42   file = open("/dev/mem", O_RDWR|O_SYNC);
 43   if(file < 0){
 44       printf(" ERROR : /dev/mem open failed write!!!\n");
 45       return -1;
 46   }
 47 
 48   TI81XX_GPIO_BASE = gpio ? TI81XX_GPIO1_BASE:TI81XX_GPIO0_BASE;
 49   mem_viraddr = mmap(NULL, GPIO_REG_ADDR_4KB, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, file, TI81XX_GPIO_BASE);
 50 
 51   mem_viraddr[GPIO_DATAOUT >> 2] = gpio_val ? gpio_port:~gpio_port;
 52 
 53   munmap((void *)mem_viraddr, GPIO_REG_ADDR_4KB);
 54   close(file);
 55 
 56   return 0;
 57 }
 58 
 59 static PyObject *pyGPIO_init(PyObject *self, PyObject *args)
 60 {
 61   int gpio,gpio_port,gpio_mode;
 62   int temp;
 63   PyObject *return_val;
 64 
 65   temp = PyArg_ParseTuple(args, "iii", &gpio,&gpio_port,&gpio_mode);
 66   if(!temp){
 67       return NULL;
 68   }
 69 
 70   temp = GPIO_init(gpio,gpio_port,gpio_mode);
 71   return_val = (PyObject *)Py_BuildValue("i", temp);
 72   return return_val;
 73 }
 74 
 75 static PyObject *pyGPIO_write(PyObject *self, PyObject *args)
 76 {
 77   int gpio,gpio_port,gpio_val;
 78   int temp;
 79   PyObject *return_val;
 80 
 81   temp = PyArg_ParseTuple(args, "iii", &gpio,&gpio_port,&gpio_val);
 82   if(!temp){
 83       return NULL;
 84   }
 85 
 86   temp = GPIO_write(gpio, gpio_port, gpio_val);
 87   return_val = (PyObject *)Py_BuildValue("i", temp);
 88   return return_val;
 89 }
 90 
 91 static PyMethodDef pyGPIOMethods[] = {
 92     {"GPIO_init", pyGPIO_init, METH_VARARGS},
 93     {"GPIO_write", pyGPIO_write, METH_VARARGS},
 94     {NULL,NULL}
 95 };
 96 
 97 void initPyGPIO(void)
 98 {
 99   Py_InitModule("PyGPIO", pyGPIOMethods);
100 }

交叉编译为动态链接库,拷贝到Python库路径下面即可。

技术分享

下面是一个LED闪烁的Python Demo:

‘‘‘
This a PyGPIO module test.
PyGPIO module is written in C, used to deal with GPIO hardware directly by python.
‘‘‘
import PyGPIO
import time
gpio1 = 1                   # GPIO_1
gpio_port = 0x00002000      # GPIO_1.13
gpio_mode = 0               # Output
gpio_val = 1                # Output high level
# Init GPIO1
PyGPIO.GPIO_init(gpio1,gpio_port,gpio_mode)
# Write output value
while(True):
    PyGPIO.GPIO_write(gpio1,gpio_port,0)
    time.sleep(1)
    PyGPIO.GPIO_write(gpio1,gpio_port,1)
    time.sleep(1)

自此,自己实现的RPi.GPIO模块就完成了。当然还有一些问题,比如如何在Python里面使用C里面的枚举类型,这样点亮LED就可以直接GPIO.ON而不是数字1,还有每次写GPIO都需要mmap再munmap,开销很大,可以 init 的时候mmap,不再操作GPIO uninit的时候munmap等。

实现自己的RPi.GPIO(三)-Python C API

标签:

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

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