VxWorks BSP学习笔记_串口驱动
来源:互联网 发布:管家婆服装软件 编辑:程序博客网 时间:2024/05/20 20:18
VxWorks BSP学习笔记(基于SBC8349E)
1. 串口驱动
1.1 串行驱动程序的重要结构
以下结构指出了驱动程序函数的入口点 ../target/h/sioLib.h
Typedef struct sio_drv_funcs /* driver functions */
{
int (*ioctl)
(
SIO_CHAN * pSioChan,
int cmd,
void * arg
);
int (*txStartup)
(
SIO_CHAN * pSioChan
);
int (*callbackInstall)
(
SIO_CHAN * pSioChan,
int callbackType,
STATUS (*callback)(void *, ...),
void * callbackArg
);
int (*pollInput)
(
SIO_CHAN * pSioChan,
char * inChar
);
int (*pollOutput)
(
SIO_CHAN * pSioChan,
char outChar
);
}SIO_DRV_FUNCS;
typedef struct sio_chan /* a serial channel */
{
SIO_DRV_FUNCS * pDrvFuncs;
/* device data */
} SIO_CHAN;
在串行设备的驱动程序中,必须有一个包含指向SIO_DRV_FUNCS指针的结构(XX_CHAN),这个结构可以包含设备的其他信息以及提供给高层协议的回调函数。以16550为例:
../target/h/drv/sio/ns16552Sio.h
typedef struct /* NS16550_CHAN * */
{
/* always goes first */
SIO_DRV_FUNCS * pDrvFuncs; /* driver functions */
/* callbacks */
STATUS (*getTxChar) (); /* pointer to xmitr function */
STATUS (*putRcvChar) (); /* pointer to rcvr function */
void * getTxArg;
void * putRcvArg;
UINT8 *regs; /* NS16552 registers */
UINT8 level; /* 8259a interrupt level for this device */
UINT8 ier; /* copy of ier */
UINT8 lcr; /* copy of lcr, not used by ns16552 driver */
UINT8 mcr; /* copy of modem control register */
UINT16 channelMode; /* such as INT, POLL modes */
UINT16 regDelta; /* register address spacing */
int baudRate;
UINT32 xtal; /* UART clock frequency */
UINT32 options; /* hardware setup options */
} NS16550_CHAN;
1.2 串行驱动程序的初始化函数
串行设备驱动程序的初始化函数应该包含下面的内容:
1) 包含一个指向xx_DRV结构的指针;
2) 初始化xx_CHAN;
3) 初始化驱动程序必要的内容;
4) 重新设置芯片
../target/src/drv/sio/ns16550Sio.c
/* driver functions */
#ifdef INCLUDE_TTY_DEV
static SIO_DRV_FUNCS ns16550SioDrvFuncs =
{
(int (*)()) ns16550Ioctl,
(int (*)()) ns16550TxStartup,
(int (*)()) ns16550CallbackInstall,
(int (*)()) ns16550PollInput,
(int (*)(SIO_CHAN *,char))ns16550PollOutput
};
#else /* INCLUDE_TTY_DEV */
static SIO_DRV_FUNCS ns16550SioDrvFuncs =
{
(int (*)()) NULL,
(int (*)()) NULL,
(int (*)()) NULL,
(int (*)()) ns16550PollInput,
(int (*)(SIO_CHAN *,char))ns16550PollOutput
};
#endif /* INCLUDE_TTY_DEV */
void ns16550DevInit
(
NS16550_CHAN * pChan /* pointer to channel */
)
{
int oldlevel = intLock ();
/* initialize the driver function pointers in the SIO_CHAN's */
pChan->pDrvFuncs = &ns16550SioDrvFuncs;
/* set the non BSP-specific constants */
pChan->getTxChar = ns16550DummyCallback;
pChan->putRcvChar = ns16550DummyCallback;
pChan->channelMode = 0; /* undefined */
pChan->options = (CLOCAL | CREAD | CS8);
pChan->mcr = MCR_OUT2;
/* reset the chip */
ns16550InitChannel (pChan);
intUnlock (oldlevel);
}
1.3 回调安装函数以及驱动各函数的实现
SIO_DRV_FUNCS结构中的各函数的实现
1.4 串行设备的安装
1.4.1 串行设备的初始化
sysDuartHwInit(),由usrInit()函数调用,初始化了驱动程序相关的xx_CHAN结构。调用了xxDevInit()函数初始化硬件,设置中断未连接标志。该函数在内核初始化之前完成。使用16550芯片的例子:
void sysDuartHwInit (void)
{
int i;
eumbbar_base = (char *)CCSBAR;
for (i = 0; i < N_DUART_CHANNELS; i++)
{
ns16550Chan[i].regs = (UINT8 *)devDuartParas[i].baseAdrs;
ns16550Chan[i].level = devDuartParas[i].intLevel;
ns16550Chan[i].channelMode = SIO_MODE_INT;
ns16550Chan[i].regDelta = devDuartParas[i].regSpace;
ns16550Chan[i].baudRate = DUART_BAUD;
ns16550Chan[i].xtal = sysClkFreqGet();
ns16550DevInit (&ns16550Chan[i]);
}
/* 以下初始硬件 */
if (ns16550Chan[0].channelMode == SIO_MODE_INT)
{
eumbbar_base[UDCR1] = 0x01; /* set duart mode */
eumbbar_base[ULCR1] = 0x80; /* open DLAB */
eumbbar_base[UAFR1] = 0x00;
eumbbar_base[UDMB1] = 0x03; /* for mpc8245 MSB, 9600bps @66Mhz */
eumbbar_base[UDLB1] = 0x64; /* LSB */
eumbbar_base[ULCR1] = 0x03; /* clear DLAB, no-parity, 1stop bit, 8bit data */
eumbbar_base[UMCR1] = 0x02; /* disable loopback mode */
eumbbar_base[UIER1] = 0x03; /* Tx empty, Rx interrupt enable */
}
if (ns16550Chan[1].channelMode == SIO_MODE_INT)
{
eumbbar_base[UDCR2] = 0x01; /* set duart mode */
eumbbar_base[ULCR2] = 0x80; /* open DLAB */
eumbbar_base[UAFR2] = 0x00;
eumbbar_base[UDMB2] = 0x01; /* for mpc8245 MSB, 9600bps @66Mhz */
eumbbar_base[UDLB2] = 0xB2; /* LSB */
eumbbar_base[ULCR2] = 0x03; /* clear DLAB, no-parity, 1stop bit, 8bit data */
eumbbar_base[UMCR2] = 0x02; /* diable loopback mode */
eumbbar_base[UIER2] = 0x03; /* Tx empty, Rx interrupt enable */
}
} /* sysDuartHwInit () */
1.4.2 安装串行设备的ISR
sysDuartHwInit2()由usrRoot任务中的sysClkConnnect()函数调用,安装了设备的中断服务程序。这个函数在系统初始化之后执行,此时系统已经可以执行中断连接了。
void sysSerialHwInit2 (void)
{
int i;
/* connect serial interrupts */
for (i = 0; i < N_DUART_CHANNELS; i++)
{
(void) intConnect ((VOIDFUNCPTR *)((int)devDuartParas[i].vector),
(VOIDFUNCPTR)ns16550Int, (int)&ns16550Chan[i] );
intEnable (devDuartParas[i].vector);
}
} /* sysDuartHwInit2 () */
1.4.3 串行设备描述符与通道号的转换
sysSerialChanGet()的作用是将串行设备通道的索引转换为该通道的设备描述符。通常目标机代理会使用这个函数以获得通道的指针,usrRoot()任务也会用到该函数。
SIO_CHAN * sysSerialChanGet
(
int channel /* serial channel */
)
{
if ( (channel < 0) ||
(channel >= (int)NELEMENTS(sysSerialSioChans)) )
return (SIO_CHAN *) ERROR;
return sysSerialSioChans[channel];
}
- VxWorks BSP学习笔记_串口驱动
- VxWorks串口驱动概述
- QNX 学习笔记-导入BSP-导入qnx工程bsp驱动包
- 【转】PowerPC VxWorks BSP分析5——VxWorks设备驱动
- vxWorks学习笔记
- VxWorks 操作系统学习笔记
- VxWorks 操作系统学习笔记
- VxWorks学习笔记 -- 信号量
- VxWorks 操作系统学习笔记
- VxWorks 操作系统学习笔记
- VxWorks 操作系统学习笔记
- vxWorks学习笔记
- VxWorks 学习笔记-Reconfiguring VxWorks
- VxWorks BSP理解
- VxWorks的BSP开发
- vxworks bsp调试
- VxWorks BSP 制作概要
- VxWorks的BSP开发
- MySQL 常见错误提示的对照表
- 用手机测试你的肺活量!?
- 一个很好的shell学习网址
- 关于早起
- struct和class的关系
- VxWorks BSP学习笔记_串口驱动
- 22条途径提升你的大脑!
- 重新学习下visudo
- add-month使用
- 民间不传的53个秘密
- 文件的权限问题--数据库不能添加新记录
- OpenCV 资源
- JS获取浏览器窗口大小 获取屏幕,浏览器,网页高度宽度
- Asp添加文字水印