在210上做io口模拟串口
2014-03-25 11:03
393 查看
内核版本:linux3.0.8
CPU:s5pv210
在driver/char/ 目录下添加驱动IO_URAT.c
这个驱动要说明一下::刚开始打算开个定时器来当做波特率,查资料得知,linux下的定时器基数都很高,只能用高精度的定时器“hrtimer”,我也试了下,发现定时时间在us级别下很难定准(这里不知道是否是配置问题,不知道有谁知道的说下)。没办法,就采用延时的方式来设置波特率了。但是这边又出现问题了,直接用延时来发一个字节,误码率非常高,十有九错,最右肯能的原因是在发一个个位时有别的进程或中断打断了我们发送程序。。到这里就想到开个进程给他来发送一个字节,这边对进程不太熟悉,然后看到之前的定时器的中断,于是就用定时器的中断函数来发送数据。。这里有谁知道怎么开进程的指导下哈。
这边有个问题是:当你发完一个字节后,再发第二个字节时会把定时器重新开并初始化,这会导致系统出问题。所以在定时器初始化之前把定时器取消掉了“
当你发完最后一个字节后,定时器没有取消掉。。这也是个大问题。。。。。
然后在写个应用程序就可以对这个驱动进行测试:
然后写个android.mk文件来编译该应用
CPU:s5pv210
在driver/char/ 目录下添加驱动IO_URAT.c
/************************************* NAME:IO-UART.c *************************************/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/miscdevice.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/delay.h> #include <mach/gpio.h> #include <mach/regs-gpio.h> #include <plat/gpio-cfg.h> #include <linux/uaccess.h>//copy_from_user(); #include <linux/hrtimer.h> #define DEVICE_NAME "GPIO_UART" /*定时器设备结构体*/ static struct hrtimer vibe_timer ; static int value = 55 ,test =1 , io_cnt=0 ,test1; /* Time out setting,104 us */ /* 用来指定UART所用的GPIO引脚 */ static int GPIO_UART_gpios[] = { S5PV210_GPH2(0), S5PV210_GPH2(1), }; #define LED_NUM ARRAY_SIZE(GPIO_UART_gpios) static enum hrtimer_restart timer_func(struct hrtimer *timer) { // if(io_cnt < 9) //hrtimer_start(&vibe_timer, ktime_set(0, 49000),HRTIMER_MODE_REL); // printk("start \n"); for(;;) { if(io_cnt++ < 1) {gpio_set_value(GPIO_UART_gpios[0], 0);//起始位 } else if(io_cnt < 10) { if(test&0x01) {gpio_set_value(GPIO_UART_gpios[0], 1); } else {gpio_set_value(GPIO_UART_gpios[0], 0); } test = test >> 1; } else { gpio_set_value(GPIO_UART_gpios[0], 1); io_cnt = 0;test1=1; break; }/**/ udelay(100); } return HRTIMER_NORESTART; } static long GPIO_UART_write(struct file *filp, const char *buf, size_t count , loff_t *offset) { char kbuf[10]; // printk("-----------start------------ \r\n"); io_cnt = 0; copy_from_user(kbuf,buf,count); // printk("kbuf is %c \n",kbuf[0]);
udelay(500)//这里要加个延时,不然会死机 if( test1 == 1) hrtimer_cancel(&vibe_timer); //取消定时器 hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); vibe_timer.function = timer_func ; gpio_set_value(GPIO_UART_gpios[0], 1);// 设置指定引脚的输出电平为1 hrtimer_start(&vibe_timer,ktime_set(0, 100*1000),HRTIMER_MODE_REL); test = kbuf[0]; return count; } static struct file_operations GPIO_UART_dev_fops = { .owner = THIS_MODULE, // .unlocked_ioctl = GPIO_UART_ioctl, .write = GPIO_UART_write, }; static struct miscdevice GPIO_UART_dev = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &GPIO_UART_dev_fops, }; static int __init GPIO_UART_dev_init(void) { int ret; int i; ret = gpio_request(GPIO_UART_gpios[0], "LED"); if (ret) { printk("%s: request GPIO %d for LED failed, ret = %d\n", DEVICE_NAME, GPIO_UART_gpios[0], ret); return ret; } s3c_gpio_cfgpin(GPIO_UART_gpios[0], S3C_GPIO_OUTPUT); s3c_gpio_setpull(S5PV210_GPB(0), S3C_GPIO_PULL_UP); gpio_set_value(GPIO_UART_gpios[0], 1);// 设置指定引脚的输出电平为1 ret = misc_register(&GPIO_UART_dev); printk(DEVICE_NAME"\t------initialized------\n"); return ret; } static void __exit GPIO_UART_dev_exit(void) { int i; hrtimer_cancel(&vibe_timer); //取消定时器 for (i = 0; i < LED_NUM; i++) { gpio_free(GPIO_UART_gpios[i]); } printk(DEVICE_NAME"\texit\n"); misc_deregister(&GPIO_UART_dev); } module_init(GPIO_UART_dev_init); module_exit(GPIO_UART_dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("ljf"); MODULE_DESCRIPTION("GPIO control for IO to uart");
这个驱动要说明一下::刚开始打算开个定时器来当做波特率,查资料得知,linux下的定时器基数都很高,只能用高精度的定时器“hrtimer”,我也试了下,发现定时时间在us级别下很难定准(这里不知道是否是配置问题,不知道有谁知道的说下)。没办法,就采用延时的方式来设置波特率了。但是这边又出现问题了,直接用延时来发一个字节,误码率非常高,十有九错,最右肯能的原因是在发一个个位时有别的进程或中断打断了我们发送程序。。到这里就想到开个进程给他来发送一个字节,这边对进程不太熟悉,然后看到之前的定时器的中断,于是就用定时器的中断函数来发送数据。。这里有谁知道怎么开进程的指导下哈。
这边有个问题是:当你发完一个字节后,再发第二个字节时会把定时器重新开并初始化,这会导致系统出问题。所以在定时器初始化之前把定时器取消掉了“
hrtimer_cancel(&vibe_timer); //取消定时器”
当你发完最后一个字节后,定时器没有取消掉。。这也是个大问题。。。。。
然后在写个应用程序就可以对这个驱动进行测试:
/************************************* NAME:io-uart.c *************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <fcntl.h> int main(int argc, char **argv) { int on_off; int fd; char buf[2] ; if (argc != 2 ) { fprintf(stderr, "Usage: io-uart 0|1\n"); exit(1); } fd = open("/dev/GPIO_UART", O_RDWR);//O_RDWR ,因为我们驱动是写函数,所以要填这个参数 if (fd < 0) { perror("open device GPIO faile"); exit(1); } // sscanf(argv[1], "%d", &on_off); sscanf(argv[1], "%d", &buf); printf("on_off: %d", buf[0]); printf("ioctl+++++++++++++++++++++++++++1\n"); // ioctl(fd, on_off, 0); write(fd,buf,2); printf("write+++++++++++++++++++++++++++2\n"); close(fd); return 0; }
然后写个android.mk文件来编译该应用
# # Makefile for calibrate # LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= io-uart.c LOCAL_MODULE := io-uart LOCAL_MODULE_TAGS := eng include $(BUILD_EXECUTABLE)
相关文章推荐
- 使用单片机普通IO口模拟串口的三种方法
- STM8S003F使用IO口模拟串口(三)使用中断方式发送和接收数据
- STM8S003F使用IO口模拟串口(四)正真意义上的模拟串口
- gec210 i2c程序io模拟方式实现
- STM32用IO口模拟串口
- STM32 IO口模拟串口通讯
- 51单片机IO口模拟串口通讯5
- 20120725-51单片机IO口模拟串口通讯5
- 用STM32F103RCT6的普通IO口模拟串口的实验
- STM8S003F使用IO口模拟串口(二)接收数据
- io 模拟串口
- 使用单片机普通IO口模拟串口的三种方法
- 串口通信类JustinIO.CommPort及使用方法
- 标准IO的简单应用,动静态库,读取系统时间并打印,模拟ls -l功能
- IO模拟I2C代码
- 开发板作模拟网卡(RNDIS)与串口
- 2567. 【NOIP2011模拟9.17】电话时间 (Standard IO)
- 关于IO口模拟SPI
- 2558. 【NOIP2011模拟9.9】过河问题 (Standard IO)
- 史上最口语化Arduino入门教程——1.3模拟IO口