摘要:介绍了uclinux 操作系统的内核结构以及设备驱动编程的基本原理,并对CAN 总线的嵌入式系统进行了硬件设计及软件驱动编程,提出CAN 总线技术应用于嵌入式系统的一种方案。

1 引言
    早期应用于八位单片机软件设计的嵌入式系统主要为前后台系统(或超循环系统),程序大约在几千行以内,由两部分组成,即其应用程序是一个无限的循环,循环中调用函数完成相应的操作,属于后台行为;其中断服务程序处理异步事件,属于前台行为.随着嵌入式系统功能越来越庞杂,如友好的人机界面、网络化、远程监控等.各种任务的优先级不同,传统的设计方法无法完成,程序长达数万行,程序员必须同繁琐的底层硬件打交道,这样效率低下.现代电子技术的发展为嵌入式微处理器提供了更多的外设,通用的如串口、并口、以太网口、现场总线、USB口等.基于免费自由软件Linux发展而来的嵌入式系统uclinux,是一种免费的嵌入式操作系统.uclinux系统具有内核小、效率高、源码开放、性能稳定、大量的开发工具、良好的开发环境等特点,并且各种应用程序丰富,是进行嵌入式系统开发的最优秀工具之一.

2 uclinux操作系统简介
    uclinux 系统主要由用户进程、系统调用接口、uclinux 内核、硬件控制器等四部分组成.用户进程是用户根据自己的设计和功能要求开发的应用程序,通过调用系统的功能函数来实现系统功能;系统调用接口通过系统调用实现用户与系统内核的接口,这些调用和服务也可以看成是系统内核的一部分;uclinux 内核是操作系统的灵魂,它抽象了许多硬件细节,将所有的硬件抽象成统一的虚拟接口,使程序可以以一种统一的方式进行数据处理,它主要包括基于优先级的进程调度、内存管理、文件系统、网络接口、进程间通讯等五部分;硬件控制器则包含了系统需要的所有可能的物理设备.以上四个部分之间的每个子系统都只能跟邻近的系统进行通信。
    uclinux 的设备管理系统是嵌入式操作系统的重要组成部分,它可以分为:下层、与设备相关的,即所谓的设备驱动程序,直接与相应的设备打交道,并向上提供一组访问接口;以及上层、与设备无关,根据输入输出请求,通过特定设备驱动提供的接口,与设备进行通信.如通用的串口、网卡等驱动程序在uclinux 中都可以找到.

3 uclinux驱动编程原理
    uclinux嵌入式系统不能象Linux一样动态加载驱动程序模块,而只能同内核一起编译,与应用程序、其他驱动程序一起固化到可擦写的Flash上,驱动程序长驻内存,是静态驱动程序.uclinux系统根据设备性质的不同,将设备分为四种类型:字符设备(char)、块设备(block)、网络接口( net )和其他设备驱动程序模块.在下载的uclinux源代码包中,可以在uclinux/linux/drivers目录下面看到通用设备如char,block, net, cdrom, scsi, sound等.系统对于每个设备都对应一个主设备号和一个次设备号,不同的设备可以对应相同的主设备号,应用程序访问设备通过不同的次设备号来识别和区别设备.在Linux系统/dev目录下通过输入ls -l命令可以查到系统已注册的设备,因此编写新的驱动程序时必须向系统注册
该设备.在uclinux系统中,通过register_chrdev函数实现注册.
    uclinux系统将所有硬件抽象成虚拟的文件系统,所有的字符设备、块设备都支持文件操作接口,因此可以对这种虚拟的设备文件系统进行文件操作.通常对设备文件进行的操作有open、read、write、release等,即打开、读、写、释放文件.每一个设备驱动程序实质上是用来完成特定任务的一组函数集. 驱动程序拥有一个称为fileoperation 的数据结构,其中包含指向驱动程序内部大多数函数的指针.引导系统时,内核调用每一个驱动程序的初始化函数,将驱动程序的主设备号以及程序内部的函数地址结构的指针传输给内核.这样,内核就能通过设备驱动程序的主设备号索引访问驱动程序内部的子程序,完成打开、读、写等操作.程序员经常面临的一项工作就是为系统的新设备编写驱动程序.
    在现代控制系统中,为了便于数据通讯,在底层常采用现场总线,目前CAN总线广泛应用于过程工业、机械工业、纺织机械、农用机械、机器人、数控机床、医疗器械及传感器等领域,下面介绍CAN总线应用于嵌入式系统的驱动编程.

