在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 在mini2440上面搞定CC2500物理層驅動

            在mini2440上面搞定CC2500物理層驅動

            作者: 時間:2016-11-19 來源:網(wǎng)絡 收藏
            1. 寫在前面

            最近基本搞定了CC2500在linux下面的驅動,在這個過程中遇到了好多問題,特此總結出來和大家分享。但是需要注意的事情是:
            第一,本文不負責程序的具體講解,諸如每一行程序都講什么:這個在程序的里面有注釋。本篇文章更側重于從整體結構上讓大家對于linux下的CC2500DE驅動有一個整體的了解,如果到時候需要深入研究的時候,再來看具體的代碼;
            第二,很多師弟師妹沒有習慣在linux下編程,或曰,在操作系統(tǒng)下面寫程序;并且,對于本專業(yè)的東西理解并不扎實。但是,文章中不可能就每一個涉及到的概念都大加講解。因此,這篇文章還是需要有一些基礎才能來閱讀的,如果遇到什么不明白的地方,請及時來問我,或者跟帖,或者自己查資料。畢竟,這個驅動花費了我半個多月的時間,其中遇到的問題,不可能在一篇文章中就講得清清楚楚。


            1. 背景知識

            如果大家看過實驗室的WSN方面的程序,可能會被其中的架構搞得天昏地暗。這里,簡單的幫助大家把實驗室的WSN的軟件、硬件方面捋一捋。
            說到軟件,就不能不說硬件。我們的節(jié)點由兩部分組成,一個是單片機,一個是CC2500的射頻模塊。射頻模塊通過SPI接口和單片機進行通信。除了SPI模塊用到的4條線,實際上CC2500還需要告訴單片機“我接收到一個數(shù)據(jù)”,這個地方CC2500可以通過配置GDO來實現(xiàn)。我們這里采用的CC2500的GDO0作為單片機的一個外部中斷,當接收到數(shù)據(jù)的時候,GDO0就會變?yōu)榈碗娖?,然后觸發(fā)CC2500的中斷,從而接收數(shù)據(jù)。
            那么,CC2500究竟是如何來進行數(shù)據(jù)發(fā)送、接收的呢?其實很簡單。如果大家稍微用過一點可以控制的芯片就會知道,很多芯片內(nèi)部都有寄存器,CC2500之所以能夠完成發(fā)送、接收的功能,就是通過配置寄存器來完成的。比較重要的配置有信道、波特率、信號強度等等,另外,CC2500還有64bytes的RXFIFO和64bytes的TXFIFO,他們的作用就是用來發(fā)送和接收。當配置CC2500結束之后,如果用來發(fā)送,那么就把數(shù)據(jù)放在TXFIFO里面,然后把CC2500的狀態(tài)變?yōu)榘l(fā)射狀態(tài),數(shù)據(jù)就自動發(fā)送出去了。同樣的道理,當RXFIFO里面接收到了數(shù)據(jù)之后,CC2500就會如前所說,發(fā)出一個中斷,通知單片機來讀取數(shù)據(jù)。
            單片機通過SPI接口讀出了CC2500中的數(shù)據(jù),就需要進行簡單的處理了。我們的節(jié)點是遵循802.15.4協(xié)議的,如果有興趣,大家可以去看一看這個協(xié)議的內(nèi)容。對于我們來說,比較重要的就是幀的結構。下面這個是物理層幀的結構:
            字節(jié):4
            1
            1
            可變
            先導碼
            幀定界符

            幀長度(7位)

            保留位(1位)
            負載內(nèi)容

            同步頭

            PHY頭

            PHY負載

            簡單的講,因為是無線通信,沒有一個時鐘的存在,因此本質上所有的無線通信都是一個異步的通信。那么,就需要發(fā)送和接收的雙方首先對數(shù)據(jù)進行同步——這個就是同步頭的作用。隨后的是PHY的頭,很簡單,就是一個長度。換句話說,每個幀不能夠超過2的8次方減一個數(shù)據(jù)(127個)。隨后就是負載的內(nèi)容了,簡單吧?另外,由于CC2500是一個802.15.4兼容的芯片,這一部分內(nèi)容都已經(jīng)固化在芯片里面了,像同步頭這種東西,都是芯片幫我們完成(當然也可以自行配置)。我們只需要把寫入的數(shù)據(jù)大小和數(shù)據(jù)內(nèi)容寫入即可。
            雖然簡單,但是還有一個問題:每次從CC2500中讀取了數(shù)據(jù),存放到哪里呢?有的同學可能想的比較簡單,比如建立一個大數(shù)組,收到多少個數(shù),放在里面就行了。但是,這樣就會遇到問題:如果收到了兩個包,上層來不及處理怎么辦?建立兩個大數(shù)組?更多的包呢?當然,我們可以通過建立好多個數(shù)組來解決這個問題。但是,從效率上講,這個是非常笨的一個辦法。因此,我們建立了一個環(huán)形緩沖區(qū)PHY_RX_BUFFER,來解決這個問題。環(huán)形緩沖區(qū)的具體原理不過多涉及,可以自行百度。
            另外一個問題就是,如果我們從CC2500中接收到了數(shù)據(jù),那么應該怎樣才能告訴上層來進行處理呢?這里就要用到操作系統(tǒng)的消息機制了。如果確定接收到了一個數(shù)據(jù),那么就給上層發(fā)送一個消息,來通知上層。上層接收到這個消息,就會知道接收到了數(shù)據(jù)。
            當從CC2500讀取到了數(shù)據(jù),因為物理層沒有什么東西,我們就直接通知MAC層來處理數(shù)據(jù)。MAC層的結構如下:
            字節(jié):2
            1
            0/2
            0/2/8
            0/2
            0/2/8
            可變
            2
            幀控制域
            序列號
            目的PAN標示符
            目的地址
            源PAN標示符
            源地址
            幀負載
            FCS
            地址域
            MAC幀頭
            MAC負載
            MFR

            具體內(nèi)容可以參見老師的《無線傳感器網(wǎng)絡技術與工程應用》這本書,這里不再詳細的講,大概內(nèi)容就是,會有一系列的幀頭,然后是幀數(shù)據(jù),最后有校驗。而我們最關心的就是幀的內(nèi)容。但是,幀頭也比較麻煩,因此我們需要首先對幀頭進行處理,把數(shù)據(jù)給“剝離”出來,這也是基本上所有的協(xié)議棧解析協(xié)議的方法。


            1. 硬件結構

            硬件上,我們采用的是mini2440開發(fā)板,和實驗室的CC2500節(jié)點(把單片機焊掉,然后把mini2440的相應管腳接到上面)。


            Mini2440方面,我們用的是CON8這個引腳,具體連線如下:
            EINT8對應S3C2440的GPG0引腳,連接到了CC2500的GDO2
            EINT11對應S3C2440的GPG3引腳,連接到了CC2500的CSN
            EINT13對應S3C2440的GPG5引腳,連接到了CC2500的SO
            EINT14對應S3C2440的GPG6引腳,連接到了CC2500的SI
            EINT15對應S3C2440的GPG7引腳,連接到了CC2500的CLK
            EINT19對應S3C2440的GPG11引腳,連接到了CC2500的GDO0
            除此之外,還有3.3V電源和GND


            1. Linux下驅動編寫

            為什么要用驅動呢?簡單的說,就是為了在linux下完成用戶空間和內(nèi)核空間的交互。本質上,驅動就是完成了兩件事情:第一,初始化SPI接口,并且通過SPI和CC2500完成通信。第二,完成讀寫函數(shù),read和write,通過讀寫函數(shù)的接口來對CC2500進行操作。
            附件里面有幾個文件,這里簡單講解一下:
            Common.h主要是包含了很多l(xiāng)inux的頭文件,并且對一些數(shù)據(jù)類型做了定義
            CC2500.h里面主要是對CC2500的寄存器做了一些定義,沒啥東西
            Driver.h主要是定義了很多和CC2500進行通信,并且利用CC2500進行發(fā)送和接收的內(nèi)容
            Phy.h主要是完成了一些諸如信道設定、通信速率等功能,并且把CC2500里的數(shù)據(jù)讀到環(huán)形緩沖區(qū)里面
            CC2500.c這個就是完成設備注冊、讀寫函數(shù)、iocontrol等功能
            這樣有了一個整體的把握之后,不用看很多代碼,學會使用就好。


            1. 驅動接口使用

            那么,這個驅動怎樣使用呢?主要是通過read/write/ioctl三個接口來實現(xiàn)的。
            在應用程序中read/dev/CC2500這個文件,如果有數(shù)據(jù),會返回相應的數(shù)據(jù)。其中,返回的數(shù)據(jù)中第一個字節(jié)為數(shù)據(jù)的長度(不包括該字節(jié)本身),后面為相應的數(shù)據(jù)。
            如果是寫文件的話,只需要向/dev/CC2500中寫入相應的數(shù)據(jù)即可。寫入的時候需要注意,第一個字節(jié)同樣為數(shù)據(jù)長度(不包括該字節(jié)本身),后面跟相應的數(shù)據(jù)。當寫入的字節(jié)合適的時候,驅動會自動執(zhí)行發(fā)送函數(shù)。如果寫入的字節(jié)數(shù)量和寫入的數(shù)據(jù)第一個字節(jié)不匹配的時候,會返回錯誤。
            ioctl主要有這樣幾種命令:


            CC2500_IOC_PHY_DETECT_STATUS
            表示將CC2500的狀態(tài)變?yōu)镽X
            CC2500_IOC_PHY_GET_BAUDRATE
            讀取CC2500的波特率,返回的是1,2,3,4,分別是2.4k,10k,250k,500k的波特率
            CC2500_IOC_PHY_SET_BAUDRATE
            設定CC2500的波特率,后面的參數(shù)是1,2,3,4,分別是2.4k,10k,250k,500k的波特率
            CC2500_IOC_PHY_GET_TXPOWER
            獲取發(fā)送功率,返回的是在發(fā)送功率表{0x00, 0x50, 0x44, 0xC0, 0x84, 0x81, 0x46, 0x93, 0x55, 0x8D, 0xC6,0x97, 0x6E, 0x7F, 0xA9, 0xBB, 0xFE, 0xFF }中的數(shù)組下標
            CC2500_IOC_PHY_SET_TXPOWER
            設定發(fā)送功率,參數(shù)的是在發(fā)送功率表{0x00, 0x50, 0x44, 0xC0, 0x84, 0x81, 0x46, 0x93, 0x55, 0x8D, 0xC6,0x97, 0x6E, 0x7F, 0xA9, 0xBB, 0xFE, 0xFF }中的數(shù)組下標
            CC2500_IOC_PHY_GET_CHANNEL
            獲取頻段,參數(shù)是頻段表{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,0xB0, 0xC0, 0xD0, 0xE0, 0xF0 }中的數(shù)組下標
            CC2500_IOC_PHY_SET_CHANNEL
            設定頻段,參數(shù)是頻段表{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,0xB0, 0xC0, 0xD0, 0xE0, 0xF0 }中的數(shù)組下標


            1. 應用層程序編寫

            這里的應用層主要是將mac層實現(xiàn)了。其實,mac層的作用也很簡單,主要是對要發(fā)送的包進行封裝,接收回來的包進行包的解析。這一部分的內(nèi)容還不全面,僅僅是將原來的程序移植過來,還有很多需要改動的地方,有待補充。因此,這里只是提供源代碼,具體的說明請參見程序內(nèi)部


            1. 如何配置內(nèi)核文件

            1首先修改/opt/FriendlyARM/mini2440/linux-2.6.32.2/drivers/char/Kconfig
            加入如下幾句話:
            config CC2500_DRIVER


            tristate "CC2500 driverfor FriendlyARM Mini2440 development boards"


            depends on MACH_MINI2440


            default m if MACH_MINI2440


            help


            this is CC2500 driver forFriendlyARM Mini2440 development boards




            2修改Makefile,讓CC2500的驅動可以編譯。
            加入如下幾句話:


            obj-$(CONFIG_CC2500_DRIVER) +=CC2500inuse.o


            CC2500inuse-objs :=./CC2500.in_use/cc2500.o ./CC2500.in_use/phy.o./CC2500.in_use/driver.o


            其中,CONFIG_CC2500_DRIVER需要和Kconfig中的configCC2500_DRIVER
            保持一致。
            CC2500inuse-objs這句話,意思是CC2500inuse.ko是由哪幾個文件組成的。這樣就實現(xiàn)了模塊化的處理。
            需要注意的是,CC2500inuse-objs和冒號之間需要有個空格,不然會出錯誤。這個地方我搞了好久。
            具體的Makefile的格式也可以參考這兩篇文章:
            http://blog.csdn.net/tommy_wxie/article/details/7282463
            http://hi.baidu.com/wjq_qust/blog/item/97ddbdfdfb2e541309244d30.html


            1. 調試過程中的一些問題

            CC2500驅動調試的過程中,遇到的一些問題
            第一,在調試的過程中,發(fā)現(xiàn)板子和2500沒有辦法進行通信。一開始懷疑是2500芯片的問題,后來確認2500芯片沒有問題之后,用示波器看了一下波形,發(fā)現(xiàn)SPI引腳上沒有輸出。進而發(fā)現(xiàn),對SPI寄存器進行讀寫的時候,無論寫入是什么,讀出的都是0。后來發(fā)現(xiàn),原來是PCLK(也就是SPI模塊的時鐘)沒有使能,囧。設置了寄存器之后,問題就解決了。
            第二,CC2500驅動沒有辦法自動在/dev/目錄下面創(chuàng)建節(jié)點。這個問題可以參考下面幾篇文章:
            http://blog.csdn.net/cjok376240497/article/details/6848536
            整體來說,創(chuàng)建節(jié)點的工作是這樣的:
            我們通過udev來創(chuàng)建節(jié)點。但是,udev是應用層的東東,不要試圖在內(nèi)核的配置選項里找到它;加入對udev的支持很簡單,只要在驅動初始化的代碼里調用class_create為該設備創(chuàng)建一個class,再為每個設備調用class_device_create創(chuàng)建對應的設備。
            換句話說,首先要為每一個設備創(chuàng)建一個類。然后用這個類去申請一個設備節(jié)點。
            第三,在調試的過程中,發(fā)現(xiàn)只要一啟動CC2500,那么液晶屏就熄滅了。調試了半天也沒有找到原因。
            最后發(fā)現(xiàn),在配置S3C2440中GPGCON寄存器的時候,對寄存器直接進行了覆蓋性的修改;而該寄存器還管理著LCD的電源...于是,對寄存器進行覆蓋性修改的時候,悲劇了...
            總結一下吧,在linux下2500驅動編寫的過程中,如果涉及到寄存器級別的操作,和單片機一樣,必須十分注意各個模塊之間的關系,以及相關模塊的寄存器配置,不要認為linux會全部給你配好!


            評論


            技術專區(qū)

            關閉