基于散列DMA的高速串口驅(qū)動(dòng)方案設(shè)計(jì)
3.2 驅(qū)動(dòng)程序設(shè)計(jì)
串口驅(qū)動(dòng)程序的核心是實(shí)現(xiàn)數(shù)據(jù)高效穩(wěn)定的收發(fā)。為了實(shí)現(xiàn)UART的高速數(shù)據(jù)傳輸,UART中斷設(shè)置為最高優(yōu)先級(jí);同時(shí)在操作系統(tǒng)中允許中斷嵌套,打開(kāi)UART接收超時(shí)中斷RTI并使能UART的DMA傳輸。這樣,當(dāng)UART的發(fā)送FIFO數(shù)據(jù)減少到設(shè)定的參考值(FIFOLevel)時(shí),發(fā)送DMA傳輸就會(huì)被觸發(fā)。同樣,當(dāng)接收FIFO的數(shù)據(jù)增長(zhǎng)到設(shè)定值時(shí),接收DMA傳輸就會(huì)被觸發(fā)。為了減少DMA傳輸被觸發(fā)的次數(shù)同時(shí)保證數(shù)據(jù)被及時(shí)傳輸,發(fā)送FIFO Level設(shè)定為2字節(jié),而接收FIFOLevel設(shè)定為14字節(jié),將發(fā)送和接收的FIFO Level分別設(shè)定為0和16字節(jié)是有很大風(fēng)險(xiǎn)的。MPI協(xié)議要求傳輸?shù)囊粠瑪?shù)據(jù)不能有間斷,所以在使用DMA傳輸U(kuò)ART數(shù)據(jù)時(shí)DMAC必須獨(dú)占系統(tǒng)總線。為了避免產(chǎn)生緩存一致性問(wèn)題,使用2塊非緩存內(nèi)存區(qū)域存放待發(fā)送的數(shù)據(jù)和已接收到的數(shù)據(jù)。
發(fā)送數(shù)據(jù)時(shí),待發(fā)送的數(shù)據(jù)量總是已知的。先構(gòu)造一個(gè)傳輸節(jié)點(diǎn),數(shù)據(jù)源地址為數(shù)據(jù)包的首地址,目的地址為UART寄存器,數(shù)據(jù)位寬為8,下一節(jié)點(diǎn)指針(PTR_NEXT)為空。當(dāng)前數(shù)據(jù)包發(fā)送結(jié)束前,如果PTR_NEXT被更新,則下一個(gè)數(shù)據(jù)包的傳輸自動(dòng)開(kāi)始。當(dāng)前數(shù)據(jù)包是否發(fā)送完畢,可通過(guò)讀取DMAC寄存器DMACCnControl的TransferSize字段得知。整個(gè)發(fā)送數(shù)據(jù)的過(guò)程無(wú)需觸發(fā)任何中斷,流程圖如圖3所示。如果采用DMA塊傳輸方式,就需要在每次傳輸完畢后產(chǎn)生DMA中斷,重新裝載數(shù)據(jù)到內(nèi)存中的發(fā)送數(shù)據(jù)區(qū)以發(fā)送下一個(gè)數(shù)據(jù)包。
接收數(shù)據(jù)時(shí),對(duì)方發(fā)過(guò)來(lái)的數(shù)據(jù)量一般是未知的。構(gòu)造含有100個(gè)節(jié)點(diǎn)的循環(huán)鏈表結(jié)構(gòu),每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的傳輸塊大小為接收FIFO Level。數(shù)據(jù)源地址為UART數(shù)據(jù)寄存器的地址,首節(jié)點(diǎn)的目的地址為接收數(shù)據(jù)內(nèi)存區(qū)域的首地址,此后節(jié)點(diǎn)的目的地址每次向后偏移(FIFO Level×2)個(gè)字節(jié),數(shù)據(jù)位寬為16(8個(gè)數(shù)據(jù)位,4個(gè)狀態(tài)位,4個(gè)保留位)。當(dāng)接收到的數(shù)據(jù)達(dá)到接收內(nèi)存區(qū)域的80%(RECV_TH)時(shí),需要通知數(shù)據(jù)發(fā)送方停止數(shù)據(jù)傳輸,在第80個(gè)節(jié)點(diǎn)處設(shè)置DMA中斷,該節(jié)點(diǎn)為閾值節(jié)點(diǎn)。采用本文的設(shè)計(jì)方案接收1幀不超過(guò)RECV_TH大小的數(shù)據(jù),最多產(chǎn)生一次RTI中斷。當(dāng)接收到的數(shù)據(jù)量少于FIFOLevel時(shí)不會(huì)觸發(fā)DMA接收,在RTI中斷中把UART接收FIFO中的數(shù)據(jù)復(fù)制到內(nèi)存中的數(shù)據(jù)接收區(qū),同時(shí)使DMA接收節(jié)點(diǎn)的目的地址向后偏移相應(yīng)的長(zhǎng)度并更新閾值節(jié)點(diǎn)的位置。接收數(shù)據(jù)流程如圖4所示。如果采用DMA塊傳輸方式,就必須額外使用一個(gè)環(huán)形數(shù)據(jù)緩沖區(qū)(Ring Buffer),每次接收到指定大小的數(shù)據(jù)塊后產(chǎn)生DMA中斷,在中斷服務(wù)程序中將接收到的數(shù)據(jù)復(fù)制到環(huán)形數(shù)據(jù)緩沖區(qū)中。
3.3驅(qū)動(dòng)測(cè)試
本文的設(shè)計(jì)方案直接應(yīng)用于工業(yè)級(jí)的HMI產(chǎn)品,必須經(jīng)過(guò)嚴(yán)格的測(cè)試。利用3臺(tái)西門子S7系列PLC和1臺(tái)產(chǎn)品樣機(jī)搭建令牌網(wǎng),使用西門子MPI協(xié)議進(jìn)行測(cè)試,并利用數(shù)據(jù)分析工具ProfiTrace監(jiān)測(cè)通信過(guò)程。測(cè)試結(jié)果表明,2 400 bps~12 Mbps的各個(gè)波特率下都能進(jìn)行穩(wěn)定的數(shù)據(jù)通信。
4 結(jié) 語(yǔ)
本文詳細(xì)介紹了DMA數(shù)據(jù)傳輸?shù)奶攸c(diǎn)和散列DMA的工作方式。在此基礎(chǔ)上,提出了一套基于散列DMA的高速串口驅(qū)動(dòng)設(shè)計(jì)方案,發(fā)送數(shù)據(jù)完全由DMAC完成,無(wú)需觸發(fā)任何中斷,接收1幀不超過(guò)接收區(qū)閾值的數(shù)據(jù)最多產(chǎn)生1次RTI中斷。和現(xiàn)有的各種利用DMA塊傳輸進(jìn)行串口數(shù)據(jù)通信的方案相比,中斷次數(shù)大幅減少,大大提高了數(shù)據(jù)傳輸?shù)男?。在?yīng)用了本方案的人機(jī)界面產(chǎn)品上,實(shí)現(xiàn)了波特率高達(dá)12 Mbps的穩(wěn)定數(shù)據(jù)傳輸。對(duì)于在其他平臺(tái)上設(shè)計(jì)實(shí)現(xiàn)高速串口,本方案是一個(gè)很好的參考。本文引用地址:http://m.butianyuan.cn/article/149508.htm
評(píng)論