当前位置: 技术问答>linux和unix
RS232串口驱动的一些问题,请各位执教
来源: 互联网 发布时间:2015-11-18
本文导语: 最近,要写一个linux下的RS232驱动程序,想在驱动程序一级实现异步IO。 但是我遇到了一些问题(我从来没有在linux下写程序,更不用说驱动了) 一:系统已经有了RS232串口的驱动。机器重新启动以后,硬件的端口地址...
最近,要写一个linux下的RS232驱动程序,想在驱动程序一级实现异步IO。
但是我遇到了一些问题(我从来没有在linux下写程序,更不用说驱动了)
一:系统已经有了RS232串口的驱动。机器重新启动以后,硬件的端口地址仍然不会改变对吧?
二:我怎么知道我的硬件(比如RS232)的的端口地址呢?
三:如果我要写一个RS232,如果硬件忙,我放到一个缓冲里面,我怎么保重硬件空闲的时候从缓冲
中取出数据进行实际意义上的写出呢?
走过路过,不要错过。
各位请多多赐教,讲得无论多少都是对我的帮助,谢谢了!再谢谢!
但是我遇到了一些问题(我从来没有在linux下写程序,更不用说驱动了)
一:系统已经有了RS232串口的驱动。机器重新启动以后,硬件的端口地址仍然不会改变对吧?
二:我怎么知道我的硬件(比如RS232)的的端口地址呢?
三:如果我要写一个RS232,如果硬件忙,我放到一个缓冲里面,我怎么保重硬件空闲的时候从缓冲
中取出数据进行实际意义上的写出呢?
走过路过,不要错过。
各位请多多赐教,讲得无论多少都是对我的帮助,谢谢了!再谢谢!
|
概括一下:
驱动是自己约定的,比如内核自行约定次设备号0就是COM1,1就是COM2,那么内核就可以区分自己到底是操作哪一个IO!!!!
应用层就需要遵守这种约定,但为了简化操作,应用层在使用设备时,直接操作文件就可以了,这就需要将文件与设备关联起来,这就是设备文件的概念,需要用到mknod命令,这个命令在使用时需要遵守你内核中的约定,这样就将应用层与驱动程统一起来了!!!!!
驱动程序不管每个引脚的电平特征,直接往它上面读写就可以了么?
在PC机上的驱动程序基本上需要两个函数来操作设备,outb,inb,用于向设备的指定端口读写数据,具体的电平特征,在调试的时候可能会汲及到,比如你用示波器来看某个IO脚到底输出了数据没有!!!
如果串口被焊下来了!
我怎么探测它不见了?用什么特征(电气特征?或者用系统的某种数据结构?)可以探测到它的存在/消失?
对于一个键壮的驱动程序,有时需要在设备初始化例程中探测相应的设备是否存在,原理很简单,就是通过改写外围硬件一个寄存器,再去观察另一个会受影响的寄存器,看它是否是你想要的结果,这跟具体的硬件相关,需要结合具体硬件的芯片资料,当然,你也完全不用去判断这个硬件是否存在
驱动是自己约定的,比如内核自行约定次设备号0就是COM1,1就是COM2,那么内核就可以区分自己到底是操作哪一个IO!!!!
应用层就需要遵守这种约定,但为了简化操作,应用层在使用设备时,直接操作文件就可以了,这就需要将文件与设备关联起来,这就是设备文件的概念,需要用到mknod命令,这个命令在使用时需要遵守你内核中的约定,这样就将应用层与驱动程统一起来了!!!!!
驱动程序不管每个引脚的电平特征,直接往它上面读写就可以了么?
在PC机上的驱动程序基本上需要两个函数来操作设备,outb,inb,用于向设备的指定端口读写数据,具体的电平特征,在调试的时候可能会汲及到,比如你用示波器来看某个IO脚到底输出了数据没有!!!
如果串口被焊下来了!
我怎么探测它不见了?用什么特征(电气特征?或者用系统的某种数据结构?)可以探测到它的存在/消失?
对于一个键壮的驱动程序,有时需要在设备初始化例程中探测相应的设备是否存在,原理很简单,就是通过改写外围硬件一个寄存器,再去观察另一个会受影响的寄存器,看它是否是你想要的结果,这跟具体的硬件相关,需要结合具体硬件的芯片资料,当然,你也完全不用去判断这个硬件是否存在
|
第一次看到居然还给出99分的!!!!!!
1.如果你的串口是PC机上的标准串口,其地址是固定的,如果是PCI卡上的扩展串口,就不一定了
2.PC上的标准串口的地址是固定的,COM1的串口基地址就是0x3f8
3.那是你驱动做的事情,用户层可以不管!!!具体实现在LINUX设备驱动程序一书中有说明,你PC机上的串口驱动程序本身就支持异步方式,你需要用异步IO的方式对设备进行读写就行了,用不着去实现一个驱动,并且系统已经自带了这样的驱动,你是无法再为此写另一个驱动的,这涉及到设备是否独占的问题,默认情况下,串口设备是被独占的
1.如果你的串口是PC机上的标准串口,其地址是固定的,如果是PCI卡上的扩展串口,就不一定了
2.PC上的标准串口的地址是固定的,COM1的串口基地址就是0x3f8
3.那是你驱动做的事情,用户层可以不管!!!具体实现在LINUX设备驱动程序一书中有说明,你PC机上的串口驱动程序本身就支持异步方式,你需要用异步IO的方式对设备进行读写就行了,用不着去实现一个驱动,并且系统已经自带了这样的驱动,你是无法再为此写另一个驱动的,这涉及到设备是否独占的问题,默认情况下,串口设备是被独占的
|
给你代码,你自己参考一下,
////////////////////////Linux 驱动测试调试////////////////////////
#include
#include
#include
#include
#include
#include
#include
#define DP_MAJOR 50
#define DP_MINOR 0
static int char_read(struct file *filp,char __user *buffer,size_t,loff_t *);
static int char_open(struct inode *,struct file *);
static int char_write(struct file *filp,const char __user *buffer,size_t ,loff_t*);
static int char_release(struct inode *,struct file *);
static char *arr,*p;
static int chropen;
struct cdev *my_cdev;
static int len;
struct file_operations Fops = {
.read = char_read,
.write = char_write,
.open = char_open,
.release = char_release, /* a.k.a. close */
};
static int irq=4;
static char *interface="test";
/*
MODULE_PARM(interface, "s");
MODULE_PARM_DESC(interface, "A network interface");
MODULE_PARM(irq, "i");
MODULE_PARM_DESC(irq, "The IRQ of the network interface");
*/
static irqreturn_t myinterrupt(int irq, void *dev_id, struct pt_regs *regs)
{
static int mycount = 0;
if (mycount pid);
if(my_cdev==NULL){
return -1;
}
if(register_chrdev_region(dev,10,interface)ops = &Fops;
cdev_init(my_cdev,&Fops);
cdev_add(my_cdev,dev,1);
return 0;
}
static int char_open(struct inode *inode,struct file *file)
{
if(chropen==0)
chropen++;
else{
printk(KERN_ALERT"Another process open the char devicen");
return -1;
}
p=arr;
try_module_get(THIS_MODULE);
return 0;
}
static int char_release(struct inode *inode,struct file *file)
{
chropen--;
module_put(THIS_MODULE);
return 0;
}
static int char_read(struct file *filp,char __user *buffer,size_t length,loff_t *offset)
{
int i=0;
if(*p=='')
return 0;
while(length&&*p){
put_user(*(p++),buffer++);
length--;
i++;
}
return i;
}
static int char_write(struct file *filp,const char __user *buffer,size_t length,loff_t *offset)
{
int i;
for(i=0;i
////////////////////////Linux 驱动测试调试////////////////////////
#include
#include
#include
#include
#include
#include
#include
#define DP_MAJOR 50
#define DP_MINOR 0
static int char_read(struct file *filp,char __user *buffer,size_t,loff_t *);
static int char_open(struct inode *,struct file *);
static int char_write(struct file *filp,const char __user *buffer,size_t ,loff_t*);
static int char_release(struct inode *,struct file *);
static char *arr,*p;
static int chropen;
struct cdev *my_cdev;
static int len;
struct file_operations Fops = {
.read = char_read,
.write = char_write,
.open = char_open,
.release = char_release, /* a.k.a. close */
};
static int irq=4;
static char *interface="test";
/*
MODULE_PARM(interface, "s");
MODULE_PARM_DESC(interface, "A network interface");
MODULE_PARM(irq, "i");
MODULE_PARM_DESC(irq, "The IRQ of the network interface");
*/
static irqreturn_t myinterrupt(int irq, void *dev_id, struct pt_regs *regs)
{
static int mycount = 0;
if (mycount pid);
if(my_cdev==NULL){
return -1;
}
if(register_chrdev_region(dev,10,interface)ops = &Fops;
cdev_init(my_cdev,&Fops);
cdev_add(my_cdev,dev,1);
return 0;
}
static int char_open(struct inode *inode,struct file *file)
{
if(chropen==0)
chropen++;
else{
printk(KERN_ALERT"Another process open the char devicen");
return -1;
}
p=arr;
try_module_get(THIS_MODULE);
return 0;
}
static int char_release(struct inode *inode,struct file *file)
{
chropen--;
module_put(THIS_MODULE);
return 0;
}
static int char_read(struct file *filp,char __user *buffer,size_t length,loff_t *offset)
{
int i=0;
if(*p=='')
return 0;
while(length&&*p){
put_user(*(p++),buffer++);
length--;
i++;
}
return i;
}
static int char_write(struct file *filp,const char __user *buffer,size_t length,loff_t *offset)
{
int i;
for(i=0;i