首页 新闻 会员 周边 捐助

S3C2440 UART1可用的驱动代码

0
悬赏园豆:5 [已关闭问题] 关闭于 2016-11-21 16:58

  大神们有没有可以使用的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 的问题还是驱动源码的问题。请大神们指点指点。

Linux-杠杆的主页 Linux-杠杆 | 初学一级 | 园豆:197
提问于:2016-11-07 07:58
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册