4 CAN 总线的性能特点
    CAN(Controller Area Network)即控制器局域网络.CAN 总线目前已形成国际标准 version2.0.该技术规范包括A 和B 两部分.2.0A 给出了CAN 报文标准格式,而2.0B 给了出厂标准和扩展两种格式.CAN 总线是应用最广泛的现场总线之一,CAN为多主方式工作,网络上任一节点均可在任意时刻主动地向网络上其他节点发送信息,而不分主从,通信方式灵活,且无需站地址等节点信息;CAN 网络上的节点信息分成不同的优先级,可满足不同的实时要求;CAN 采用非破坏性总线仲裁技术,当多个节点同时向总线发送信息时,优先级较低的节点会主动地退出发送,而最高优先级的节点可不受影响地继续传输数据;CAN 只需通过报文滤波即可实现点对点、一点对多点及全局广播等几种方式传送接收数据,无需专门的“调度”,CAN 的直接通信距离最远可达10km(速率5kbps 以下);通信速率最高可达1Mbps(此时通信距离最长为40m).CAN 上的节点数主要取决于总线驱动电路,目前可达110个;采用短帧结构,传输时间短,受干扰概率低,具有极好的检错效果;CAN 的通信介质可为双绞线、同轴电缆或光纤等.CAN 总线的数据通信具有突出的可靠性、实时性和灵活性.

5 CAN总线的嵌入式系统硬件设计
    本设计选用Samsung公司的S3C4510B作为嵌入式系统的微处理器芯片,该处理器是16/32位RISC微处理控制器,内含由ARM公司设计的16/32位ARM7TDMI RISC处理器核,适用于价格及功耗敏感的场合.除内核外,该微处理器的片内外围功能模块包括:2个带缓冲描述符的HDLC通道;2个UART通道;2个GDMA通道;2个32位定时器及可编程I/O口.CAN控制器选用philips公司的SJA1000,该芯片与PCA82C200电气兼容,带64字节先进先出(FIFO)堆栈,兼容协议CAN2.0B,支持11位和29位识别码,位速率可达1Mbps,24MHZ时钟频率,芯片内含寄
存器,可由用户配置CAN总线波特率,设置验收屏蔽标识码,可配置系统为PeliCAN 模式或BasicCAN模式,出错告警等.
    该系统采用82C250作为收发器,其硬件连线如图(1)所示.AD0~AD7与S3C4510B的p0~p7连线,/cs接p12,ALE接p13,/RD接p14,/wr接p15,/int接XINTREQ0.
 
图1 SJA1000硬件连线

6 驱动软件设计
 
图2 CAN总线初始化框图
    本设计中,CAN总线驱动程序是作为一个模块放在linux/deriver/char/文件夹里面,软件流程如图(2)所示,其设计详细介绍如下.
