主题 : s3c2440编写串口驱动中的一些问题请教 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 3173
精华: 0
发帖: 11
金钱: 65 两
威望: 19 点
综合积分: 22 分
注册时间: 2008-12-30
最后登录: 2010-11-12
楼主  发表于: 2010-11-07 14:24

 s3c2440编写串口驱动中的一些问题请教

linux arm9的串口tty设备驱动看的还可以,不过我想自己用杂项设备形式给串口写个驱动,驱动的目标是能发送一个字节数据,硬件上RXD、TXD短接达到自发自收。不过我驱动写的还不熟所以一些错误还不清楚怎么修改,希望您能耐心看完,代码如下
#include <linux/errno.h>
//#include <linux/kernel.h>
//#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <plat/regs-serial.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>


static void __iomem * base_addr;

#define rGPHCON        (*(volatile unsigned *)0x56000070)      //Port H control
#define rGPHUP         (*(volatile unsigned *)0x56000078)       //Pull-up control H

#define rULCON0        (*(volatile unsigned long *)(base_addr+S3C2410_ULCON))
#define rUCON0        (*(volatile unsigned long *)(base_addr+S3C2410_UCON))
#define rUFCON0        (*(volatile unsigned long *)(base_addr+S3C2410_UFCON))
#define rUMCON0        (*(volatile unsigned long *)(base_addr+S3C2410_UMCON))
#define rUTRSTAT0    (*(volatile unsigned long *)(base_addr+S3C2410_UTRSTAT))
#define rUERSTAT0    (*(volatile unsigned long *)(base_addr+S3C2410_UERSTAT))
#define rUFSTAT0    (*(volatile unsigned long *)(base_addr+S3C2410_UFSTAT))
#define rUMSTAT0    (*(volatile unsigned long *)(base_addr+S3C2410_UMSTAT))
#define rUTXH0        (*(volatile unsigned long *)(base_addr+S3C2410_UTXH))
#define rURXH0        (*(volatile unsigned long *)(base_addr+S3C2410_URXH))
#define rUBRDIV0    (*(volatile unsigned long *)(base_addr+S3C2410_UBRDIV))

#define BAUD_SET    115200                //设置波特率

#define DEVICE_NAME       "s3c_UART0_jyj"
#define DEVICE_MAJOR    125
#define DEVICE_MINOR    0

static int vSignReceOK;                    //串口接收标志
static wait_queue_head_t uartrece_wait;            //串口等待列表
static int uart0recedata;                //接收数据
struct semaphore uart0_lock;                //uart0互斥锁

static ssize_t S3C2440_uart0read (struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
    if(down_trylock(&uart0_lock))
    {
        wait_event_interruptible(uartrece_wait, vSignReceOK);
        //vSignReceOK = 0;
        copy_to_user(buffer,(char * )&uart0recedata,sizeof(uart0recedata));
        up(&uart0_lock);
    }
}

static ssize_t S3C2440_uart0write (struct file *filp, char *buffer, size_t count,loff_t *offset)
{
    while(!(rUTRSTAT0 & 0x04));    //等待,直到发送缓冲区中数据为空
    rUTXH0 = 1;            //想rUTXHO中写入数据,uart自动将它发送出去。
}

static ssize_t S3C2440_uart0open (struct inode *inode, struct file *filp)
{    init_waitqueue_head(&uartrece_wait);
    printk("UART0 opened");
    return 0;
}

static int S3C2440_UART_Release(struct inode *inode, struct file *filp)
{                 //暂缺
}

static int S3C2440_uart0ioctl(  struct inode *inode,
                struct file *file,
                 unsigned int cmd,
                unsigned long arg)
{    //暂缺;
}

static struct file_operations dev_fops = {        //文件指针
    .owner    = THIS_MODULE,
    .open   = S3C2440_uart0open,
    .read    = S3C2440_uart0read,
    .write    = S3C2440_uart0write,
    .release = S3C2440_UART_Release,
    .ioctl    = S3C2440_uart0ioctl,
};

