新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 串口驅(qū)動(Serial Drivers)編寫實例解讀

串口驅(qū)動(Serial Drivers)編寫實例解讀

作者: 時間:2011-03-12 來源:網(wǎng)絡(luò) 收藏
串口驅(qū)動(Serial Drivers)編寫實例解讀(連載:一)
[代碼步驟:Code Steps]
。初始化
。定義支持的串口通道數(shù)
。初始化驅(qū)動的設(shè)備描述
。寫你的設(shè)備初始化代碼
。寫入口程序(entry point routines)
。寫ISRs(中斷服務(wù)程序)來管理設(shè)備
。使用模板 wind/target/src/drv/ssio/templateSio.c

注意:串口驅(qū)動在VxWorks系統(tǒng)開始的代碼里初始化

[設(shè)備描述:The Device Descriptor]
。XX_DRV結(jié)構(gòu)每個通道有一個XX_CHAN
。每個XX_CHAN指向SIO_DRV_FUNCS
。SIO_DRV_FUNCS引誘驅(qū)動的入口(entry point)

。XX_DRV是xxDrv使用的中心數(shù)據(jù)結(jié)構(gòu)
。xx_CHAN包括:
。xxDrv需要的通道特定信息
。指向驅(qū)動SIO_DRV_FUNCS結(jié)構(gòu)的指針
。例:
/* device and channel structures */

typedef struct
{
/* must be first */

SIO_CHAN sio; /* standard SIO_CHAN element */

/* callbacks */

STATUS (*getTxChar) ();
STATUS (*putRcvChar) ();
void * getTxArg;
void * putRcvArg;

/* register addresses */

volatile char * cr; /* channel control register */
volatile char * dr; /* channel data register */
volatile char * sr; /* channel status register */
volatile char * ms; /* channel modem status register */
volatile char * mc; /* channel modem control register */
volatile short * br; /* channel baud constant register */

/* misc */

int mode; /* current mode (interrupt or poll) */
int baudFreq; /* input clock frequency */
int options; /* Hardware options */
} TEMPLATE_CHAN;

typedef struct
{
TEMPLATE_CHAN portA; /* DUSRAT has two channels */
TEMPLATE_CHAN portB;
volatile char * masterCr; /* master control register */
} TEMPLATE_DUSART;

[SIO_CHAN結(jié)構(gòu)]
。對一般字符驅(qū)動,一個指向DEV_FDR的指針被用來在驅(qū)動和I/O system 之間通訊
。對一個串口驅(qū)動,一個指向SIO_CHAN的指針用來在驅(qū)動和高層協(xié)議之間通訊

在 wind/target/h/sioLib.h;里,SIO_CHAN如下定義:
typedef struct sio_chan/* a serial channel */
{
SIO_DRV_FUNCS * pDrvFuncs;
/* device data */
} SIO_CHAN;

.由于高層協(xié)議不知道驅(qū)動的XX_CHAN結(jié)構(gòu),SIO_CHAN被用來允許一個精心定義的數(shù)據(jù)類型在協(xié)議間交換數(shù)據(jù)
.ttyDrv通過SIO_DRV_FUNCS里的入口向xxDrv發(fā)送信息,而xxDrv通過回調(diào)向ttyDrv發(fā)送信息
[入口:Entry Points]
xxCallBackInstall() 安裝到高層協(xié)議的入口(I/O system,target agent(目標代理),等等)
xxPollOutPut() 輪巡模式輸出
xxPollInput() 輪巡模式輸入
xxIoctl() 支持設(shè)備特定的ioctl命令
xxTxStaartup() 初始化一個傳輸循環(huán)(transmit cycle)

[驅(qū)動回調(diào)安裝程序]
int xxCallbackInstall(pSsioChan,callbackType,callback,callbbackArg)
pSioChan 指向SIO_CHAN的指針
callbackType SIO_CALLBACK_GET_TX_CHAR 或 SIO_CALLBACK_PUT_RCV_CHAR
callback 指向回調(diào)程序的指針
callbackArg 回調(diào)的參數(shù)
。初始化SIO_CHAN結(jié)構(gòu)里的特定成員
。返回OK 或 ENOSYS(當callbackType不是上兩種中的一種)
/********************************************************************************
templateCallbackInstall - install ISR callbacks to get/put chars
This driver allows interrupt callbacks for transmitting characters
and receiving characters. In general, drivers may support other
types of callbacks too.
*
* RETURNS: OK on success, or ENOSYS for an unsupported callback type.*/
LOCAL int templateCallbackInstall
(
SIO_CHAN * pSioChan, /* channel */
int callbackType, /* type of callback */
STATUS (*callback)(), /* callback */
void * callbackArg /* parameter to callback */
)
{
TEMPLATE_CHAN * pChan = (TEMPLATE_CHAN *)pSioChan;

switch (callbackType)
{
case SIO_CALLBACK_GET_TX_CHAR:
pChan->getTxChar = callback;
pChan->getTxArg = callbackArg;
return (OK);

case SIO_CALLBACK_PUT_RCV_CHAR:
pChan->putRcvChar = callback;
pChan->putRcvArg = callbackArg;
return (OK);

default:
return (ENOSYS);

}
}
[驅(qū)動初始化]
。參數(shù)是沒一個指向XX_DRV的指針
。初始化XX_CHAN
。帶你的程序的SIO_DRV_FUNCS
??芑卣{(diào)
。所有設(shè)備特定
。重啟芯片
/* local variables */

LOCAL SIO_DRV_FUNCS templateSioDrvFuncs =
{
templateIoctl,
templateTxStartup,
templateCallbackInstall,
templatePollInput,
templatePollOutput
};
void templateDevInit
(
TEMPLATE_DUSART * pDusart
)
{
/* initialize each channel"s driver function pointers */

pDusart->portA.sio.pDrvFuncs = templateSioDrvFuncs;
pDusart->portB.sio.pDrvFuncs = templateSioDrvFuncs;

/* install dummy driver callbacks */

pDusart->portA.getTxChar = dummyCallback;
pDusart->portA.putRcvChar = dummyCallback;
pDusart->portB.getTxChar = dummyCallback;
pDusart->portB.putRcvChar = dummyCallback;

/* reset the chip */

TEMPLATE_REG_WRITE(pDusart, masterCr,
TEMPLATE_RESET_CHIP);

/* setting polled mode is one way to make the device quiet */

templateIoctl ((SIO_CHAN *)pDusart->portA, SIO_MODE_SET,
(void *)SIO_MODE_POLL);
templateIoctl ((SIO_CHAN *)pDusart->portB, SIO_MODE_SET,
(void *)SIO_MODE_POLL);
}
/*******************************************************************************
*
* dummyCallback - dummy callback routine
*
* RETURNS: ERROR.
*/

LOCAL STATUS dummyCallback (void)
{
return (ERROR);
}
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)


評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