模块首先对引用的库函数进行申明,并且定义:
#define IOPMOD (*(volatile unsigned *)0x3ff5000)
#define IOPDATA (*(volatile unsigned *)0x3ff5008)
#define IOPCON (*(volatile unsigned *)0x3ff5004)
#define EXTDBWTH(*(volatile unsigned *)0x3ff5
#define SYSCFG(*(volatile unsigned *)0x
主要有以下几个模块:
void can_init(void)
{
SYSCFG =SYSCFG & 0x0fffffffd;
EXTDBWTH =EXTDBWTH& 0x00ff0ff;
IOPMOD=0xf0ff;
IOPDATA=0x6000; 寄存器地址0,MOD寄存器
IOPDATA= IO_PDATA&0xdfff; ALE=0 配置MOD寄存器
IOPDATA= IO_PDATA|0x3f; ; 复位模式、使能
IOPDATA=0x6006; ;寄存器地址6,总线定时器0寄存器
IOPDATA=IO_PDATA&0xdfff; ALE=0配置寄存器
IOPDATA= IO_PDATA|0x3f; 跳转宽度、波特率设置
……;配置总线定时器1、验收代码寄存器等
IOPDATA=0x6000; SJA1000 寄存器地址0,MOD寄存器
IOPDATA=IO_PDATA&0xdfff; ALE=0配置MOD寄存器
IOPDATA= IO_PDATA&0xfe;写复位位,进入工作模式
result = register_chrdev(254,"can",&can_fops);申请主设备号
if (result<0) {
printk(KERN_WARNING "CAN:can’t getmajor ", result);
return result;
}
在该驱动程序中,定义结构变量can_fops为应用程序访问内核的接口:
static struct file_operations can_fops = {
read: can_read,
write: can_write,
open: can_open,
release: can_release,
};
static int can_release(struct inode *inode, struct file *file)
{
MOD_DEC_USE_COUNT; ;用户减计数
Return 0;
}
static int can_open(struct inode *inode,struct file *file)
{
Scull_Dev *dev;
Int num = NUM(inode->i_rdev); 设备号
Int type = TYPE(inode->i_rdev); 设备类型
If (num>=scull_nr_devs) return -ENODEV;
dev = &scull_devices[num];
flip->private_data = dev;
MOD_INC_USE_COUNT; 用户数人工计数
IOPCON=0x16; //xIRQ0
disable_irq(INT_can);
if(request_irq(INT_can, &can_rx,
SA_INTERRUPT, "can rx isr","can")) {
printk("s3c4510-can: Can't get irq %d\n",
INT_sja1000);
return -EAGAIN;
}
printk("can has get irq 0\n");
enable_irq(INT_can);
…… ; 配置SJA1000内部中断及屏蔽寄存器
return 0;
}

7 结束语
    本文介绍了CAN总线在嵌入式系统中的驱动编程,对CAN总线技术在嵌入式系统中的应用进行了探索.本设计已在通信用逆变电源远程监控系统中应用.

CAN 总线嵌入式驱动编程相关推荐

  1. 基于uclinux 的CAN 总线嵌入式驱动编程

    1 引言 早期应用于八位单片机软件设计的嵌入式系统主要为前后台系统(或超循环系统),程序大约在几千行以内,由两部分组成,即其应用程序是一个无限的循环,循环中调用函数完成相应的操作,属于后台行为:其中断 ...

  2. 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  3. 【嵌入式Linux】嵌入式Linux驱动开发基础知识之总线设备驱动模型

    文章目录 前言 1.驱动编写的三种方法 1.1.传统写法 1.2.总线驱动模型 1.3.设备树驱动模型 2.Linux实现分离:Bus/Dev/Drv模型 2.1.Bus/Dev/Drv模型 2.2. ...

  4. 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】PowerPC + Linux2.6.25平台下的I2C驱动架构分析

    PowerPC + Linux2.6.25平台下的I2C驱动架构分析 Sailor_forever  sailing_9806#163.com (本原创文章发表于Sailor_forever 的个人b ...

  5. 【嵌入式Linux学习七步曲之第五篇 Linux内核及驱动编程】PowerPC + Linux2.6.25平台下的SPI驱动架构分析

    PowerPC + Linux2.6.25平台下的SPI驱动架构分析 Sailor_forever  sailing_9806#163.com (本原创文章发表于Sailor_forever 的个人b ...

  6. cfnet用于嵌入式_做嵌入式驱动的,你一定要挺住!

    搞嵌入式驱动开发一年多了,项目做的不少: 从网络驱动到CAN驱动.从Dataflash驱动到NAND/NOR FLASH驱动.从CF/IDE驱动到各种嵌入式文件系统.从LCD/VGA驱动到音频驱动.从 ...

  7. Linux总线设备驱动框架的理解(非常棒的文章!)

    以下内容源于微信公众号:嵌入式企鹅圈.有格式内容上的修改,如有侵权,请告知删除. Linux的设备驱动框架,即某类设备对应的驱动的框架. 这里是"Linux总线设备驱动框架",应该 ...

  8. 从入门到精通ARM(4412)-Linux内核驱动编程【下】-李志勇-专题视频课程

    从入门到精通ARM(4412)-Linux内核驱动编程[下]-247人已学习 课程介绍         嵌入式绝对是当前IT领域最炙手可热的话题了.其主要应用领域涵盖与人类相关的各行各业: * 消费电 ...

  9. ARM Cortex-M3M4 处理器上的嵌入式系统编程

    ARM Cortex-M3/M4 处理器上的嵌入式系统编程 在基于 ARM Cortex M 处理器的微控制器上使用 C 编程和汇编进行动手编码 课程英文名:Embedded Systems Prog ...

最新文章

  1. 争自动驾驶领头羊还是确保技术安全?欧美选择不同
  2. iOS—如何申请苹果公司开发者账号流程详细图文介绍(包括邓白氏编码的申请方法详细介绍)...
  3. Android调用浏览器打开网址遇到的问题
  4. 分享一个android debug模式,出现 waiting for debugger把界面卡住,取巧的解决办法
  5. pycharm如何修改默认浏览器?修改成chrome
  6. python所有变量更新_PYTHON:使用python变量更新MULTIPLE COLUMNS
  7. 输入十个数,输出其中最大数、下标,用函数实现
  8. html怎么设置子目录,如何让主域名指向public_html下的子目录
  9. java项目功能详情介绍,JAVAEE—spring的详细介绍
  10. 如何导出已安装的安卓app为apk包
  11. element ui 弹出组件的遮罩层在弹出层的上面的解决方法
  12. kotlin android中文文档,Android studio 生成带Kotlin文档的实现方式
  13. Python3安装Crypto模块
  14. 《软件工程导论》之总体设计
  15. 双网卡服务器实现内外网访问
  16. 国际电话登机英文术语
  17. 计算机设置了密码后不能打印了,为什么电脑设置了开机密码后就不能打印了
  18. mysql典型安装和完全安装的区别_MySQL安装详解(安装版本mysql-5.5.25)
  19. jQuery 加入购物车 弹窗
  20. halcon图像灰度操作

热门文章

  1. java list排序工具类_java 之 Collections集合工具类排序
  2. Zookeeper集群搭建(涵盖命令详解)与Error contacting service. It is probably not running的问题解决
  3. linux 日志报告生成器,Linux报告生成器工具awk
  4. tomcat 9 无法启动_运维常见问题汇总tomcat篇
  5. plantuml 方法图_UML与软件建模:第四次作业(学习PlantUML活动图绘制方法)
  6. 如何设置ftp服务器上传文件夹至不同路径,设置ftp服务器上传文件夹
  7. java逆向框架,Android逆向之逆向框架层
  8. 1×pbs缓冲液配方_【应用】蒸渗仪与氧化还原电位的测量1
  9. oracle插入CLOB类型超过4000个字符报ORA-01704错的解决方法及其它相关场景解决方案...
  10. 昂贵的聘礼(枚举区间+最短路)