|
1. 文檔中的一個小錯誤 ![]() wlan_ioctl_get_scan_results 函數(shù)用于返回WLAN掃描的結果,每調用一次返回一個結果。返回的數(shù)據結構在文檔中給出,但是這里文檔寫錯了。。。Result entry前的56bytes應該是42bytes,而每次的結果總有有4+4+42=50(bytes)。把下面的結果加起來,也會發(fā)現(xiàn)各項的和是42 而不是56. 這本來只是手冊上的一個筆誤,但在編程時,大家通常會使用一個結構體來接收返回的數(shù)據,如果這個字節(jié)數(shù)不對的話,就會影響內存對齊,從而導致返回的結果錯誤。這里,我使用的結構體定義如下:
另外,這個函數(shù)讀到最后一條結果時,再讀會返回一個長度為0的結果,即前四個字節(jié)(number of networks found)為零,然后再讀才會讀出下一次掃描的結果。這一點手冊上并沒有指出,是我們在編程實踐中自己發(fā)現(xiàn)的。
2. SpiPause - SpiResume與WlanInterruptDisable - WlanInterruptEnable的實現(xiàn)
如 果前面一條是一個小坑的話,這一條絕對是一個大坑。目前為止,我見過的CC3000的驅動實現(xiàn)中,不論是開源的、產品正在開發(fā)而尚未開源的實現(xiàn),除了官方 的例程以外,還沒有人將這兩組函數(shù)寫對。甚至有人能通過降低SPI速率、修改IO中斷方式等等辦法,使得整個程序得以正常運行,將錯誤帶到了產品中。只要 有人說:“我的CC3000驅動有點問題,調了很久都不行。。?!敝惖脑?,不用等他說完,就可以猜想他是把這兩組函數(shù)寫錯了。
這兩組函數(shù)非常容易錯,錯了又非常難以發(fā)現(xiàn)。這兩組函數(shù)的實現(xiàn)已經成為了CC3000驅動移植的主要障礙。其主要原因如下:
(1)是官方的Porting Guide沒有明確指出這兩組函數(shù)的區(qū)別。很多人則想當然地認為這兩組函數(shù)是一樣的。甚至是一組中調用另一組。再看官方的實現(xiàn),又有點不知所云,所以就忽略了這個問題。
(2) 忽略這個問題后,CC3000模塊可以正常初始化,還可以正常掃描WiFi熱點,有人還能正常進行Smart config,甚至有人還能正常打開socket并使用UDP協(xié)議發(fā)送數(shù)據!開發(fā)者根據CC3000驅動自下而上分層的架構來看,看到SPI已經可以進行 正常通信,從而直接在心理上排除了SPI驅動實現(xiàn)有誤的可能性,錯誤查來查去還是在原地兜圈子。
(3)由于這兩組函數(shù)實現(xiàn)有誤導致的錯誤幾乎成了一個人品問題,在不同速度MCU上的錯誤實現(xiàn)會導致不同的錯誤現(xiàn)象,以至于大家的描述不統(tǒng)一,很難從現(xiàn)象判斷到底是哪兒錯了,即使在網上根據錯誤現(xiàn)象搜索或者發(fā)帖求助,也很難得到有針對性的答案。
為什么這兩組函數(shù)寫錯了,會有這么神奇的問題呢?答案就是,這里的錯誤會導致程序的“競態(tài)問題”,類似于數(shù)字電路基礎中的“競爭冒險”。SPI速率、AP的品質和信號強度、IO口翻轉速度、延時的誤差等無關緊要的問題,都可能讓競態(tài)問題出現(xiàn)不同的現(xiàn)象。因此,出現(xiàn)的錯誤現(xiàn)象千奇百怪,貌似跟人品有關就不難解釋了。說了這么多,下面就來解釋一下這兩組函數(shù)到底有什么區(qū)別:
WlanInterruptDisable的作用是關閉IO口的外部中斷,也就是IRQ的下降沿中斷。關閉以后,IRQ下降沿的中斷將被丟棄,在調用WlanInterruptEnable時,會重新使能中斷,之后發(fā)生在該IO上的外部中斷又再次可以響應。而中斷被禁用期間,發(fā)生的中斷都被丟棄,永遠不再響應。這個函數(shù)一般人都寫對了。
SpiPauseSpi函數(shù)是暫時掛起IO口外部中斷,也就是IRQ下降沿中斷,如果在SpiPauseSpi調用之后,IRQ線上再有下降沿,該中斷將一直保持Pending狀態(tài),暫時不調用中斷服務程序,該中斷必須在調用SpiResumeSpi被重新響應,而不能被丟棄。這里,很多很多很多人,都,寫錯了。。。
這種中斷的響應方式比較特殊,像STM32就沒有在標準驅動庫中實現(xiàn)相應的API,而必須通過操作寄存器的方式來手工實現(xiàn)。相應寄存器的定義,既不在芯 片Datasheet里,也不在那份大家熟知的STM32F1系列Reference Manual(RM0008)里,而是在很多STM32開發(fā)者都沒有聽說過的一份文檔PM0056——STM32F10xxx/20xxx/21xxx/L1xxxx Cortex-M3 programming manual里。有很多MCU,甚至包括TI的MSP430,在硬件上根本就不支持這種響應方式,因此只能用一些猥瑣的方法來實現(xiàn)。MSP430該函數(shù)的代碼居然是向一個配置為輸入的IO口寫數(shù)據,足以讓不熟悉MSP430的開發(fā)者撓頭了。
STM32F103上的實現(xiàn)如下
另外一組的實現(xiàn)是
3. TI提供的CC3000 Host Driver假設char類型是無符號的
這個問題可能很多人都不會遇到,因為在嵌入式開發(fā)中char通常都是無符號的,基本所有的用于嵌入式平臺的編譯器默認情況下都會這樣設定。而我則比較習慣PC上有符號的char,所以我手賤給GCC加了一個編譯參數(shù)-fsigned-char......
TI 的Host Driver就比較扯淡,它假設char是無符號的,并且在char有符號時就會因符號位在強制轉換中的行為不同而出錯。這個問題不容易排查,因為需要跟 蹤到TI實現(xiàn)的Host Driver里,而大家通常都會假設這個實現(xiàn)是沒錯的,能跟進去就是一種勇氣了……我當時遇到這個問題時,不知道是哪兒的錯誤,就在很多回調函數(shù)中添加了 串口打印的語句,通過串口輸出,觀察各個函數(shù)被調用的情況,結合現(xiàn)象,再加以大膽的猜想,才解決了這個問題。
4. 供電
![]() 看 看德州儀器官方WiFi模塊(TI的WiFi模塊封裝尺寸和引腳定義與WG1300完全相同,本人咨詢Jorjin總代理后得知TI的官方模塊正是由 Jorjin設計并制造的,與WG1300相比在硬件上也是完全一樣的,只是外殼上的字不同而已) 的文檔后,不禁大吃一驚!發(fā)送電流峰值275mA,接收峰值103mA,合起來有接近400mA的峰值電流!正是因為如此,我120mA的LDO被瞬間秒 殺,電壓從3.3V拉到了2.6V……我居然還不知道!因為STM32可以在2.6V下正常工作,我的還是在各種加斷點、各種單步跟蹤,完全沒有意識到模 塊已經因電壓過低死機了。。??戳艘幌耂parkcore的電路圖,發(fā)現(xiàn)它用的LDO型號是MIC5219,一個SOT23-5封裝,500mA的 LDO,哈哈~
另外還有一個不算是坑,或者說只是一個小坑~就是security.h文件最后少了一段代碼,在用C++編譯時可能導致編譯出錯,并且把錯誤報到別的文件里,讓人很困惑。。。缺少的代碼如下,大家一看就懂了~
#ifdef __cplusplus
}
#endif
|
|
|