0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32之LWIP網(wǎng)絡(luò)協(xié)議棧TCP服務(wù)器創(chuàng)建

嵌入式技術(shù) ? 來源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-06-02 08:44 ? 次閱讀

1.LWIP介紹

lwip是瑞典計算機科學(xué)院網(wǎng)絡(luò)嵌入式系統(tǒng)小組(SICS)的Adam Dunkels(亞當(dāng)·鄧克爾) 開發(fā)的一個小型開源的TCP/IP協(xié)議棧。實現(xiàn)的重點是在保持 TCP 協(xié)議主要功能的基礎(chǔ)上減少對RAM的占用。
LwIP是Light Weight(輕型)IP 協(xié)議,有無操作系統(tǒng)的支持都可以運行。LwIP 實現(xiàn)的重點是在保持TCP協(xié)議 主要功能的基礎(chǔ)上減少對RAM的占用,它只需十幾KB的RAM和 40K左右的ROM就可以運行,這使LwIP協(xié)議棧適合在低端的嵌入式系統(tǒng)中使用。

2.TCP服務(wù)器搭建

硬件平臺:STM32F103ZE開發(fā)板、DM9000有線網(wǎng)卡
開發(fā)環(huán)境:KEIL5

#include "lwip_config.h"
#include "lwip/tcp.h"
/*接收成功回調(diào)函數(shù)*/
u8 buff[1024];
u16 rx_len=0;
err_t tcp_recv_func(void *arg, struct tcp_pcb *tpcb,struct pbuf *p, err_t err)
{
	memset(buff,0,sizeof(buff));
	rx_len=0;
	if(p==NULL)
	{
			clinet_stat=0;
			printf("[%d.%d.%d.%d:%d]:客戶端斷開連接rn",(u8)(tpcb->remote_ip.addr),
														(u8)(tpcb->remote_ip.addr>>8),
														(u8)(tpcb->remote_ip.addr>>16),
														(u8)(tpcb->remote_ip.addr>>24),
														tpcb->remote_port);
	}
	else
	{
		if(p->tot_len==p->len)
		{
			memcpy(buff,p->payload,p->len);
			rx_len=p->len;
			pbuf_free(p);
		}
		else
		{
			struct pbuf *temp=p;
			struct pbuf *q=temp;
			while(temp!=NULL)
			{
				memcpy(buff+rx_len,temp->payload,temp->len);
				q=temp;
				temp=temp->next;
				rx_len+=temp->len;
				pbuf_free(q);
			}
		}
		buff[rx_len]='?';
		printf("[%d.%d.%d.%d:%d]:%srn",(u8)(tpcb->remote_ip.addr),
										(u8)(tpcb->remote_ip.addr>>8),
										(u8)(tpcb->remote_ip.addr>>16),
										(u8)(tpcb->remote_ip.addr>>24),
										tpcb->remote_port,
										buff);
	}
	return ERR_OK;
}
/*客戶端連接成功回調(diào)函數(shù)*/
u8 client_addr[4];//IP地址
u16 client_prot=0;
u8 clinet_stat=0;
err_t tcp_client(void *arg, struct tcp_pcb *newpcb, err_t err)
{
	client_addr[0]=newpcb->remote_ip.addr>>0;
	client_addr[1]=newpcb->remote_ip.addr>>8;
	client_addr[2]=newpcb->remote_ip.addr>>16;
	client_addr[3]=newpcb->remote_ip.addr>>24;	
	clinet_stat=1;
	printf("客戶端連接成功:%d.%d.%d.%d:%drn",client_addr[0],client_addr[1],client_addr[2],client_addr[3],newpcb->remote_port);
	new_tcp=newpcb;
	tcp_recv(newpcb,tcp_recv_func);
	return ERR_OK;
}
/*TCP服務(wù)器創(chuàng)建*/
struct tcp_pcb *new_tcp;//tcp網(wǎng)絡(luò)信息(套接字)
u8 LWIP_CreateTcpServer(u16 port)
{
	/*1.建立一個新的網(wǎng)卡設(shè)備*/
	new_tcp=tcp_new();
	if(new_tcp==NULL)return 1;
	/*2.綁定IP地址和端口號*/
	if(tcp_bind(new_tcp, IP_ADDR_ANY,port)!=ERR_OK)
	{
		return 2;//綁定端口號失敗
	}
	/*開始監(jiān)聽*/
	new_tcp=tcp_listen(new_tcp);
	/*等待客戶端連接*/
	tcp_accept(new_tcp,tcp_client);
	return 0;
}

