本章為系列指南的第七章,講述如何在之前的基礎(chǔ)上,編寫程序在STM32上發(fā)送一個(gè)網(wǎng)絡(luò)包,并使用WireShark進(jìn)行驗(yàn)證。
先回顧一下之前的章節(jié)我們做好的準(zhǔn)備工作,在《STM32F4+DP83848以太網(wǎng)通信指南第五章:MAC+DMA配置》結(jié)束時(shí)我們封裝了一個(gè)DP83848的初始化函數(shù),該函數(shù)完成了PHY的配置,MAC層的配置,DMA的配置,并且啟用了以太網(wǎng)中斷,函數(shù)命名為DP83848Init(),那么今天,我們要做的主要任務(wù)就是編寫一個(gè)類似的DP83848Send(u8* data, u16 length)函數(shù)。
可以在本章的一開始跟大家劇透一個(gè)好消息,有了《STM32F4+DP83848以太網(wǎng)通信指南第四章:PHY配置》 和 《STM32F4+DP83848以太網(wǎng)通信指南第五章:MAC+DMA配置》 的基礎(chǔ),我們本章最終實(shí)現(xiàn)的DP83848Send(u8* data, u16 length)函數(shù),只有兩行代碼,非常非常簡單。這兩行代碼我暫時(shí)先不貼出來,我們來順著原來的思路,根據(jù)相關(guān)文檔和官方示例代碼,順藤摸瓜,一步一步深入了解以太網(wǎng)發(fā)包的流程,最終理解體系結(jié)構(gòu)后,也就水到渠成能夠?qū)懗鰜砹恕?p>在 《STM32F4+DP83848以太網(wǎng)通信指南第五章:MAC+DMA配置》 最后一部分提到在LWIP官方樣例中,路徑為STM32F4x7_ETH_LwIP_V1.1.1UtilitiesThird_Partylwip-1.4.1portSTM32F4x7Standaloneethernetif.c的文件中,第76行有個(gè)low_level_init()函數(shù),該函數(shù)調(diào)用ETH庫函數(shù)對MAC底層及DMA進(jìn)行了初始化。同樣的,這份文件的138行,有個(gè)名為low_level_output(struct netif *netif, struct pbuf *p)的函數(shù),疑似是向外輸出網(wǎng)絡(luò)包的函數(shù),下面就對這部分代碼進(jìn)行分析,并試著用其中的核心邏輯進(jìn)行測試。
因?yàn)閑thernetif.c這份代碼本身隸屬于LWIP,而我們是不使用LWIP的,所以這份代碼只能盡量去看懂和借鑒,想要原封不動(dòng)地使用是不可以的。
我們先完整地貼出這個(gè)函數(shù):
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t low_level_output(struct netif *netif, struct pbuf *p) {
err_t errval;
struct pbuf *q;
u8 *buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);
__IO ETH_DMADESCTypeDef *DmaTxDesc;
uint16_t framelength = 0;
uint32_t bufferoffset = 0;
uint32_t byteslefttocopy = 0;
uint32_t payloadoffset = 0;
DmaTxDesc = DMATxDescToSet;
bufferoffset = 0;
/* copy frame from pbufs to driver buffers */
for(q = p; q != NULL; q = q->next) {
/* Is this buffer available? If not, goto error */
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) {
errval = ERR_BUF;
goto error;
}
/* Get bytes in current lwIP buffer */
byteslefttocopy = q->len;
payloadoffset = 0;
/* Check if the length of data to copy is bigger than Tx buffer size*/
while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) {
/* Copy data to Tx buffer*/
memcpy( (u8_t *)((u8_t *)buffer + bufferoffset), (u8_t *)((u8_t *)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) );
/* Point to next descriptor */
DmaTxDesc = (ETH_DMADESCTypeDef *)(DmaTxDesc->Buffer2NextDescAddr);
/* Check if the buffer is available */
if((DmaTxDesc->Status & ETH_DMATxDesc_OWN) != (u32)RESET) {
errval = ERR_USE;
goto error;
}
buffer = (u8 *)(DmaTxDesc->Buffer1Addr);
byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset);
payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset);
framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset);
bufferoffset = 0;
}
/* Copy the remaining bytes */
memcpy( (u8_t *)((u8_t *)buffer + bufferoffset), (u8_t *)((u8_t *)q->payload + payloadoffset), byteslefttocopy );
bufferoffset = bufferoffset + byteslefttocopy;
framelength = framelength + byteslefttocopy;
}
/* Note: padding and CRC for transmitted frame
are automatically inserted by DMA */
/* Prepare transmit descriptors to give to DMA*/
ETH_Prepare_Transmit_Descriptors(framelength);
errval = ERR_OK;
error:
/* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
if ((ETH->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET) {
/* Clear TUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_TUS;
/* Resume DMA transmission*/
ETH->DMATPDR = 0;
}
return errval;
}
這個(gè)函數(shù)的官方注釋描述的就是用來向外發(fā)送以太網(wǎng)包的,函數(shù)中說要發(fā)的包在第二個(gè)參數(shù),類型為pbuf結(jié)構(gòu)體指針的參數(shù)p中,并且說了p可能是個(gè)鏈表,我們看到函數(shù)的兩個(gè)入?yún)⒍际墙Y(jié)構(gòu)體參數(shù),這兩個(gè)結(jié)構(gòu)體的定義我們不需要管,是LWIP自己封裝的一個(gè)結(jié)構(gòu)體。我們?nèi)ほE參數(shù)p的用法,在代碼片段的30行,使用q變量和for循環(huán)遍歷p,因此我們能夠確定p就是個(gè)頭尾相接的pbuf鏈表。繼續(xù)觀察遍歷體中的操作邏輯,我們看到整個(gè)for循環(huán)的主要目的就是在嘗試將q->payload中的byte,利用函數(shù)memcopy()向buffer變量中堆,并且做了一些長度的校驗(yàn),我們繼而去觀察一下buffer變量的定義,第19行的u8 *buffer = (u8 *)(DMATxDescToSet->Buffer1Addr);是一個(gè)比較重要的線索,由此我們可以抽絲剝繭出整體的邏輯,應(yīng)該就是將首尾相接的p遍歷出來,取其中每個(gè)元素的payload區(qū)域,向DMATxDescToSet->Buffer1Addr中壓。最后,第73行的ETH_Prepare_Transmit_Descriptors(framelength);調(diào)用了ETH庫中的函數(shù),實(shí)現(xiàn)了最終的結(jié)局,將網(wǎng)絡(luò)包發(fā)出去,入?yún)⒌膄ramelength應(yīng)該就是需要發(fā)出去的包長度,包內(nèi)容應(yīng)該就是通過DMA技術(shù),將內(nèi)存中的DMATxDescToSet->Buffer1Addr發(fā)出去了。
有了以上針對low_level_output()函數(shù)的分析,我們來做實(shí)驗(yàn)印證一下,因?yàn)槲覀儚牧汩_始構(gòu)建的項(xiàng)目沒有LWIP,也沒有ethernetif.c,更沒有l(wèi)ow_level_output()函數(shù),因此,函數(shù)內(nèi)部的邏輯都需要我們自己手動(dòng)實(shí)現(xiàn),慢著,不要一看到「手動(dòng)實(shí)現(xiàn)」就頭疼,你以為手動(dòng)實(shí)現(xiàn)就很復(fù)雜嗎?不,LWIP把事情搞復(fù)雜了,又是pbuf又是鏈表的,還有長度判斷導(dǎo)致的Buffer2NextDescAddr切換(詳見第43-62行一整段,不過不重要),如果我們手動(dòng)寫這段邏輯,放棄一些異常處理,再放棄那些跟LWIP強(qiáng)相關(guān)的結(jié)構(gòu)體,我們整個(gè)發(fā)包函數(shù)只要兩行就行:
void DP83848Send(u8* data, u16 length){
memcpy((u8 *)DMATxDescToSet->Buffer1Addr, data, length);
/* Prepare transmit descriptors to give to DMA*/
ETH_Prepare_Transmit_Descriptors(length);
}
這里附帶說明一下,并不是LWIP原版代碼又臭又長,LWIP要做一個(gè)TCP/IP全棧協(xié)議,還要考慮包長度溢出的眾多問題,我們精簡版的協(xié)議很多不需要考慮,因此可以放棄很多繁瑣的操作。
有了上述DP83848Send()函數(shù),下面來做個(gè)小程序試驗(yàn)一下:
int main() {
u8 MyMacAddr[6] = {0x08, 0x00, 0x06, 0x00, 0x00, 0x09};
/* 下面是一段60byte大小的ARP報(bào)文,手動(dòng)構(gòu)建的 */
u8 mydata[60] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0xa8,
0x02, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8,
0x02, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
u32 clock;
/* 默認(rèn)調(diào)用SystemInit,系統(tǒng)時(shí)鐘168MHz */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //4位搶占,0位響應(yīng)
DP83848Init(MyMacAddr);
while(1){
DP83848Send(mydata, 60);
clock = 42000000; //1s延時(shí),while中每個(gè)步進(jìn)需要4個(gè)周期
while(clock--);
}
}
使用Keil編譯,用JLink下載到STM32F407中,給開發(fā)板接上網(wǎng)線,用WireShark就可以在網(wǎng)口中觀察到STM32每隔1秒鐘向外發(fā)送ARP報(bào)文了,雖然這段報(bào)文幾乎沒有任何意義。
我使用WireShark截圖如下:
總結(jié)一下,這一章我們完成了一個(gè)DP83848Send()發(fā)包函數(shù),這個(gè)函數(shù)可以接受一個(gè)字節(jié)buffer,一個(gè)字節(jié)buffer的長度,將這個(gè)buffer通過以太網(wǎng)發(fā)送出去,buffer內(nèi)部的內(nèi)容全部需要我們手工構(gòu)建。DP83848Send()函數(shù)的設(shè)計(jì)思路來自于分析LWIP官網(wǎng)示例,主要是ethernetif.c中的代碼。下一章我們同樣根據(jù)這份代碼,分析收包邏輯,實(shí)現(xiàn)STM32對以太網(wǎng)上數(shù)據(jù)的監(jiān)聽。
上一篇:STM32開發(fā)筆記54:STM32F4+DP83848以太網(wǎng)通信指南系列(八)
下一篇:STM32開發(fā)筆記52:STM32F4+DP83848以太網(wǎng)通信指南系列(六)
推薦閱讀
史海拾趣
1993年,Transico公司收購了EECO Switch部門,這標(biāo)志著EECO Switch公司進(jìn)入了一個(gè)全新的發(fā)展階段。在被收購后,EECO Switch獲得了更多的資源和支持,進(jìn)一步加速了其業(yè)務(wù)拓展的步伐。公司不僅在原有的人機(jī)界面產(chǎn)品領(lǐng)域繼續(xù)深耕細(xì)作,還積極拓展新的業(yè)務(wù)領(lǐng)域,如智能家居、物聯(lián)網(wǎng)等。
隨著業(yè)務(wù)的不斷拓展,固得沃克意識到技術(shù)升級和產(chǎn)能擴(kuò)張的重要性。2019年,公司在江蘇鹽城成立了江蘇固得沃克微電子科技有限公司,作為新的生產(chǎn)基地。該基地?fù)碛?萬平米的廠房,引進(jìn)了具有國際水準(zhǔn)的專業(yè)生產(chǎn)設(shè)備及先進(jìn)檢測儀器,并通過了ISO9001、ISO14001等國際管理體系認(rèn)證。這一舉措不僅提升了公司的生產(chǎn)能力和產(chǎn)品質(zhì)量,還進(jìn)一步鞏固了其在半導(dǎo)體行業(yè)的地位。
自E-Z-HOOK公司成立以來,其產(chǎn)品線一直在不斷擴(kuò)大。到了1970年代,隨著電子行業(yè)的快速發(fā)展,對測試工具的需求也日益增加。公司的新主人繼承了阿爾伯特·史密斯的愿景,并決定進(jìn)一步擴(kuò)展產(chǎn)品線。他們引入了一系列新的測試鉤型號,以適應(yīng)不同尺寸和形狀的測試點(diǎn)。此外,公司還開始生產(chǎn)其他與測試相關(guān)的零部件和組件,以滿足客戶日益增長的需求。
Connector City公司成立于XX世紀(jì)初,當(dāng)時(shí)電子連接器市場正處于快速發(fā)展的階段。作為初創(chuàng)企業(yè),Connector City面臨著資金短缺、技術(shù)落后和市場競爭激烈的挑戰(zhàn)。然而,公司創(chuàng)始人憑借對行業(yè)的深刻理解和敏銳的市場洞察力,成功捕捉到了市場機(jī)遇。他們積極尋求投資,加強(qiáng)與科研機(jī)構(gòu)的合作,不斷提升產(chǎn)品性能和質(zhì)量。同時(shí),公司還注重市場營銷和品牌建設(shè),通過參加行業(yè)展會、舉辦產(chǎn)品發(fā)布會等方式,提高了品牌知名度和市場占有率。
在競爭激烈的電子行業(yè)中,EIC公司深知供應(yīng)鏈管理和成本控制的重要性。公司建立了完善的供應(yīng)鏈管理體系,與供應(yīng)商建立了長期穩(wěn)定的合作關(guān)系,確保了原材料的穩(wěn)定供應(yīng)和質(zhì)量的可靠性。同時(shí),EIC還通過優(yōu)化生產(chǎn)流程、提高生產(chǎn)效率等措施,不斷降低生產(chǎn)成本,提升產(chǎn)品的競爭力。
本信息來自合作QQ群:AVR單片機(jī)學(xué)習(xí)與交流群(17727270) 群管理員在壇子里的ID:銅河 要有COM口,有并口。有網(wǎng)口… 查看全部問答∨ |
EP3C120F780是CYCLONE III 中比較大的FPGA,其相關(guān)介紹資料如下圖: 780個(gè)管腳,F(xiàn)BGA封裝,工業(yè)溫度(-40 到100度),商業(yè)溫度(0~85度) ES: 工程樣品, LEAD-FREE 表示啥意思? 此外上面也沒有介紹,其等效的邏輯門數(shù)量? 這而也 ...… 查看全部問答∨ |
WINCE USB攝像頭驅(qū)動(dòng)成功,結(jié)果實(shí)時(shí)視頻速度太慢 這是一個(gè)大喜又大悲的結(jié)果,前天搞定了6410下USB攝像頭驅(qū)動(dòng),可以捕獲320X240 YUV420格式圖像,昨天修改成了實(shí)時(shí)視頻流的程序,結(jié)果大失所望,S3C6410的USB HOST是USB1.1協(xié)議的,全速12Mbps,所以我想獲取30FPS的圖像很難呀,實(shí)際測試結(jié)果是160MS一 ...… 查看全部問答∨ |
|
淘寶購物特點(diǎn)是,一次性的,退不了的,所以\"兵者國之大事,不可不察也\" 一句話,挑最近成交多的,而且貨比三家,再有同賣家談好,別發(fā)生不愉快. 我上淘寶買東西主要有以下幾種方式: 一,急 我對急用的東東,不賣不行非買不可的,我貨比三家后,找 ...… 查看全部問答∨ |
據(jù)我的總結(jié)如下: begin-end語句的各句話是順序執(zhí)行的; fork-join語句各句話是并行執(zhí)行的; 阻塞賦值“=”計(jì)算表達(dá)式和賦值一起進(jìn)行; 非阻塞賦值“<=”先計(jì)算表達(dá)式,再在語句塊中統(tǒng)一賦值; 但是,唉,說實(shí)話還是搞得不明不白的!!比如begin- ...… 查看全部問答∨ |
BeagleBone 學(xué)習(xí)筆記03_2012_10_08 開貼說說sqlite移植 1)下載sqlite的源碼,解壓后進(jìn)入文件夾,新建build文件夾 2)可使用../configure -help查看配置的參數(shù)說明項(xiàng) 3)進(jìn)入build文件夾使用命令生成makefile文件:../configure --host=arm-arago-linux-gnueabi --prefix=/hom ...… 查看全部問答∨ |
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦
- 漏電火災(zāi)報(bào)警系統(tǒng)的設(shè)計(jì)與應(yīng)用探討
- 對USB接口進(jìn)行固件設(shè)計(jì)提升視頻傳輸質(zhì)量方案
- 怎樣測試運(yùn)算放大器的輸入失調(diào)電壓?
- TI 電池管理產(chǎn)品可使移動(dòng)電源開啟高壓智能充電模式
- 手機(jī)芯事:性能與功耗續(xù)航必定矛盾?
- 藍(lán)牙兩大技術(shù)―BR/EDR和Smart的十大重要區(qū)別
- 流量監(jiān)控與WIFI監(jiān)控誰更勝一籌?
- 移動(dòng)電源當(dāng)中的自動(dòng)檢測負(fù)載方式講解
- 智能攝像機(jī)或是智能家居破局關(guān)鍵
- 應(yīng)用在物聯(lián)網(wǎng)節(jié)點(diǎn)的SHA和AES解決方案
- EEWorld十五周年,感恩同行!盤點(diǎn)那些難忘的小確幸~
- 參與有禮|歡迎來到泰克高速串行知識星球
- 立即報(bào)名 | 2025 瑞薩電子工業(yè)以太網(wǎng)技術(shù)日 即將開啟?。?月12日-4月18日)
- 泰克有獎(jiǎng)看視頻 深入淺出剖析高速信號的抖動(dòng)和眼圖
- 有獎(jiǎng)直播|魏德米勒 OMNIMATE® 聯(lián)接技術(shù)的創(chuàng)新發(fā)展
- 村田在線課堂:移動(dòng)篇
- 是德科技有獎(jiǎng)直播:示波器在通用電子測量中的應(yīng)用和技巧
- 【迎新迎國慶】dcexpert帶你“全?!眲?dòng)手搞:基于ESP8266可充電的觸控創(chuàng)意LED燈
- 超異構(gòu)計(jì)算創(chuàng)造卓越能效比,開源的技術(shù)將造福全人類
- 高精度,更靈活,TI零漂移霍爾效應(yīng)電流傳感器問市
- Nordic nRF52840 助力唐山宏佳電子科技構(gòu)建更完善的遠(yuǎn)程應(yīng)用
- Bourns雙通道TBU?高速保護(hù)器可有效減少組件數(shù)量和BOM成本
- Telit新一代5G/LTE M.2卡可確保無線高速連接不受干擾
- 基于ARM Cortex-M0+內(nèi)核的bootloader程序升級原理及代碼解析
- ARM USB 通信
- 高性能Wi-Fi方案讓智能家居實(shí)現(xiàn)寬而廣的聯(lián)接
- STM8L051F3_03_CLK應(yīng)用
- 低功耗版STM8L051的一個(gè)詭異配置