在860里增加TL16C554多串口芯片驱动.doc_第1页
在860里增加TL16C554多串口芯片驱动.doc_第2页
在860里增加TL16C554多串口芯片驱动.doc_第3页
在860里增加TL16C554多串口芯片驱动.doc_第4页
在860里增加TL16C554多串口芯片驱动.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在860里增加TL16C554多串口芯片驱动(一)一设备概述MPC860t有4个SCC(serial communications controller串口通讯控制器)和2个SMC(serial management controller串口管理控制器),一共可以扩展6个串口。但笔者开发的通讯控制器项目中,由于考虑到需要扩展8个或更多串口,SCC和SMC扩展显然不能满足要求,需要需求一种新的可扩展的串口芯片 。我们采用两个TL16C554芯片来解决这个问题。一个TL16C554芯片集成了四个ST16550 ACE(异步通讯元件ASYNCHRONOUS COMMUNICATIONS ELEMENT)。二串口驱动简介I/O SystemyyChan2yyChan1xxChan2xxChan1yyDrv xxDrv ttyDrv 注意:此处xxDrv,yyDrv表示一个特定的驱动程序,下同 . ttyDrv 虚拟驱动,用以.管理I/O System.调用实际的驱动程序来管理硬件 . ModelTarget Agent(中断或轮巡模式)ApplicationI/O SystemttyDrv(中断模式)xxDrv. xxDrv支持: 标准I/O System接口 Target Agent接口 两种模式(中断interrupt,轮巡poll).回调CallBacks允许高层协议来设定驱动怎样收发数据设备驱动有两个回调(驱动调用)高层协议 getCallback putCallBack put回调:传送一个从设备读到的字符到高层协议 get回调:从高层协议取得一个字符以便写到设备代码实现usrConfig.c 一般性代码 sysSerial.c 特定执行代码 xxDrv.c 设备特定代码三详细解说(调用和实现部分)usrConfig.c,sysSerial.c注意:由于我们采用了多种设备实际的驱动(SMC和16C554),所以在sysSerial.c里需要整合,整合的函数包括sysSerialHwInit(),sysSerialHwInit2 (),sysSerialChanGet(),sysSerialReset()解读usrConfig.c先看usrConfig.c里与串口有关的部分(前面部分是早期版本的,不予理会),这里调用了ttyDrv(),然后用ttyDevCreate(),sysSerialChanGet()在sysSerials.c里定义,它把设备的编号同一个SIO_CHAN类型的结构关联起来,而这个结构在是至关重要的.(注意,如果系统采用串口调试,则该串口号被保留起来)ttyDev()作的工作:调用iosDrvInstall安装ttyDrv到设备表(使用ttyDrv和tyLib的入口)ttyDevCreate()作的工作: 申请并初始化设备描述调用tyDevinit()初始化tyLib 初始化selectLib 建立输入输出环行缓冲 创建信号量调用iosDevAdd()增加设备到设备列表安装tyLib的程序和输入输出回调使设备开始中断模式#ifdef INCLUDE_TYCODRV_5_2#ifdef INCLUDE_TTY_DEV if (NUM_TTY 0)tyCoDrv ();/* install console driver */for (ix = 0; ix 0)ttyDrv();/* install console driver */for (ix = 0; ix = chanNum)return (SIO_CHAN *) ERROR); return (SIO_CHAN *) &ppc860Chan channel);单独采用16c554时为:SIO_CHAN * sysSerialChanGet ( int channel /* serial channel */ ) if (channel = (int) (NELEMENTS(sysSioChans) )return (SIO_CHAN *) ERROR; return sysSioChanschannel;我们必须把两种情况整合.SIO_CHAN * sysSerialChanGet(int channel ) if (channel = (int) (NELEMENTS(sysSioChans) )return (SIO_CHAN *) ERROR;if channel=1 return (SIO_CHAN *)ppc860Chanchannel else return sysSioChanschannel-2;sysSerialReset()关于sysSerialResset,由于16c554 和860的smc采用不同的原理,所以其重启也有不同,所以在sysSerialReset()里要考虑两中情况void sysSerialReset (void) /* disable serial interrupts */ intDisable (devPLevel); void sysSerialReset (void) sysSerialHwInit ();void sysSerialReset (void) sysSerialHwInit ();intDisable (devPLevel);重中之重:关于sysSerialHwInit2() sysSerialHwInit2()由usrConfig.c里的usrRoot调用,用于连接中断smc的如下:void sysSerialHwInit2 (void) inti;/* an index */ /* connect serial interrupts */ for (i = 0; i i);CIMR是一个叫CP Int mask reg的宏,这里分别开启SMC1和SMC2的中断#define CIMR_SMC10x00000010/* SMC 1 */#define CIMR_SMC2_PIP0x00000008/* SMC 2 */#defineCIMR(base)(CAST(VUINT32 *)(base) + 0x0948)为什么在不在sysSerialHwinit()里调用连接呢?因为在sysHwInit()执行的时刻内核内存分配算符还没有初始化!16c554的:void sysSerialHwInit2 (void) (void) intConnect (INUM_TO_IVEC(devParas0.vector), st16554MuxInt, (int) &st16554Mux); intEnable (devPLevel);各位必须注意,16c554中断服务程序是一个多重的,意思是:所有使用同一中断的8个通道有一样的中断服务程序,这样在st16554MuxInt()处理的时候需要做出相应的判断(具体实现见后面)经过整合后的sysSerialHwInit2应该是:void sysSerialHwInit2 (void) inti;/* an index */ /* connect serial interrupts */ for (i = 0; i i);void sysSerialHwInit2 (void) inti;/* an index */ /* connect serial interrupts */ for (i = 0; i i); (void) intConnect (INUM_TO_IVEC(devParas0.vector), st16554MuxInt, (int) &st16554Mux); intEnable (devPLevel);重中之重:关于sysSerialHwInit()首先看16554的:void sysSerialHwInit (void) int i; for (i = 0; i N_ST16554_UART_CHANNELS; i+)st16554Chani.regDelta = devParasi.regSpace;st16554Chani.regs = devParasi.baseAdrs;st16554Chani.baudRate = CONSOLE_BAUD_RATE;st16554Chani.xtal = UART_XTAL_FREQ; st16554Chani.level = devPLevel;/* * Initialise driver functions, getTxChar, putRcvChar and * channelMode and init UART. */st16554DevInit(&st16554Chani); devParas结构用存放设备的一些参数typedef struct UINT vector; UINT8 *baseAdrs; UINT regSpace; UINT intLevel; CMA_ST16554_CHAN_PARAS;LOCAL CMA_ST16554_CHAN_PARAS devParas = INT_VEC_COM, (UINT8 *)SERIAL_A_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM, INT_VEC_COM, (UINT8 *)SERIAL_B_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM, INT_VEC_COM, (UINT8 *)SERIAL_C_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM, INT_VEC_COM, (UINT8 *)SERIAL_D_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM, INT_VEC_COM, (UINT8 *)SERIAL_E_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM, INT_VEC_COM, (UINT8 *)SERIAL_F_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM, INT_VEC_COM, (UINT8 *)SERIAL_G_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM, INT_VEC_COM, (UINT8 *)SERIAL_H_BASE_ADR, UART_REG_ADDR_INTERVAL, INT_LVL_COM ;从SERIAL_A_BASE_ADR到SERIAL_H_BASE_ADR表示两个16c554的8个通道的基地址。INT_VEC_COM和INT_LVL_COM是通道所用中断的矢量和中断号,各位可以看到8个通道(4 X 2)所用的通道一样.当然可以在设计电路的时候选择不同的通道,但这对有限的中断是浪费.UART_REG_ADDR_INTERVAL是寄存器的步长,或者叫间隔,等于8.SysSerialHwInit先对st16554Chan结构做一些初始化(st16554Chan(i)对应相应的通道),设置寄存器步长regDelta,基地址regs,波特率baudRate,时钟晶振频率xtal,中断号intLevel然后调用xxDrv里的st16554DevInit,关于xxDevInit在xxDrv.c详解里详细介绍.使用smc的SysSerialHwInit要复杂许多void sysSerialHwInit (void) inti;/* an index */ /* enable serial I/O on the board */ *BCSR1 &= (BCSR1_RS232_EN_L); /* If running an 823 or an 850, use only SMC1 */ if (*BCSR3 & BCSR3_DBID_MASK) = BCSR3_823DB_MASK) | (*BCSR3 & BCSR3_DBID_MASK) = BCSR3_850DB_MASK) chanNum = 1; if (chanNum = 2)*BCSR1 &= (BCSR1_RS232_2_EN_L); /* intialize the chips device descriptors */ for (i = 0; i smcm = 0; ppc860Chan i.pBaud = (UINT32 *) (UINT32) MPC860_BRGC1 (regBase) + (i * 4);ppc860Chan i.channelMode = 0;/* select RS232 pins */*MPC860_PBPAR(regBase) |= 0xC0 (i * 4); /* set it to normal operations */*MPC860_SDCR(regBase) = SDCR_RAID_BR5; /* reset the chip */ppc860DevInit(&(ppc860Chan i); 经过整合,应该是这样:void sysSerialHwInit (void) inti;/* an index */ /* enable serial I/O on the board */ *BCSR1 &= (BCSR1_RS232_EN_L); /* If running an 823 or an 850, use only SMC1 */ if (*BCSR3 & BCSR3_DBID_MASK) = BCSR3_823DB_MASK) | (*BCSR3 & BCSR3_DBID_MASK) = BCSR3_850DB_MASK) chanNum = 1; if (chanNum = 2)*BCSR1 &= (BCSR1_RS232_2_EN_L); /* intialize the chips device descriptors */ for (i = 0; i smcm = 0; ppc860Chan i.pBaud = (UINT32 *) (UINT32) MPC860_BRGC1 (regBase) + (i * 4);ppc860Chan i.channelMode = 0;/* select RS232 pins */*MPC860_PBPAR(regBase) |= 0xC0 (i * 4); /* set it to normal operations */*MPC860_SDCR(regBase) = SDCR_RAID_BR5; /* reset the chip */ppc860DevInit(&(ppc860Chan i); for (i = 0; i getTxChar= callback; pChan-getTxArg= callbackArg; return OK;case SIO_CALLBACK_PUT_RCV_CHAR: pChan-putRcvChar= callback; pChan-putRcvArg= callbackArg; return OK;default: return ENOSY

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论