static struct miscdevice misc = {
    .minor = DEVICE_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

/*串口中断接收数据*/
static irqreturn_t uart0reive_int_handler(int irq, void *dev_id)
{    while(!(rUTRSTAT0 & 0x01));            //等待,直到接收缓冲区中有数据
    uart0recedata = rURXH0;                //读取rURXH0中数据
    wake_up_interruptible(&uartrece_wait);
}

/*******************************************************************************
*** 函数功能:S3C2440 UART I/O config
*** 入口参数:
*** 出口参数:
*** 函数说明: I/O表
        GPH2~3 TXD0 RXD0
        GPH4~5 TXD1 RXD1
        GPH6~7 TXD2 RXD2
********************************************************************************/
void UARTIOPortConfig(void)
{    rGPHCON |= (0xa<<4);    //将GPH2~3端口设置为串口功能,且允许上拉!
    rGPHUP = 0x7ff;    
    
}

/*******************************************************************************
*** 函数功能:UART0初始化设置
*** 入口参数:
*** 出口参数:
********************************************************************************/
void Uart_Init()
{    UARTIOPortConfig();    //配置相关串口I/O
    rULCON0 = 0x3;        //8个控制位,无校验位,1个停止位。
    rUCON0 = 0x245;        //工作于查询模式,设置uart的时钟源。
    rUFCON0 = 0x0;        //不使用FIFO
    rUMCON0 = 0x0;        //不适用流控制
    rUBRDIV0 = 21;//这里我想的是自发自收,波特率暂不设置成某个值,只要能发就行
}

static int __init uart0_dev_init(void)
{    int ret;
    base_addr = ioremap(S3C2410_PA_UART0,S3C_UART_OFFSET);
    if(base_addr == NULL)
    {    printk(KERN_ERR "failed to remap register block\n");
        return -ENOENT;
    }    
    Uart_Init();

    ret = request_irq(IRQ_S3CUART_RX0, uart0reive_int_handler, IRQF_SHARED, DEVICE_NAME, 0);
    if(ret)
        goto ERR_reqint;

    ret = misc_register(&misc);
    if(ret)
        goto ERR_register;

ERR_reqint :
    printk(KERN_ERR "%s: request irq failed\n", __FILE__);
ERR_register :
    printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
    return ret;
}

static int __init uart0_dev_exit(void)
{    //暂缺;
}

module_init(uart0_dev_init);
module_exit(uart0_dev_exit);

MODULE_AUTHOR("yeqishi");
MODULE_DESCRIPTION("UART0 /dev entries driver");
MODULE_LICENSE("GPL");

/**************                内核编译出错信息如下:   ***************************/

[root@yeqishi linux-2.6.30.4]# make zImage
  CHK     include/linux/version.h
make[1]: “include/asm-arm/mach-types.h”是最新的。
  CHK     include/linux/utsrelease.h
  SYMLINK include/asm -> include/asm-arm
  CALL    scripts/checksyscalls.sh
<stdin>:1097:2: warning: #warning syscall fadvise64 not implemented
<stdin>:1265:2: warning: #warning syscall migrate_pages not implemented
<stdin>:1321:2: warning: #warning syscall pselect6 not implemented
<stdin>:1325:2: warning: #warning syscall ppoll not implemented
<stdin>:1365:2: warning: #warning syscall epoll_pwait not implemented
  CHK     include/linux/compile.h
  CC      drivers/char/uart.o
In file included from drivers/char/uart.c:13:
arch/arm/plat-s3c/include/plat/regs-serial.h:225: error: expected specifier-qualifier-list before 'upf_t'    //问题主要是这句
drivers/char/uart.c:86: warning: initialization from incompatible pointer type
drivers/char/uart.c:125: warning: function declaration isn't a prototype
drivers/char/uart.c:162: warning: initialization from incompatible pointer type
make[2]: *** [drivers/char/uart.o] 错误 1
make[1]: *** [drivers/char] 错误 2
make: *** [drivers] 错误 2

这些错误还不清楚怎么修改,如果您知道能指点一二吗,谢谢
[ 此帖被yeqishi在2010-11-07 20:28重新编辑 ]
级别: 新手上路
UID: 3173
精华: 0
发帖: 11
金钱: 65 两
威望: 19 点
综合积分: 22 分
注册时间: 2008-12-30
最后登录: 2010-11-12
1楼  发表于: 2010-11-07 21:42
希望即使和我一样不是很懂的也说说,有什么想法多提提,大家共同学习进步,呵呵
级别: 新手上路
UID: 3173
精华: 0
发帖: 11
金钱: 65 两
威望: 19 点
综合积分: 22 分
注册时间: 2008-12-30
最后登录: 2010-11-12
2楼  发表于: 2010-11-08 21:33
大家顶顶呀,现在还不能沉水呀,
while(1)
{           wait_answer();
}