3.主函數(shù)

#include "dm9000.h"
#include "lwip_config.h"
u8 buff_tx[]="LWIP協(xié)議使用示例,發(fā)送數(shù)據(jù)測試示例.";
int main()
{
	char buff[200];
	u8 stat;
	u8 key;
	Beep_Init();
	Led_Init();
	Key_Init();
	W25Q64_Init();
	Usartx_Init(USART1,115200,72);
	TIMx_Init(TIM2,72,20*1000);
	IIC_Init();
	printf("初始化完成rn");
	NT35310_Init();
	/*DM9000初始化*/
	LCD_ShowStr(30,30,16,"DM9000初始化中。。。");//顯示字符串
	if(DM9000_Init()==0)
	{
		printf("DM9000初始化成功rn");
		LCD_ShowStr(30,30+20,16,"DM9000t OK!");//顯示字符串
	}
	else 
	{
		printf("DM9000初始化失敗rn");
		LCD_ShowStr(30,30+20,16,"DM9000t ERR!");//顯示字符串
	}
	/*獲取DM9000工作模式*/
	LCD_ShowStr(128,30+20*2,16,"網(wǎng)卡信息");//顯示字符串
	stat=DM9000_Get_SpeedAndDuplex();//獲取連接狀態(tài)和工作方式
	if(stat!=0xff)
	{
		printf("網(wǎng)卡速度:%d Mbps 模式:%srn",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
		snprintf(buff,sizeof(buff),"網(wǎng)卡速度:%d MHZt %s",(stat&0x02)?10:100,(stat&0x01)?"全雙工":"半雙工");
		LCD_ShowStr(30,30+20*3,16,(u8 *)buff);//網(wǎng)卡速度
		
	}
	else 
	{
		printf("DM9000網(wǎng)卡狀態(tài)信息獲取失敗!rn");
		LCD_ShowStr(30,30+20*3,16,(u8 *)"獲取網(wǎng)卡信息失敗!");//網(wǎng)卡速度
	}
	LWIP_Config_Init();//LWIP協(xié)議棧初始化
	while(!lwip_dhcp_stat)//等待IP分配成功
	{
		LWIP_DataUpdata();
	}
	TIMx_Init(TIM6,72,1000);
	TIM6->CR1|=1<<0;
	LWIP_CreateTcpServer(8899);//創(chuàng)建服務(wù)器
	while(1)
	{
		LWIP_DataUpdata();
		key=Key_Scan();
		if(key && clinet_stat)
		{
			tcp_write(new_tcp,buff_tx,strlen((char *)buff_tx),1);
			tcp_output(new_tcp);
		}
	}
}

運行效果:

pYYBAGKWtUuAIrV6AAeOz_3s2Y0767.png

4.相關(guān)函數(shù)介紹

4.1.建立TCP連接函數(shù)tcp_new

struct tcp_pcb *tcp_new(void)
函數(shù)功能:建立一個新的連接標(biāo)志(pcb)
形 參:無
返回值: pcb 正常建立了連接標(biāo)志,返回建立的 pcb
NULL 新的 pcb 內(nèi)存不可用時

4.2.綁定IP和端口號tcp_bind

err_t tcp_bind (struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
函數(shù)功能:綁定本地 IP 地址和端口號
形 參: pcb 準(zhǔn)備綁定的連接,類似于 BSD 標(biāo)準(zhǔn)中的 Sockets
Ipaddr 綁定的 IP 地址。如果為 IP_ADDR_ANY,則將連接綁定到所有的本地 IP 地址上
port 綁定的本地端口號。注意:千萬不要和其它的應(yīng)用程序產(chǎn)生沖突
返回值: ERR_OK 正確地綁定了指定的連接
ERR_USE 指定的端口號已經(jīng)綁定了一個連接,產(chǎn)生了沖突

4.3.使指定連接進(jìn)入監(jiān)聽狀態(tài)tcp_listen

struct tcp_pcb *tcp_listen (struct tcp_pcb *pcb)
函數(shù)功能:使指定的連接開始進(jìn)入監(jiān)聽狀態(tài)
形 參: pcb 指定將要進(jìn)入監(jiān)聽狀態(tài)的連接
返回值: pcb 返回一個新的連接標(biāo)志 pcb,它作為一個參數(shù)傳遞給將要被分派的函數(shù)。這樣做的原因是處于監(jiān)聽狀態(tài)的 連接一般只需要較小的內(nèi)存,于是函數(shù) tcp_listen()就會收回原始連接的內(nèi)存,而重新分配一個較小內(nèi)存塊供處 于監(jiān)聽狀態(tài)的連接使用。
NULL 監(jiān)聽狀態(tài)的連接的內(nèi)存塊不可用時,返回 NULL。如果這樣的話,作為參數(shù)傳遞給函數(shù)tcp_listen()的 pcb 所占用的內(nèi)存將不能夠被分配。

4.4.等待客戶端連接tcp_accept

void tcp_accept(struct tcp_pcb pcb,err_t ( accept)(void *arg,struct tcp_pcb *newpcb,err_t err))
函數(shù)功能:指定處于監(jiān)聽狀態(tài)的連接接通后將要調(diào)用的回調(diào)函數(shù)
形 參: pcb 指定一個處于監(jiān)聽狀態(tài)的連接
? accept 指定連接接通后將要調(diào)用的回調(diào)函數(shù)
返回值:無

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • STM32
    +關(guān)注

    關(guān)注

    2257

    文章

    10828

    瀏覽量

    352452
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1324

    瀏覽量

    78755
  • DM9000
    +關(guān)注

    關(guān)注

    0

    文章

    24

    瀏覽量

    16851
  • LwIP
    +關(guān)注

    關(guān)注

    2

    文章

    84

    瀏覽量

    26932
收藏 人收藏

    評論

    相關(guān)推薦

    STM32LWIP網(wǎng)絡(luò)協(xié)議移植步驟與方案

    LwIP是Light Weight(輕型)IP 協(xié)議,有無操作系統(tǒng)的支持都可以運行。LwIP 實現(xiàn)的重點是在保持TCP協(xié)議 主要功能的基礎(chǔ)上
    的頭像 發(fā)表于 06-01 08:35 ?1.3w次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>之</b><b class='flag-5'>LWIP</b><b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>協(xié)議</b><b class='flag-5'>棧</b>移植步驟與方案

    lwip協(xié)議代碼分析

    lwIP(Lightweight IP)是一個為嵌入式系統(tǒng)設(shè)計的輕量級TCP/IP協(xié)議。
    的頭像 發(fā)表于 10-29 17:37 ?1612次閱讀
    <b class='flag-5'>lwip</b><b class='flag-5'>協(xié)議</b><b class='flag-5'>棧</b>代碼分析

    為什么LWIP雙向發(fā)送大量數(shù)據(jù)時網(wǎng)絡(luò)協(xié)議會崩潰?

    /?36380,貌似bug已經(jīng)解決了,不知道有補丁沒有。同樣是這個移植的協(xié)議,跑跑原子教材中普通的TCP回響服務(wù)器例程是沒問題的,很久都不會掛掉,但一開始VNC就不行了。
    發(fā)表于 11-04 03:19

    怎么實現(xiàn)的基于TCP/IP協(xié)議的簡易服務(wù)器?

    本文以SPCE061A為主控制,DM9000為以太網(wǎng)MAC控制,配合一定的外圍電路而實現(xiàn)的基于TCP/IP協(xié)議的簡易
    發(fā)表于 05-31 06:34

    LwIP協(xié)議開發(fā)嵌入式網(wǎng)絡(luò)的三種方法有何關(guān)系

    服務(wù)器端通信為例,分析三種方法以及之間的關(guān)系,著重介紹基于raw API的應(yīng)用程序設(shè)計。 LwIP協(xié)議開發(fā)嵌入式網(wǎng)絡(luò)的三種方法分析 摘要輕
    發(fā)表于 08-05 07:55

    LwIP協(xié)議開發(fā)嵌入式網(wǎng)絡(luò)有哪幾種方法

    TCP服務(wù)器端通信為例,分析三種方法以及之間的關(guān)系,著重介紹基于raw API的應(yīng)用程序設(shè)計。最后在ST公司STM32F107微處理平臺上驗證,并給出了測試結(jié)果。關(guān)鍵詞
    發(fā)表于 08-06 07:33

    TCP服務(wù)器創(chuàng)建過程

    用過正點原子LWIP服務(wù)器例程開發(fā)的朋友可能知道,例程的設(shè)計是只支持一個客戶端連接的,但實際應(yīng)用中往往需要用到多客戶端連接。下面是在正點原子擴展例程網(wǎng)絡(luò)實驗14 NETCONN_TCP
    發(fā)表于 08-24 08:03

    在BL706上基于LwIP協(xié)議實現(xiàn)一個HTTP服務(wù)器

    是萬維網(wǎng)的數(shù)據(jù)通信的基礎(chǔ)。本 demo 主要是在 BL706 上基于 LwIP 協(xié)議,實現(xiàn)一個 HTTP 服務(wù)器,在 BL706 上部署了一個簡單的網(wǎng)頁,然后我們可以通過瀏覽
    發(fā)表于 07-04 18:13

    【技術(shù)精選】嵌入式STM32原創(chuàng)征文活動精選文章

    應(yīng)用案例基于PAJ7620和STM32手勢識別應(yīng)用案例STM32應(yīng)用案例 基于STM32F103ZE開發(fā)的數(shù)碼相冊基于STM32的小說閱讀
    發(fā)表于 07-27 18:26

    介紹tcp_ip協(xié)議lwip的特點

    簡介了嵌入式tcp_ip協(xié)議lwip的基本信息
    的頭像 發(fā)表于 07-03 13:05 ?3556次閱讀

    LWIP協(xié)議中Raw TCP中使用

    本文檔的主要內(nèi)容詳細(xì)介紹的是LWIP協(xié)議中Raw TCP中使用的資料免費下載
    發(fā)表于 11-05 17:36 ?17次下載
    <b class='flag-5'>LWIP</b><b class='flag-5'>協(xié)議</b><b class='flag-5'>棧</b>中Raw <b class='flag-5'>TCP</b>中使用

    UM1713_如何應(yīng)用stm32cube的中間件LwIP_TCP、IP協(xié)議

    UM1713_如何應(yīng)用stm32cube的中間件LwIP_TCP、IP協(xié)議
    發(fā)表于 11-22 19:16 ?1次下載
    UM1713_如何應(yīng)用<b class='flag-5'>stm32</b>cube的中間件<b class='flag-5'>LwIP_TCP</b>、IP<b class='flag-5'>協(xié)議</b><b class='flag-5'>棧</b>

    使用LwIP TCP/IP,在STM32Cube上開發(fā)應(yīng)用

    電子發(fā)燒友網(wǎng)站提供《使用LwIP TCP/IP,在STM32Cube上開發(fā)應(yīng)用.pdf》資料免費下載
    發(fā)表于 09-21 11:03 ?6次下載
    使用<b class='flag-5'>LwIP</b> <b class='flag-5'>TCP</b>/IP<b class='flag-5'>棧</b>,在<b class='flag-5'>STM32</b>Cube上開發(fā)應(yīng)用

    LwIP協(xié)議源碼詳解—TCP/IP協(xié)議的實現(xiàn)

    電子發(fā)燒友網(wǎng)站提供《LwIP協(xié)議源碼詳解—TCP/IP協(xié)議的實現(xiàn).pdf》資料免費下載
    發(fā)表于 07-03 11:22 ?1次下載

    串口服務(wù)器TCP/IP協(xié)議是什么關(guān)系

    串口服務(wù)器TCP/IP協(xié)議之間存在著緊密而復(fù)雜的關(guān)系。這種關(guān)系主要體現(xiàn)在串口服務(wù)器如何利用TCP
    的頭像 發(fā)表于 08-25 17:35 ?1087次閱讀