文档库 最新最全的文档下载
当前位置:文档库 › msp430mlx90614驱动

msp430mlx90614驱动

msp430mlx90614驱动
msp430mlx90614驱动

//------------------------IO bits Input-----------

#define P1Input(n) P1IN&n?1:0

#define P2Input(n) P2IN&n?1:0

#define P3Input(n) P3IN&n?1:0

#define P4Input(n) P4IN&n?1:0

#define P5Input(n) P5IN&n?1:0

#define P6Input(n) P6IN&n?1:0

//--------------------------------------------------------------------------------

#ifndef _MLX90614_H_

#define _MLX90614_H_

//-----------------------------------

#define SMBus_SDA BIT0

#define SMBus_SCL BIT1

//#define SDA_1 P2OUT |= SMBus_SDA

//#define SDA_0 P2OUT &=~ SMBus_SDA

#define SDA_1 P2DIR &= ~SMBus_SDA

#define SDA_0 P2DIR |= SMBus_SDA

#define SCL_1 P2OUT |= SMBus_SCL

#define SCL_0 P2OUT &= ~SMBus_SCL

#define mSDA_IN P2DIR &= ~SMBus_SDA

#define mSDA_OUT P2DIR |= SMBus_SDA

#define mSCL_OUT P2DIR |= SMBus_SCL

#define SDA_READ P2IN&SMBus_SDA

#define ACK 0

#define NACK 1

//MLX90614 constants

#define SA 0x00 // Slave address

#define DEFAULT_SA 0x5A // Default Slave address

#define RAM_Access 0x00 // RAM access command

#define EEPROM_Access 0x20 // EEPROM access command #define RAM_Tobj1 0x07 // To1 address in the eeprom

//*PROTOTYPES*******************************

void START_bit(void);

void STOP_bit(void);

unsigned char TX_byte(unsigned char Tx_buffer);

unsigned char RX_byte(unsigned char ack_nack);

void send_bit(unsigned char bit_out);

unsigned char Receive_bit(void);

void MLX90614_init(void);

unsigned int MemRead(unsigned char SlaveAddress,unsigned char command); void SendRequest(void);

void DummyCommand(unsigned char byte);

float CalcTemp(unsigned int value);

unsigned char PEC_calculation(unsigned char pec[]);

#endif

//----------------------------------------------------------------------

void SM_Wait(void)

{

_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();

_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();

_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();

_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();

}

void MLX90614_init(void)

{

mSDA_OUT; // Set SDA as Output

P2OUT &=~ SMBus_SDA;

mSCL_OUT;// Set SCL as Output

SCL_1;

SDA_1;

SendRequest();

}

void START_bit(void)

{

//mSDA_OUT;

SDA_1;SM_Wait();

SCL_1;SM_Wait();

SDA_0;SM_Wait();

SCL_0;SM_Wait();

}

void STOP_bit(void)

{ //mSDA_OUT;

SCL_0;SM_Wait(); // Wait a few microseconds

SDA_0;SM_Wait();

SCL_1;SM_Wait(); // Stop condition setup time(Tsu:sto=4.0us min) SDA_1;SM_Wait(); // Set SDA line

}

//--------------------------------------------------------------------------------------------- void send_bit(unsigned char bit_out)

{

//mSDA_OUT;

if(bit_out) SDA_1;

else SDA_0;

SM_Wait();

SCL_1;

SM_Wait();

SCL_0;

SM_Wait();

//return;

}//End of send_bit()

//--------------------------------------------------------------------------------------------- unsigned char TX_byte(unsigned char Tx_buffer)

