大神们有没有可以使用的S3C2440 UART驱动驱动代码,最近在弄串口蓝牙,参考了网上的UART驱动进行了实验,可是并不能正常使用,下面贴出源码,大家帮忙看看哪里出问题了。
#include <linux/kernel.h> #include <linux/module.h> #include <asm/uaccess.h> //copy_to_use, copy_from_user #include <asm/io.h> #include <linux/fs.h> #include "regs-serial.h" //寄存器宏 #include <linux/serial_core.h> //readl, readb, writel, writeb #define BUFSIZE 100 #define ttyS0_MAJOR 240 #define iobase S3C24XX_VA_UART1 #define UART_ULCON1 iobase #define UART_UCON1 iobase + 0x4 #define UART_UFCON1 iobase + 0x8 #define UART_UTRSTAT1 iobase + 0x10 #define UART_UTXH1 iobase + 0x20 #define UART_URXH1 iobase + 0x24 #define UART_UBRDIV1 iobase + 0x28 MODULE_AUTHOR("sunsea"); MODULE_DESCRIPTION("s3c2440 serial driver"); MODULE_LICENSE("GPL"); int sunsea_open(struct inode *inode, struct file *filp) { writel(3, UART_ULCON1); writel(5, UART_UCON1); writel(26, UART_UBRDIV1); //115200 return 0; } ssize_t sunsea_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { char wbuf[BUFSIZE] = {0}; int state; int i = 0; copy_from_user(wbuf, buf, count); while(wbuf[i] != '/0') { state = readl(UART_UTRSTAT1); if((0x02 & state) == 2) { writeb(wbuf[i], UART_UTXH1); i++; } } return 0; } ssize_t sunsea_read(struct file *filp, char __user *buf, size_t count, loff_t *f_ops) { char rbuf[1] = {0}; int state; state = readl(UART_UTRSTAT1); if((0x01 & state) == 1) { rbuf[0] = readb(UART_URXH1); copy_to_user(buf, rbuf, 1); } else { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(10); } return 0; } int sunsea_release(struct inode *inode, struct file *filp) { return 0; } struct file_operations ttyS0_fops = { .owner = THIS_MODULE, .open = sunsea_open, .write = sunsea_write, .read = sunsea_read, .release = sunsea_release, }; int __init sunsea_init(void) { int rc; printk("s3c2440 serial module loaded!/n"); rc = register_chrdev(ttyS0_MAJOR, "ttyS0", &ttyS0_fops); if(rc < 0) { printk("Error: register ttyS0 device error!/n") ; return -1; } return 0; } void __exit sunsea_exit(void) { unregister_chrdev(ttyS0_MAJOR, "ttyS0"); printk("s3c2440 serial module exit!/n"); return; } module_init(sunsea_init); module_exit(sunsea_exit);
编译的时候报的错:
make -C /work/2440/source/system/linux-2.6.22.6 M=`pwd` modules make[1]: Entering directory `/work/2440/source/system/linux-2.6.22.6' CC [M] /work/filesystem/work/mycar_driver/UART/uart.o In file included from /work/filesystem/work/mycar_driver/UART/uart.c:6: /work/filesystem/work/mycar_driver/UART/regs-serial.h:51: error: syntax error before "upf_t" /work/filesystem/work/mycar_driver/UART/regs-serial.h:51: warning: no semicolon at end of struct or union /work/filesystem/work/mycar_driver/UART/regs-serial.h:58: error: syntax error before '}' token /work/filesystem/work/mycar_driver/UART/uart.c:40:26: warning: multi-character character constant /work/filesystem/work/mycar_driver/UART/uart.c: In function `sunsea_write': /work/filesystem/work/mycar_driver/UART/uart.c:40: warning: comparison is always true due to limited range of data type /work/filesystem/work/mycar_driver/UART/uart.c:39: warning: ignoring return value of `copy_from_user', declared with attribute warn_unused_result /work/filesystem/work/mycar_driver/UART/uart.c: In function `sunsea_read': /work/filesystem/work/mycar_driver/UART/uart.c:60: warning: ignoring return value of `copy_to_user', declared with attribute warn_unused_result make[2]: *** [/work/filesystem/work/mycar_driver/UART/uart.o] Error 1 make[1]: *** [_module_/work/filesystem/work/mycar_driver/UART] Error 2 make[1]: Leaving directory `/work/2440/source/system/linux-2.6.22.6' make: *** [all] Error 2
regs-serial.h : 51行的代码
struct s3c2410_uartcfg { 48 unsigned char hwport; /* hardware port number */ 49 unsigned char unused; 50 unsigned short flags; 51 upf_t uart_flags; /* default uart flags */ 52 unsigned long ucon; /* value of ucon for port */ 53 unsigned long ulcon; /* value of ulcon for port */ 54 unsigned long ufcon; /* value of ufcon for port */ 55 56 struct s3c24xx_uart_clksrc *clocks; 57 unsigned int clocks_size; 58 };
// upf_t 的来源
typedef unsigned int upf_t; /* cannot include linux/serial_core.h */
我把51 行改成unsigned int uart_flags; 编译时可以通过的,插入内核之后,运行应用层程序,但是连接了串口接上蓝牙后一直不停的喷乱码, 不知到是不是修改了upf_t 的问题还是驱动源码的问题。请大神们指点指点。