全志A20 GPIO 总结文档
来源:互联网 发布:linux指令grep 编辑:程序博客网 时间:2024/05/19 15:42
/* * author: chwenj@gmail.com. * Agreement: GPL. */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#define GPIO_SET 0xAC #define GPIO_GET 0xAB#define DEVICE_FILE "/dev/gpio_cdev"typedef struct { unsigned char count; //GPIO序列 unsigned char data; //GPIO电平状态} gpio_userspace_t;/*main*/int main(/* int argc, char **argv */){ /*open*/ int gpio_fd, ret; gpio_fd = open(DEVICE_FILE, O_RDWR); //读写权限打开文件 if (gpio_fd < 0) { printf("gpio device fail to open.\n"); return -1; } printf("%s opend.\n", DEVICE_FILE);#if 1 /*write*/ gpio_userspace_t write_gpio; write_gpio.count = 5; //GPIO序列号 write_gpio.data = 1; //GPIO电平值 printf("write: count = %d , data = %d.\n", write_gpio.count, write_gpio.data); ret = write(gpio_fd, &write_gpio, sizeof(gpio_userspace_t)); if (ret < 0) { printf("%s fail to write.\n", DEVICE_FILE); return -1; }#endif /*ioctl*/ gpio_userspace_t ioctl_gpio; ioctl_gpio.data = 0xff; //level:0xff ioctl_gpio.count = 5; //pin:4 ret = ioctl(gpio_fd, GPIO_SET, &ioctl_gpio); if (ret < 0) { printf("ioctl: ioctl fail.\n"); return -1; } /*read*/ gpio_userspace_t read_gpio; ret = read(gpio_fd, &read_gpio, sizeof(gpio_userspace_t)); if (ret < 0) { printf("read: fail to read.\n"); return -1; } printf("read: count = %d, data = %d.\n", read_gpio.count, read_gpio.data); /*close*/ close(gpio_fd); printf("%s close.\n", DEVICE_FILE); return 0;}
#include <linux/fs.h>#include <linux/types.h>#include <linux/module.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/cdev.h>#include <linux/platform_device.h>#include <linux/utsname.h>#include <asm/uaccess.h>#include <asm/io.h>#include <mach/sys_config.h>#include <mach/includes.h>#include <linux/gpio.h>#include <linux/delay.h>/**********************************************************/#define GPIO_SET 0xAC #define GPIO_GET 0xAB /**********************************************************/script_item_u *gpio_list = NULL;//gpio_userspace_t 和 gpio_pdata_t 在序列上是一一对应的关系.typedef struct { unsigned char count; //IO序列:0,1,2,..., 19. unsigned char data; //IO电平.} gpio_userspace_t;typedef struct { struct gpio_config gpio; char gpio_name[32]; int gpio_cnt;} gpio_pdata_t;typedef struct {//debug tag for printk #define __DEBUG_TAG__ #ifdef __DEBUG_TAG__ #define dprintk(fmt, arg...) printk(fmt, ## arg) #else #define dprintk(fmt, arg...) #endif//char device name: /dev/gpio_cdev #define DEVICE_NAME "gpio_cdev"//multiple #define MUL_SEL_INPUT 0 #define MUL_SEL_OUTPUT 1//char device struct cdev *gpio_cdev; dev_t devid; struct class *gpio_class;//gpio count int gpio_cnt;//general gpio subsystem gpio_pdata_t pin[20];//} gpio_info_t;static gpio_info_t info;//global gpio pin record:char pin_count;/**********************************************************/static int gpio_cdev_open(struct inode *inode, struct file *file){ dprintk("[gpio]: gpio_cdev_open fn.\n");<span style="white-space:pre"></span>return 0;}static int gpio_cdev_release(struct inode *inode, struct file *file){ dprintk("[gpio]: gpio_cdev_release fn.\n");<span style="white-space:pre"></span>return 0;}/**********************************************************///writestatic ssize_t gpio_cdev_write(struct file *file, const char __user *buf, \ size_t count, loff_t *ppos){ gpio_userspace_t write_gpio; unsigned char write_data, write_count; dprintk("[gpio]: gpio_cdev_write fn.\n"); copy_from_user(&write_gpio, (gpio_userspace_t *)buf, sizeof(gpio_userspace_t)); write_data = write_gpio.data; write_count = write_gpio.count; dprintk("[gpio][write]: data=%d, count=%d.\n", write_data, write_count); //error correction. if ((write_data != 0) && (write_data != 1)) { dprintk("[gpio][write][error]: write_data invalid.\n"); } if ((write_count < 0) || (write_count >19)) { dprintk("[gpio][write][error]: write_count does not exit.\n"); } gpio_direction_output(info.pin[write_count].gpio.gpio, write_data); //mdelay(1); return 0;}//read static ssize_t gpio_cdev_read(struct file *file, char __user *buf, \ size_t count, loff_t *ppos){ int i; unsigned char data; unsigned int gpio; gpio_userspace_t read_gpio; dprintk("[gpio]: gpio_cdev_read fn.\n");#if 0 gpio_userspace_t read_gpio[20]; for (i = 0; i < 20; i++) { gpio = info.pin[i].gpio.gpio; //调试用;不要轻易打开: #if 0 if(0 != gpio_direction_input(gpio)) { dprintk("set to input failed.\n"); continue; } #endif data = __gpio_get_value(gpio); read_gpio[i].count = i; read_gpio[i].data = data; dprintk("[gpio][read]: pin_%d = %d.\n", read_gpio[i].count, read_gpio[i].data); } copy_to_user(buf, read_gpio, 20*sizeof(gpio_userspace_t));#else i = pin_count; dprintk("[gpio][read]: pin_count = %d.\n", i); gpio = info.pin[i].gpio.gpio; data = __gpio_get_value(gpio); read_gpio.count = i; read_gpio.data = data; dprintk("[gpio][read]: count = %d; data = %d.\n", read_gpio.count, read_gpio.data); copy_to_user(buf, &read_gpio, sizeof(gpio_userspace_t));#endif return 0;}static long gpio_cdev_ioctl(struct file *file, unsigned int cmd, \ unsigned long arg){ dprintk("[gpio]: gpio_cdev_ioctl fn;"); dprintk(" cmd = %d.\n", cmd); void __user *uarg; uarg = (void __user *)arg; gpio_userspace_t ioctl_gpio; copy_from_user(&ioctl_gpio, (gpio_userspace_t *)uarg, sizeof(gpio_userspace_t)); dprintk("[gpio]:count = %d, data = %d.\n", ioctl_gpio.count, ioctl_gpio.data); switch(cmd) { case GPIO_SET: dprintk("[gpio]: ioctl cmd = GPIO_SET.\n"); pin_count = ioctl_gpio.count; dprintk("[gpio]: pin_count = %d.\n", pin_count); if ((pin_count > 19)|| (pin_count < 0)) { dprintk("[gpio][error]: gpio_cdev_ioctl: pin_count invalide.\n"); } break; case GPIO_GET: dprintk("[gpio]: ioctl cmd = GPIO_SET.\n"); break; default: dprintk("[gpio]: ioctl cmd = default.\n"); break; } return 0;}static const struct file_operations gpio_cdev_fops = { .owner = THIS_MODULE, .open = gpio_cdev_open, .release = gpio_cdev_release, .write = gpio_cdev_write, .read = gpio_cdev_read, .unlocked_ioctl = gpio_cdev_ioctl,};static int gpio_fetch_config(void){ char buffer[32] = {}; int i; int cnt = info.gpio_cnt; script_item_value_type_e type; script_item_u val; dprintk("[gpio]: gpio_fetch_config fn.\n"); dprintk("[gpio]: gpio_cnt=%d.\n", cnt); dprintk("--------------------\n"); for(i=0; i< cnt; i++) { //format sprintf sprintf(buffer, "gpio_pin_%d", i); dprintk("[gpio]: buffer=%s.\n", buffer); //fetch gpio_pin_# issue type = script_get_item("gpio_para", buffer, &val); if (SCIRPT_ITEM_VALUE_TYPE_PIO != type) { dprintk("[gpio]: item value type INVALID.\n"); return -1; } else { info.pin[i].gpio.gpio = val.gpio.gpio; info.pin[i].gpio.mul_sel = val.gpio.mul_sel; dprintk("[gpio][pin%d]: gpio=%d, mul_sel=%d, ", i, info.pin[i].gpio.gpio, info.pin[i].gpio.mul_sel); strcpy(info.pin[i].gpio_name, buffer); dprintk("name=%s, ", info.pin[i].gpio_name); info.pin[i].gpio_cnt = i; dprintk("gpio_cnt=%d.\n", info.pin[i].gpio_cnt); dprintk("--------------------\n"); } } dprintk("[gpio]: success to gpio_fetch_config.\n"); return 0;}static int __init gpio_module_init(void){ int ret = 0, err; int cnt = 0, i; script_item_value_type_e type; script_item_u val; dprintk("[gpio]: gpio_module_init fn.\n"); ret = alloc_chrdev_region(&(info.devid), 0, 20, DEVICE_NAME); if ( ret ) { dprintk("[gpio]: fail to alloc_chrdev_region.\n"); return -1; } dprintk("[gpio]: devid major=%d, minor=%d.\n", MAJOR(info.devid), MINOR(info.devid)); info.gpio_cdev = cdev_alloc(); cdev_init(info.gpio_cdev, &gpio_cdev_fops); info.gpio_cdev->owner = THIS_MODULE; err = cdev_add(info.gpio_cdev, info.devid, 1); if (err) { dprintk("[gpio]: cdev_add fail.\n"); return -1; } info.gpio_class = class_create(THIS_MODULE, DEVICE_NAME); if (IS_ERR(info.gpio_class)) { dprintk("[gpio]: class_create fail.\n"); return -1; } <span style="white-space:pre"></span>device_create(info.gpio_class, NULL, info.devid, NULL, DEVICE_NAME);<span style="white-space:pre"></span> dprintk("[gpio]: success to create a gpio cdev.\n"); // type = script_get_item("gpio_para", "gpio_used", &val); if (SCIRPT_ITEM_VALUE_TYPE_INT != type) { dprintk("[gpio]: type not right.\n"); return -1; } if (!val.val) { dprintk("[gpio]: gpio is not used.\n"); return -1; } dprintk("[gpio]: gpio is used.\n"); // cnt = script_get_pio_list("gpio_para", &gpio_list); dprintk("[gpio]: cnt = %d.\n", cnt); info.gpio_cnt = cnt; if (cnt == 0) { dprintk("[gpio]: fail to script_get_pio_list.\n"); return -1; } else { dprintk("[gpio]: requeset gpio(s).\n"); for (i=0; i < cnt; i++) { dprintk("[gpio]: requeset gpio No.%d.\n", i+1); if (0 != gpio_request(gpio_list[i].gpio.gpio, NULL)) dprintk("[gpio]: i = %d; fail to gpio_request.\n", i); } } //dprintk("[gpio]: 1.\n"); //config gpio. if (0 != sw_gpio_setall_range(&gpio_list[0], cnt)) { dprintk("[gpio]: fail to sw_gpio_setall_range.\n"); return -1; } //dprintk("[gpio]: 2.\n"); /*************************************************************/ gpio_fetch_config(); //dprintk("[gpio]: 3.\n"); #if 0 //test gpio. gpio_direction_output(info.pin[4].gpio.gpio, 0); mdelay(5); gpio_direction_output(info.pin[4].gpio.gpio, 1); mdelay(5);#endif //dprintk("[gpio]: 4.\n"); <span style="white-space:pre"></span>return 0;}static void __exit gpio_module_exit(void){ dprintk("[gpio]: gpio_module_exit fn.\n"); <span style="white-space:pre"></span> device_destroy(info.gpio_class, info.devid); class_destroy(info.gpio_class); cdev_del(info.gpio_cdev);}module_init(gpio_module_init);module_exit(gpio_module_exit);MODULE_AUTHOR("chwenj@gmail.com");MODULE_DESCRIPTION("gpio driver");MODULE_LICENSE("GPL");
0 0
- 全志A20 GPIO 总结文档
- 全志A20控制GPIO口的一种方法:
- 全志A20 DIY
- A20 GPIO
- 全志A20开发备忘
- 全志A20 配置串口
- 全志A20编译流程
- 全志 A20 camera移植
- 全志a20 修改序列号
- A20 操作GPIO口
- 全志A20单独烧录内核
- 全志A20一些具体工作
- 全志A20单独烧录内核
- 全志A20一些具体工作
- 全志A20单独烧录内核 .
- 全志A20配置使用spi 功能
- 全志A20电阻屏调试
- 全志A20平台调试IR
- 2014年北京师范大学新生程序设计竞赛网络赛
- iOS开发UI篇 -- 0329UIScrollView案例以及代理详解
- cocos-js 菜鸟学习笔记1
- eclipse如何把多个项目放在一个文件夹下-eclipse中对项目进行分类管理
- Java - 解压和打包Jar
- 全志A20 GPIO 总结文档
- 【4】啤酒鸭
- 【HNOI2014】Jabberwocky
- android studio 1.0,Debug and Performance,第一课:调试和演示
- 无线路由器WDS无线桥接设设置方法图解
- 我的Windows核心编程——完成端口+套接字 图解
- 使用ISAPI_REWRITE限定主机头做重写
- 怎样打开win8中的ODBC数据源
- 考试笔试简答题