{

unsigned char Bit_counter;

unsigned char Ack_bit;

unsigned char bit_out;

for(Bit_counter=8; Bit_counter; Bit_counter--)

{

if(Tx_buffer&0x80)

bit_out=1; // If the current bit of Tx_buffer is 1 set bit_out else

bit_out=0; // else clear bit_out

send_bit(bit_out); // Send the current bit on SDA

Tx_buffer<<=1; // Get next bit for checking }

SM_Wait();

Ack_bit=Receive_bit(); // Get acknowledgment bit

return Ack_bit;

}// End of TX_bite()

//--------------------------------------------------------------------------------------------- unsigned char Receive_bit(void)

{

unsigned char Ack_bit;

mSDA_IN; // SDA-input

_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();

SCL_1; // Set SCL line

SM_Wait(); // High Level of Clock Pulse

if(SDA_READ)

Ack_bit=1; // \ Read acknowledgment bit, save it in Ack_bit else

Ack_bit=0; // /

SCL_0; // Clear SCL line

SM_Wait(); // Low Level of Clock Pulse

return Ack_bit;

}//End of Receive_bit

unsigned char RX_byte(unsigned char ack_nack)

{

unsigned char RX_buffer;

unsigned char Bit_Counter;

for(Bit_Counter=8; Bit_Counter; Bit_Counter--)

{

if(Receive_bit()) // Get a bit from the SDA line

{

RX_buffer <<= 1; // If the bit is HIGH save 1 in RX_buffer

RX_buffer |=0x01;

}

else

{

RX_buffer <<= 1; // If the bit is LOW save 0 in RX_buffer

RX_buffer &=0xfe;

}

}

send_bit(ack_nack); // Sends acknowledgment bit

return RX_buffer;

}

//----------------------------------------------------------------------------------------------

unsigned int MemRead(unsigned char SlaveAddress,unsigned char command)

{

unsigned int data; // Data storage (DataH:DataL)

unsigned char Pec; // PEC byte storage

unsigned char DataL; // Low data byte storage

unsigned char DataH; // High data byte storage

unsigned char arr[6]; // Buffer for the sent bytes

unsigned char PecReg; // Calculated PEC byte storage

unsigned char ErrorCounter; // Defines the number of the attempts for communication with MLX90614

ErrorCounter=255; // Initialising of ErrorCounter

do{

repeat:

STOP_bit(); //If slave send NACK stop comunication

if(!ErrorCounter--){ //ErrorCounter=0?

break; //Yes,go out from do-while{}

}

START_bit(); //Start condition

if(TX_byte(SlaveAddress)){ //Send SlaveAddress

goto repeat; //Repeat comunication again

}

if(TX_byte(command)){ //Send command

goto repeat; //Repeat comunication again

}

START_bit(); //Repeated Start condition

if(TX_byte(SlaveAddress)){ //Send SlaveAddress

goto repeat; //Repeat comunication again

}

DataL=RX_byte(ACK); //Read low data,master must send ACK

DataH=RX_byte(ACK); //Read high data,master must send ACK

Pec=RX_byte(NACK); //Read PEC byte, master must send NACK

STOP_bit(); //Stop condition

arr[5]=SlaveAddress; //

arr[4]=command; //

arr[3]=SlaveAddress; //Load array arr

arr[2]=DataL; //

arr[1]=DataH; //

arr[0]=0; //

PecReg=PEC_calculation(arr);//Calculate CRC

}while(PecReg != Pec); //If received and calculated CRC are equal go out from do-while{}

*((unsigned char *)(&data))=DataL; //

*((unsigned char *)(&data)+1)=DataH ; //data=DataH:DataL

return data;

}

//---------------------------------------------------------------------------------------------

void SendRequest(void)

{

SCL_0; //SCL 1 ____________|<-----80ms------->|______________

delay(2000); // 0 |__________________|

SCL_1;

_NOP();_NOP();_NOP();

}

//---------------------------------------------------------------------------------------------

void DummyCommand(unsigned char byte)

{

START_bit(); //Start condition

TX_byte(byte); //Send Slave Address or whatever,no need ACK checking STOP_bit(); //Stop condition

}

//---------------------------------------------------------------------------------------------

float CalcTemp(unsigned int value)

{

float temp;

temp=(value*0.02)-273.15;

return temp;

}

unsigned char PEC_calculation(unsigned char pec[])

{

unsigned char crc[6];

unsigned char BitPosition=47;

unsigned char shift;

unsigned char i;

unsigned char j;

unsigned char temp;

do{

crc[5]=0; /* Load CRC value 0x000000000107 */

crc[4]=0;

crc[3]=0;

crc[2]=0;

crc[1]=0x01;

crc[0]=0x07;

BitPosition=47; /* Set maximum bit position at 47 */

shift=0;

//Find first 1 in the transmited message

i=5; /* Set highest index */

j=0;

while((pec[i]&(0x80>>j))==0 && i>0){

BitPosition--;

if(j<7){

j++;

}

else{

j=0x00;

i--;

}

}/*End of while */

shift=BitPosition-8; /*Get shift value for crc value*/

//Shift crc value

while(shift){

for(i=5; i<0xFF; i--){

if((crc[i-1]&0x80) && (i>0)){

temp=1;

}

else{

temp=0;

}

crc[i]<<=1;

crc[i]+=temp;

}/*End of for*/

shift--;

}/*End of while*/

//Exclusive OR between pec and crc

for(i=0; i<=5; i++){

pec[i] ^=crc[i];

}/*End of for*/

}while(BitPosition>8);/*End of do-while*/

return pec[0];

}/*End of PEC_calculation*/

//-----------------------------------------------------

read()

{

MLX90615_init();

SlaveAddress=DEFAULT_SA<<1; //Set device address

command=RAM_Access|RAM_Tobj1; //Form RAM access command + RAM address

data=MemRead(SlaveAddress,command);

t_mb=CalcTemp(data); //Calculate temperature

}

字符设备基础

Linux 字符设备基础 字符设备驱动程序在系统中的位置 操作系统内核需要访问两类主要设备,简单的字符设备,如打印机,键盘等;块设备,如软盘、硬盘等。与此对应,有两类设备驱动程序。分别称为字符设备驱动程序和块设备驱动程序。两者的主要差异是:与字符设备有关的系统调用几乎直接和驱动程序的内部功能结合在一起。而读写块设备则主要和快速缓冲存储区打交道。只有需要完成实际的输入/输出时,才用到块设备驱动程序。见下图: Linux 设备驱动程序的主要功能有: ● 对设备进行初始化; ● 使设备投入运行和退出服务; ● 从设备接收数据并将它们送到内核; ● 将数据从内核送到设备; ● 检测和处理设备出现的错误。 当引导系统时,内核调用每一个驱动程序的初始化函数。它的任务之一是将这一设备驱动程序使用的主设备号通知内核。同时,初始化函数还将驱动程序中的函数地址结构的指针送给内核。 内核中有两X 表。一X 表用于字符设备驱动程序,另一X 用于块设备驱动程序。这两X 表用来保存指向file_operations 结构的指针, 设备驱动程序内部的函数地址就保

存在这一结构中。内核用主设备号作为索引访问file_operations结构,因而能访问驱动程序内的子程序。 从开机到驱动程序的载入 系统启动过程中可能出现几种不同的方式检测设备硬件。首先机器硬件启动时BIOS会检测一部分必要的设备,如内存、显示器、键盘和硬盘等等。机器会把检测到的信息存放在特定的位置,如CMOS数据区。而另外某些设备会由设备驱动程序进行检测。 1 开机 2 引导部分(linux/config.h,arch/i386/boot/bootsect.S) 3 实模式下的系统初始化(arch/i386/boot/setup.S) 4 保护模式下的核心初始化 5 启动核心(init/main.c) init函数中函数调用关系如下: main.c init() filesystems.c sys_setup() genhd.c device_setup() mem.c chr_dev_init() 至此,驱动程序驻入内存。 设备驱动程序基本数据结构: struct device_struct 系统启动过程中要登记的块设备和字符设备管理表的定义在文件fs/devices.c中:struct device_struct { const char * name; struct file_operations * fops; }; static struct device_struct chrdevs[MAX_CHRDEV]; static struct device_struct blkdevs[MAX_BLKDEV]; 其实块设备表和字符设备表使用了相同的数据结构。在某些系统中,这些设备表也称作设备开关表,不同的是它们直接定义了一组函数指针进行对设备的管理。而这里系统用文件操作(file_operations)代替了那组开关。文件操作是文件系统与设备驱动程序之间的接口,系统特殊文件在建立的时候并没有把两者对应起来,只是把设备的缺省文件结构和i节点结构赋给设备文件,而真正的对应定义在系统启动之后,当设备被打开时时才进行的。 操作blkdev_open和chrdev_open定义在文件devices.c中,它们的基本功能是当设备文件初次打开时,根据该文件的i节点信息找到设备真正的文件操作接口,然后更新原来的设

字符设备驱动程序课程设计报告

中南大学 字符设备驱动程序 课程设计报告 姓名:王学彬 专业班级:信安1002班 学号:0909103108 课程:操作系统安全课程设计 指导老师:张士庚 一、课程设计目的 1.了解Linux字符设备驱动程序的结构; 2.掌握Linux字符设备驱动程序常用结构体和操作函数的使用方法; 3.初步掌握Linux字符设备驱动程序的编写方法及过程; 4.掌握Linux字符设备驱动程序的加载方法及测试方法。 二、课程设计内容 5.设计Windows XP或者Linux操作系统下的设备驱动程序; 6.掌握虚拟字符设备的设计方法和测试方法;

7.编写测试应用程序,测试对该设备的读写等操作。 三、需求分析 3.1驱动程序介绍 驱动程序负责将应用程序如读、写等操作正确无误的传递给相关的硬件,并使硬件能够做出正确反应的代码。驱动程序像一个黑盒子,它隐藏了硬件的工作细节,应用程序只需要通过一组标准化的接口实现对硬件的操作。 3.2 Linux设备驱动程序分类 Linux设备驱动程序在Linux的内核源代码中占有很大的比例,源代码的长度日益增加,主要是驱动程序的增加。虽然Linux内核的不断升级,但驱动程序的结构还是相对稳定。 Linux系统的设备分为字符设备(char device),块设备(block device)和网络设备(network device)三种。字符设备是指在存取时没有缓存的设备,而块设备的读写都有缓存来支持,并且块设备必须能够随机存取(random access)。典型的字符设备包括鼠标,键盘,串行口等。块设备主要包括硬盘软盘设备,CD-ROM等。 网络设备在Linux里做专门的处理。Linux的网络系统主要是基于BSD unix的socket 机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据传递。系统有支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。 3.3驱动程序的结构 驱动程序的结构如图3.1所示,应用程序经过系统调用,进入核心层,内核要控制硬件需要通过驱动程序实现,驱动程序相当于内核与硬件之间的“系统调用”。

带拖车的轮式移动机器人系统的建模与仿真

系统仿真学报 JOURNAL OF SYSTEM SIMULATION 2000 Vol.12 No.1 P.43-46 带拖车的轮式移动机器人系统的建模与仿真 杨凯 黄亚楼 徐国华 摘 要: 带拖车的轮式移动机器人系统是一种典型的非完整、欠驱动系统。本文建立了带多个拖车的移动机器人系统的运动学模型,对系统的运动特性进行了分析,并在此基础上对系统的运动进行了数值仿真和图形仿真,验证了理论分析的正确性。 关键词: 移动机器人系统; 运动学模型; 龙格-库塔法; 计算机仿真 中图分类号: TP242.3 文献标识码:A 文章编号:1004-731X (2000) 01-0043-4 Modeling and Simulation of Tractor-trailor Robot Systems' Kinematics YANG Kai, HUANG Ya-lou (Department of Computer and System Science, Nankai University, Tianjin 300071) XU Guo-hua (Institute of Automation, Chinese Academy of Sciences, Beijing 100080,China) Abstract: A mobile robot with multi-trailers is a typical nonholonomic, underactuated system. This paper establishes a kinematic model for such system. Based on the kinematic model, the motion of the system is analytically studied, and the simulation of the motion for this system is conducted with the means of Runge-Kutta method and computer graphics. It proves that the theoretical analysis is right. Keywords: mobile robot; underactuated system; Runge-Kutta; computer simulation 1 引言 移动机器人是机器人学中的一个重要分支,本文所讨论的是一种特殊类型的移动机器人系统——带拖车的轮式移动机器人(Tractor-trailer robot),它由一系列相互铰链在一起的多个二轮式刚体小车组成,运行在一个平面上。带拖车的轮式移动机器人系统的一种情形是由一个卡车型的牵引车拖动着一个或多个被动的拖车组成,牵引车可以执行类似于汽车那样的运动:驱动轮向前或向后运动,转向轮向左或向右转向,拖车跟踪牵引车的运动路径。 作为典型的欠驱动、非完整系统,带拖车的移动机器人系统的运动学、规划、控制等方面的研究明显不同于其它机器人系统,由于系统运动规律、控制特性上的理论结果亟待验证,因此,带拖车的移动机器人系统的仿真是极有价值的。 本文针对一般结构形式的带拖车的移动机器人系统建立系统的运动学模型,研究模型的递推形式以解决拖车节数变化带来的模型重构问题,同时就一些问题开展理论分析与仿真验证。 2 系统的运动学模型 2.1 基本假设与变量说明 为了使所建立的数学模型对各种车体链接形式均成立,这里以非标准型带拖车的轮式移动机器人系统为研究对象,所谓非标准型就是相邻两车体的链接点不在前一车体的轮轴上而是在链接轴的某点上(如图1所示),且假设:整个系统是在平面上运动;车轮是无滑动的;车体关于其纵向轴线对称;车轮与地面是点接触,且是纯滚动运动;车体是刚体; 用于车体连接的关节之间是无摩擦

一个简单的演示用的Linux字符设备驱动程序.

实现如下的功能: --字符设备驱动程序的结构及驱动程序需要实现的系统调用 --可以使用cat命令或者自编的readtest命令读出"设备"里的内容 --以8139网卡为例,演示了I/O端口和I/O内存的使用 本文中的大部分内容在Linux Device Driver这本书中都可以找到, 这本书是Linux驱动开发者的唯一圣经。 ================================================== ===== 先来看看整个驱动程序的入口,是char8139_init(这个函数 如果不指定MODULE_LICENSE("GPL", 在模块插入内核的 时候会出错,因为将非"GPL"的模块插入内核就沾污了内核的 "GPL"属性。 module_init(char8139_init; module_exit(char8139_exit; MODULE_LICENSE("GPL"; MODULE_AUTHOR("ypixunil"; MODULE_DESCRIPTION("Wierd char device driver for Realtek 8139 NIC"; 接着往下看char8139_init( static int __init char8139_init(void {

int result; PDBG("hello. init.\n"; /* register our char device */ result=register_chrdev(char8139_major, "char8139", &char8139_fops; if(result<0 { PDBG("Cannot allocate major device number!\n"; return result; } /* register_chrdev( will assign a major device number and return if it called * with "major" parameter set to 0 */ if(char8139_major == 0 char8139_major=result; /* allocate some kernel memory we need */ buffer=(unsigned char*(kmalloc(CHAR8139_BUFFER_SIZE, GFP_KERNEL; if(!buffer { PDBG("Cannot allocate memory!\n"; result= -ENOMEM;

字符设备驱动程序

Linux字符设备驱动(转载) 来源: ChinaUnix博客日期:2008.01.01 18:52(共有0条评论) 我要评论 Linux字符设备驱动(转载) 这篇文章描述了在Linux 2.4下,如何建立一个虚拟的设备,对初学者来说很有帮助。原文地址:https://www.wendangku.net/doc/1911285174.html,/186/2623186.shtml Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合,通过这些函数使得Windows的设备操作犹如文件一般。在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作,如open ()、close ()、read ()、write () 等。 Linux主要将设备分为二类:字符设备和块设备。字符设备是指设备发送和接收数据以字符的形式进行;而块设备则以整个数据缓冲区的形式进行。字符设备的驱动相对比较简单。 下面我们来假设一个非常简单的虚拟字符设备:这个设备中只有一个4个字节的全局变量int global_var,而这个设备的名字叫做"gobalvar"。对"gobalvar"设备的读写等操作即是对其中全局变量global_var的操作。 驱动程序是内核的一部分,因此我们需要给其添加模块初始化函数,该函数用来完成对所控设备的初始化工作,并调用register_chrdev() 函数注册字符设备: static int __init gobalvar_init(void) { if (register_chrdev(MAJOR_NUM, " gobalvar ", &gobalvar_fops)) { //…注册失败 } else

字符设备驱动开发实验

字符设备驱动实验 实验步骤: 1、将设备驱动程序使用马克file文件编译 生成模块firstdev.ko 2、将模块加载到系统中insmod firstdev.ko 3、手动创建设备节点 mknod /dev/first c 122 0 4、使用gcc语句编译firsttest.c生成可执行 文件 5、运行可执行文件firsttest,返回驱动程序 中的打印输出语句。 查看设备号:cat /proc/devices 卸载驱动:rmmod firstdev 删除设备节点:rm /dev/first 显示printk语句,(打开一个新的终端)while true do sudo dmesg -c sleep 1 done

源码分析 设备驱动程序firstdev.c #include #include #include #include #include #include //#include static int first_dev_open(struct inode *inode, struct file *file) { //int i; printk("this is a test!\n"); return 0; }

static struct file_operations first_dev_fops ={ .owner = THIS_MODULE, .open = first_dev_open, }; static int __init first_dev_init(void) { int ret; ret = register_chrdev(122,"/dev/first",&first_dev_fo ps); printk("Hello Modules\n"); if(ret<0) { printk("can't register major number\n"); return ret; }

一个简单字符设备驱动实例

如何编写Linux设备驱动程序 Linux是Unix操作系统的一种变种,在Linux下编写驱动程序的原理和思想完全类似于其他的Unix系统,但它dos或window环境下的驱动程序有很大的区别。在Linux环境下设计驱动程序,思想简洁,操作方便,功能也很强大,但是支持函数少,只能依赖kernel中的函数,有些常用的操作要自己来编写,而且调试也不方便。本文是在编写一块多媒体卡编制的驱动程序后的总结,获得了一些经验,愿与Linux fans共享,有不当之处,请予指正。 以下的一些文字主要来源于khg,johnsonm的Write linux device driver,Brennan's Guide to Inline Assembly,The Linux A-Z,还有清华BBS上的有关device driver的一些资料. 这些资料有的已经过时,有的还有一些错误,我依据自己的试验结果进行了修正. 一、Linux device driver 的概念 系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能: 1)对设备初始化和释放; 2)把数据从内核传送到硬件和从硬件读取数据; 3)读取应用程序传送给设备文件的数据和回送应用程序请求的数据; 4)检测和处理设备出现的错误。 在Linux操作系统下有两类主要的设备文件类型,一种是字符设备,另一种是块设备。字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作。块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待. 已经提到,用户进程是通过设备文件来与实际的硬件打交道。每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备。另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们。设备文件的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序. 最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度。也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作。如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck。 二、实例剖析 我们来写一个最简单的字符设备驱动程序。虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理.把下面的C代码输入机器,你就会获得一个真正的设备

linux字符设备驱动课程设计报告

一、课程设计目的 Linux 系统的开源性使其在嵌入式系统的开发中得到了越来越广泛的应用,但其本身并没有对种类繁多的硬件设备都提供现成的驱动程序,特别是由于工程应用中的灵活性,其驱动程序更是难以统一,这时就需开发一套适合于自己产品的设备驱动。对用户而言,设备驱动程序隐藏了设备的具体细节,对各种不同设备提供了一致的接口,一般来说是把设备映射为一个特殊的设备文件,用户程序可以像对其它文件一样对此设备文件进行操作。 通过这次课程设计可以了解linux的模块机制,懂得如何加载模块和卸载模块,进一步熟悉模块的相关操作。加深对驱动程序定义和设计的了解,了解linux驱动的编写过程,提高自己的动手能力。 二、课程设计内容与要求 字符设备驱动程序 1、设计目的:掌握设备驱动程序的编写、编译和装载、卸载方法,了解设备文件的创建,并知道如何编写测试程序测试自己的驱动程序是否能够正常工作 2、设计要求: 1) 编写一个简单的字符设备驱动程序,该字符设备包括打开、读、写、I\O控制与释放五个基本操作。 2) 编写一个测试程序,测试字符设备驱动程序的正确性。 3) 要求在实验报告中列出Linux内核的版本与内核模块加载过程。 三、系统分析与设计 1、系统分析 系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口。设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作。设备驱动程序是内核的一部分,它完成以下的功能: 1、对设备初始化和释放; 2、把数据从内核传送到硬件和从硬件读取数据; 3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据; 4、检测和处理设备出现的错误。 字符设备提供给应用程序的是一个流控制接口,主要包括op e n、clo s e(或r ele as e)、r e ad、w r i t e、i o c t l、p o l l和m m a p等。在系统中添加一个字符设备驱动程序,实际上就是给上述操作添加对应的代码。对于字符设备和块设备,L i n u x内核对这些操作进行了统一的抽象,把它们定义在结构体fi le_operations中。 2、系统设计: 、模块设计:

字符设备驱动框架

Linux中设备分类: 按照对设备的访问方式可分为以下三类: 1.字符设备(char device) (1)例如:键盘、鼠标、串口、帧缓存等; (2)通过/dev/下的设备节点访问;以字节为单位访问; (3)一般只支持顺序访问;(特例:帧缓存framebuffer) (4)无缓冲。 2.块设备(block device) (1)例如:磁盘、光驱、flash等; (2)以固定大小为单位访问:磁盘以扇区(512B)为单位;flash以页为单位。 (3)支持随机访问; (4)有缓冲(减少磁盘IO,提高效率)。 3.网络设备(network device) (1)无设备文件(节点); (2)应用层通过socket接口访问网络设备(报文发送和接收的媒介)。 设备驱动在内核中的结构: 1.VFS虚拟文件系统作用:向应用层提供一致的文件访问接口,正是由于VFS 的存在,才可以将设备以文件的方式访问。 2.虚拟文件系统,存在于内存中,不在磁盘上,掉电丢失。例如:/proc、/sys、 /tmp。

设备号: 1.作用:唯一地标识一个设备; 2.类型:dev_t devno;即32位无符号整型; 3.组成: (1)主设备号:用于区分不同类型(按功能划分)的设备; (2)此设备号:用于区分相同类型的不同设备。 注意:相同类型的设备(主设备号相同)可以使用同一个驱动。 4.构建设备号: int major = 250; int minor = 0; (1)dev_t devno = (major << 20) | minor;不建议使用; (2)利用宏来构建:dev_t devno = MKDEV (major, minor); 注意:我们可以通过文件$(srctree)/documentation/device.txt来查看内核对设备号的分配情况。 (1)该文本中的有对应设备文件的设备号是已经被申请过的,我们不可以重 复使用(申请); (2)从中可以看出,我们在编写驱动程序时可以使用的主设备号范围为 240~254,为了方便记忆,通常使用250作为主设备号。 字符设备驱动框架: 驱动:作用,为应用层提供访问设备的接口(对设备发的各种操作)。 一、申请设备号 1.构建设备号:dev_t devno = MKDEV (major, minor); 2.申请设备号: (1)动态申请:alloc_chrdev_region; (2)静态申请: register_chrdev_region。

字符设备驱动步骤

编写字符设备驱动框架的步骤 Step 1: 申请设备号(主要是申请主设备号) 有两种方式: ⑴静态申请 通过下面这个函数实现: int register_chrdev_region(dev_t from, unsigned count, const char *name); /* register_chrdev_region() - register a range of device numbers * @from: the first in the desired range of device numbers; must include * the major number. * @count: the number of consecutive device numbers required * @name: the name of the device or driver. * * Return value is zero on success, a negative error code on failure.*/ 这种方式主要用于,驱动开发者事先知道该驱动主设备号的情况。 ⑵动态申请 通过下面这个函数实现: int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name) /* alloc_chrdev_region() - register a range of char device numbers * @dev: output parameter for first assigned number * @baseminor: first of the requested range of minor numbers * @count: the number of minor numbers required * @name: the name of the associated device or driver * * Allocates a range of char device numbers. The major number will be * chosen dynamically, and returned (along with the first minor number) * in @dev. Returns zero or a negative error code.*/ 这种方式由系统动态分配一个设备号,返回的设备号保存在参数dev中。 Step 2 :注册字符设备 在linux 内核中用struct cdev表示一个字符设备。 字符设备的注册与注销分别通过下面的两个函数来实现: int cdev_add(struct cdev *p, dev_t dev, unsigned count); /** * cdev_add() - add a char device to the system * @p: the cdev structure for the device * @dev: the first device number for which this device is responsible * @count: the number of consecutive minor numbers corresponding to this * device * * cdev_add() adds the device represented by @p to the system, making it * live immediately. A negative error code is returned on failure.

博士生课程空间机器人关键技术

博士生课程空间机器人关键技术

1空间机器人概述 2数学力学基础 3冗余自由度机器人 4柔性机械臂 5欠驱动机器人 6机器人灵巧手 (一)空间机器人的概述 1.空间机器人在空间技术中的地位 从20世纪50年代,以美国和苏联为首的空间技术大国就在空间技术领域展开了激烈的竞赛。 i 苏联 1957年8月3日,前苏联研制的第一枚洲际弹道导弹SS-6首次发射成功。不久,前苏联火箭总设计师柯罗廖夫从美国新闻界得知美国试图在1957-1958年的国际地球物理年里发射一颗人造地球卫星。于是,他立即将SS-6导弹稍加修改,将弹头换上一个结构简单的卫星,抢先将第一颗人造卫星送上了太空。 接着,在第一颗人造卫星发射后一个月,即11月3日,又用SS-6导弹作航天运输工具,将装有小狗“莱伊卡”的第二颗人造卫星送入太空的圆形地球轨道。 1959年5月,前苏联又将“月球”l号人造卫星送入了月球轨道。 ii 美国 在1958年以前,以“红石”近程导弹和“维金”探空火箭为基础,分别研制成“丘比特”C和“先锋”号等小型运载火箭,用于发射最初的几个有效载荷仅为数千克至十几千克的小卫星。 发展到今天,从地面实验室研究到人造卫星、空间站、载人飞船、航天飞机、行星表面探测器,空间技术大国都投入了大量人力、物力和财力。空间技术对于天文学、气象、通信、医学、农业以及微电子等领域都产

生了很大的效益。不仅如此,空间技术对于未来国家安全更具有重要的意义。在空间技术发展的过程中空间机器人的作用越来越明显。 20世纪60年代前苏联的移动机器人研究所(著名的俄罗斯Rover科技有限公司前身)研制了世界上第一台和第二台月球车Lunohod-1和Lunohod-2。1976年美国发射海盗一号和二号(Rover-1、Rover-2)的登陆舱相继在在火星表面登陆,通过遥操作机械臂进行火星表面土壤取样。 随着空间技术研究的日益深入,人类空间活动的日益频繁,需要进行大量的宇航员的舱外活动(EV A),这对宇航员不仅危险,而且没有大气层的防护,宇宙射线和太空的各种飞行颗粒都会对宇航员造成伤害。建造国际空间站,以及未来的月球和火星基地,工程浩大,只靠宇航员也是非力所能及的。还有空间产业、空间科学实验和探测,这些工作是危险的,但有一定重复性,各航天大国都在研究用空间机器人来代替宇航员的大部分工作。 此外许多空间飞行器长期工作在无人值守的状态,这些飞行器上面各种装置的维护和修理依靠发射飞船,把宇航员送上太空的办法既不经济,也不现实。在未来的空间活动中,许多工作仅靠宇航员的舱外作业是无法完成的,必须借助空间机器人来完成空间作业。 2空间机器人的任务和分类 1)空间建筑与装配。一些大型的安装部件,比如无线电天线,太阳能电池,各个舱段的组装等舱外活动都离不开空间机器人,机器人将承担各种搬运,各构件之间的连接紧固,有毒或危险品的处理等任务。有人预计,在不久将来空间站建造初期,一半以上的工作都将由机器人完成。 2)卫星和其他航天器的维护与修理。随着人类在太空活动的不断发展,人类在太空的资产越来越多,其中人造卫星占了绝大多数。如果这些卫星一旦发生故障,丢弃它们再发射新的卫星就很不经济,必须设法修理后使它们重新发挥作用。但是如果派宇航员去修理,又牵涉到舱外活动的问题,而且由于航天器在太空中,是处于强烈宇宙辐射的环境之下,有时人根本无法执行任务,所以只能依靠空间机器人。挑战者号和哥伦比亚号航天飞机的坠毁引起人们对空间飞行安全的关注,采用空间机械臂修复哈勃太空望远镜似乎是一件很自然的事情。安装上新的科学仪器(包括一台视野宽阔的摄象仪和一台摄谱仪)后,哈勃望远镜的观测能力可增强十倍以上。空

字符设备驱动程序

字符设备驱动程序 字符设备驱动程序与块设备不同。所涉及的键盘驱动、控制台显示驱动和串口驱动以及与这些驱动有关的接口、算法程序都紧密相关。他们共同协作实现控制台终端和串口终端功能。 下图反映了控制台键盘中断处理过程。 以上为总的处理流程,下面对每一个驱动分开分析。首先是键盘驱动。键盘驱动用汇编写的,比较难理解,牵涉内容较多,有键盘控制器804X的编程,还有扫描码(共3套,这里用第二套)和控制命令及控制序列(p209~210有讲解)。由于键盘从XT发展到AT到现在PS/2,USB,无线键盘,发展较快,驱动各有不同,此版本驱动为兼容XT,将扫描码映射为XT再处理,因此仅供参考。CNIX操作系统的键盘驱动实现为C语言,可读性更好。 键盘驱动 键盘驱动就是上图键盘硬件中断的过程。keyboard.S中的_keyboard_interrupt 函数为中断主流程,文件中其他函数均被其调用。

以上打星处为键盘驱动的核心,即主要处理过程,针对不同扫描码分别处理,并最终将转换后所得ASCII 码或控制序列放入控制台tty 结构的读缓冲队列read_q 中。 键处理程序跳转表为key_table ,根据扫描码调用不同处理程序,对于“普通键”,即只有一个字符返回且没有含义变化的键,调用do_self 函数。其他均为“特殊键”:1. crtrl 键的按下和释放 2. alt 键的按下和释放 3. shift 键的按下和释放 4. caps lock 键的按下和释放(释放直接返回,不作任何处理) 5. scroll lock 键的按下 6. num lock 的按下 7. 数字键盘的处理(包括alt-ctrl+delete 的处理,因为老式键盘delete 键在数字小键盘上。还包括对光标移动键的分别处理) 8. 功能键 (F1~F12)的处理 9. 减号的处理(老键盘’/’与’-’以0xe0加以区分,可能其中一键要按shift ) do_self 是最常用的流程,即跳转表中使用频率最高的流程:

一种欠驱动移动机器人运动模式分析

天津比利科技发展有限公司 李艳杰 ’马岩1,钟华2,吴镇炜2 ' 隋春平2 (1.沈阳理工大学机械工程学院,沈阳110168;2.中国科学院沈阳自动化研究所,沈阳110016) 摘要:介绍了一种欠驱动移动机器人的机械结构。分析了该欠驱动移动机器人在平地行进 模式的特点,提出一种越障控制模式。在该越障控制模式中加入了障碍物高度计算算法, 使得移动机器人在越障过程中的智能控制更加高效。利用VB编写控制程序人机界面,在移 动机器人实物平台上进行了实验,实验结果证明了控制方法的有效性。 关键词:AVR单片机;欠驱动移动机器人;越障模式 中图分类号:TP242文献标志码:A Analysis of a Underactuated Mobile Robot Moving Mode LI Yan-jie',MA Yan',ZHONG Hua2,WU2hen-wej2,SUI Chun-ping2 (l.School of Mechanical Engineering,Shenyang Ligong University,Shenyang110168,China;2.Robotics Lab,Shenyang Institute of Automation,Chinese Academy of Sciences,Shenyang110016,China) Abstract:The mechanical structure of a kind of underactuated mobile robot was described in this paper.The charac- teristics of the underactuated mobile robot in the plains traveling mode was analyzed and a kind of obstacle-negotia- tion control mode was proposed.Due to calculate algorithm of obstacle's height was added to the the obstacle-nego- tiation control mode,the intelligent control of obstacle-negotiation becomes more efficient.The control procedure HMI was programmed by VB and the experiment was performed on the mobile robot platform.Experiment results show the control method was effective. Key words:AVR SCM;underactuated mobile robot;obstacle-negotiation mode 欠驱动机械系统是一类特殊的非线性系统,该容错控制的作用。因此,欠驱动机器人被广泛应用系统的独立控制变量个数小于系统的自由度个数【l】o于空间机器人、水下机器人、移动机器人、并联机器 欠驱动系统结构简单,便于进行整体的动力学分析人、伺服机器人和柔性机器人等行业。 和试验。有时在设计时有意减少驱动装置以此来增本文以四驱动、八自由度的欠驱动移动机器人加整个系统的灵活性。同时,由于控制变量受限等为实验对象,通过切换驱动器的工作模式来克服系原因,欠驱动系统又足够复杂,便于研究和验证各统不完全可控造成反馈控制失效【2】的缺点。以工控 种算法的有效性。当驱动器故障时,可能使完全驱机作为上位机,通过工控机的RS232串口与AVR 葫系统成为欠驱动系统,欠驱动控制算法可以起到单片机进行无线通讯。通过对驱动器反馈数据的分 收稿日期:2013-01-22:修订日期:2013-02-19 基金项目:国家科技支撑计划项目(2013BAK03801,2013BAK03802) 作者筒介:李艳杰(1969-),女,博士,教授,研究方向为智能机器人控制及机器人学;马岩(1988-),男,硕士研究生,研究方向为嵌入式控制;钟华(1977-),男,博士,副研究员,研究方向为机器人控制及系统集成。 Automation&Instrumentation2013(9) 一种欠驱动移动机器人运动模式分析

LINUX字符设备驱动编写基本流程

---简介 Linux下的MISC简单字符设备驱动虽然使用简单,但却不灵活。 只能建立主设备号为10的设备文件。字符设备比较容易理解,同时也能够满足大多数简 单的硬件设备,字符设备通过文件系统中的名字来读取。这些名字就是文件系统中的特 殊文件或者称为设备文件、文件系统的简单结点,一般位于/dev/目录下使用ls进行查 看会显示以C开头证明这是字符设备文件crw--w---- 1 root tty 4, 0 4月 14 11:05 tty0。 第一个数字是主设备号,第二个数字是次设备号。 ---分配和释放设备编号 1)在建立字符设备驱动时首先要获取设备号,为此目的的必要的函数是 register_chrdev_region,在linux/fs.h中声明:int register_chrdev_region(dev_t first, unsigned int count, char *name);first是你想 要分配的起始设备编号,first的次编号通常是0,count是你请求的连续设备编号的 总数。count如果太大会溢出到下一个主设备号中。name是设备的名字,他会出现在 /proc/devices 和sysfs中。操作成功返回0,如果失败会返回一个负的错误码。 2)如果明确知道设备号可用那么上一个方法可行,否则我们可以使用内核动态分配的设 备号int alloc_chrdev_region(dev_t *dev, unsigned int firstminor,unsigned int count, char *name);dev是个只输出的参数,firstminor请求的第一个要用的次编号, count和name的作用如上1)对于新驱动,最好的方法是进行动态分配 3)释放设备号,void unregister_chrdev_region(dev_t first unsigned int count); ---文件操作file_operations结构体,内部连接了多个设备具体操作函数。该变量内部 的函数指针指向驱动程序中的具体操作,没有对应动作的指针设置为NULL。 1)fops的第一个成员是struct module *owner 通常都是设置成THIS_MODULE。 linux/module.h中定义的宏。用来在他的操作还在被使用时阻止模块被卸载。 2)loff_t (*llseek) (struct file *, loff_t, int);该方法用以改变文件中的当前读/ 写位置 返回新位置。 3)ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);该函数用 以从设备文件 中读取数据,读取成功返回读取的字节数。

基于动力学模型的轮式移动机器人运动控制_张洪宇

文章编号:1006-1576(2008)11-0079-04 基于动力学模型的轮式移动机器人运动控制 张洪宇,张鹏程,刘春明,宋金泽 (国防科技大学机电工程与自动化学院,湖南长沙 410073) 摘要:目前,对不确定非完整动力学系统进行设计的主要方法有自适应控制、预测控制、最优控制、智能控制等。结合WMR动力学建模理论的研究成果,对基于动力学模型的WMR运动控制器的设计和研究进展进行综述,并分析今后的重点研究方向。 关键词:轮式移动机器人;动力学模型;运动控制;非完整系统 中图分类号:TP242.6; TP273 文献标识码:A Move Control of Wheeled Mobile Robot Based on Dynamic Model ZHANG Hong-yu, ZHANG Peng-cheng, LIU Chun-ming, SONG Jin-ze (College of Electromechanical Engineering & Automation, National University of Defense Technology, Changsha 410073, China) Abstract: At present, methods of non-integrity dynamic systems design mainly include adaptive control, predictive control, optimal control, intelligence control and so on. Based on analyzing the recent results in modeling of WMR dynamics, a survey on motion control of WMR based on dynamic models was given. In addition, future research directions on related topics were also discussed. Keywords: Wheeled mobile robot; Dynamic model; Motion control; Non-integrity system 0 引言 随着生产的发展和科学技术的进步,移动机器人系统在工业、建筑、交通等实际领域具有越来越广泛的应用和需求。进入21世纪,随着移动机器人应用需求的扩大,其应用领域已从结构化的室内环境扩展到海洋、空间和极地、火山等环境。较之固定式机械手,移动机器人具有更广阔的运动空间,更强的灵活性。移动机器人的研究必须解决一系列问题,包括环境感知与建模、实时定位、路径规划、运动控制等,而其中运动控制又是移动机器人系统研究中的关键问题。故结合WMR动力学建模理论的研究成果,对基于动力学模型的WMR运动控制器设计理论和方法的研究进展进行研究。 1 WMR动力学建模 有关WMR早期的研究文献通常针对WMR的运动学模型。但对于高性能的WMR运动控制器设计,仅考虑运动学模型是不够的。文献[1]提出了带有动力小脚轮冗余驱动的移动机器人动力学建模方法,以及WMR接触稳定性问题和稳定接触条件。文献[2]提出一种新的WMR运动学建模的方法,这种方法是基于不平的地面,从每个轮子的雅可比矩阵中推出一个简洁的方程,在这新的方程中给出了车结构参数的物理概念,这样更容易写出从车到接触点的转换方程。文献[3]介绍了与机器人动作相关的每个轮子的雅可比矩阵,与旋转运动的等式合并得出每个轮子的运动方程。文献[4]基于LuGre干摩擦模型和轮胎动力学提出一种三维动力学轮胎/道路摩擦模型,不但考虑了轮胎的径向运动,同时也考虑了扰动和阻尼摩擦下动力学模型,模型不但可以应用在轮胎/道路情况下,也可应用在对车体控制中。在样例中校准模型参数和证实了模型,并用于广泛应用的“magic formula”中,这样更容易估计摩擦力。在文献[5]中同时考虑运动学和动力学约束,其中提出新的计算轮胎横向力方法,并证实了这种轮胎估计的方法比线性化的轮胎模型好,用非线性模型来模拟汽车和受力计算,建立差动驱动移动机器人模型,模型本身可以当作运动控制器。 2 WMR运动控制器设计的主要发展趋势 在WMR控制器设计中,文献[6]给出了全面的分析,WMR的反馈控制根据控制目标的不同,可以大致分为3类:轨迹跟踪(Trajectory tracking)、路径跟随(Path following)、点镇定(Point stabilization)。轨迹跟踪问题指在惯性坐标系中,机器人从给定的初始状态出发,到达并跟随给定的参考轨迹。路径跟随问题是指在惯性坐标系中,机器人从给定的初始状态出发,到达并跟随指定的几何 收稿日期:2008-05-19;修回日期:2008-07-16 作者简介:张洪宇(1978-)男,国防科学技术大学在读硕士生,从事模式识别与智能系统研究。 ,

相关文档
相关文档 最新文档