标签:
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_ */
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等。
标签:
原文地址:http://www.cnblogs.com/ipirate/p/4525922.html