LWIP结构

更新时间:2024-04-27 21:52:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

协议栈文件Lwip.c封装接口: void Init_lwIP(void) {

struct ip_addr ip, mask, gw; static struct netif netif;

sys_sem_t sem;

/*****TCP/IP 初始化******/ sem = sys_sem_new(0);

uint8_t macaddress[6]={0,0,0,0,0,1}; //根据实际MAC地址赋值

tcpip_init(TcpipInitDone, &sem); sys_sem_wait(sem); sys_sem_free(sem);

#if LWIP_DHCP ipaddr.addr = 0; netmask.addr = 0; gw.addr = 0; #else

IP4_ADDR(&ipaddr, 10, 21, 11, 245); IP4_ADDR(&netmask, 255, 255, 255, 0); IP4_ADDR(&gw, 10, 21, 11, 254); #endif

Set_MAC_Address(macaddress);

netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &tcpip_input); netif_set_default(&netif);

#if LWIP_DHCP dhcp_start(&netif); #endif

netif_set_up(&netif); }

/*****等待Tcpip初始化完成*******/ static void TcpipInitDone(void *arg) {

sys_sem_t *sem; sem = arg;

sys_sem_signal(*sem); }

网络接口文件Ethernetif.c封装接口:

全局变量: uint8_t MACaddr[6];

/*******设置MAC地址,赋值全局变量**********/ void Set_MAC_Address(uint8_t* macadd) { }

/**********初始化网络底层接口*************/ err_t ethernetif_init(struct netif *netif) {

1、 设置网卡相关属性(填充结构体ethernetif);

2、 注册链路层发送函数low_level_output(给出框架,结合MAC芯片实际情况编写); 3、 ethernetif->ethaddr 指针指向 netif 中保存的网卡 MAC 地址; 4、 网卡初始化low_level_init(); }

注释:该接口无需用户改动。

/*****该函数是实际传输数据包,数据包包含pbuf –>payload,pbuf可能是个链表******/ static err_t low_level_output(struct netif *netif, struct pbuf *p) {

struct pbuf *q; int frameLen = 0; u8 *buffer = NULL;

/******声明一个状态保护变量******/ SYS_ARCH_DECL_PROTECT(sr);

/*********Interrupts are disabled through this whole thing to support multi-threading transmit calls. Also this function might be called from an ISR.********/ SYS_ARCH_PROTECT(sr);

buffer = (u8 *)ETH_GetCurrentTxBuffer(); for(q = p; q != NULL; q = q->next) {

memcpy((u8_t*)&buffer[l], q->payload, q->len); /****MAC芯片****/

ETH_MACAddressConfig(ETH_MAC_Address0, macadd); MACaddr[0] = macadd[0]; ……………………………. MACaddr[5] = macadd[5];

}

l = l + q->len;

ETH_TxPkt_ChainMode(l);

/****退出保护模式***/

SYS_ARCH_UNPROTECT(sr);

return ERR_OK; }

/*******返回缓冲区地址*******/ u32 ETH_GetCurrentTxBuffer(void);

/*******从应用程序的缓冲区,发送一个数据包*****/ ETH_TxPkt_ChainMode(l);

/***********/

static void low_level_init(struct netif *netif) {

SYS_ARCH_DECL_PROTECT(sr);

1、 设置MAC、最大传输单元(1500bytes);

2、 设备功能(NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP); SYS_ARCH_PROTECT(sr);

ETH_MACInit(); }

/*******初始化MAC*******/ void ETH_MACInit(void); /**

* This function should be called when a packet is ready to be read from the interface. It uses the function low_level_input() that should handle the actual reception of bytes from the network interface. Then the type of the received packet is determined and the appropriate input function is called. *

* @param netif the lwip network interface structure for this ethernetif */

err_t ethernetif_input(struct netif *netif) {

/* Enable MAC and DMA transmission and reception */ ETH_Start();

SYS_ARCH_UNPROTECT(sr);

SYS_ARCH_DECL_PROTECT(sr); SYS_ARCH_PROTECT(sr);

SYS_ARCH_PROTECT(sr);

/* move received packet into a new pbuf */ p = low_level_input(netif); SYS_ARCH_UNPROTECT(sr);

/* no packet could be read, silently ignore this */ if (p == NULL) return ERR_MEM;

err = netif->input(p, netif); // 将pbuf传递给上层协议栈 if (err != ERR_OK) {

LWIP_DEBUGF(NETIF_DEBUG, (\pbuf_free(p); p = NULL;

} /**

}

return err;

* Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf. *

* @param netif the lwip network interface structure for this ethernetif * @return a pbuf filled with the received packet (including MAC header) * NULL on memory error */

static struct pbuf * low_level_input(struct netif *netif) {

FrameTypeDef frame;

struct pbuf *p,*q; int l=0; u8 *buffer;

frame = ETH_RxPkt_ChainMode(); len=frame.length;

buffer = (u8 *)frame.buffer;

/* We allocate a pbuf chain of pbufs from the pool. */ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); if(p!=NULL) {

for(q=p;q!=NULL;q=q->next) {

} }

memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);

l = l + q->len;

……………………….. return p; }

LWIP协议栈系统使用到的api接口说明:

void tcpip_init(void(*) (void *) inifunc, void * arg) 初始化模块:

? ? 参数:

err_t tcpip_input(struct pbuf * p,struct netif* inp) 输入处理过程:

接收到的数据包通过邮箱传递给tcpip线程处理; 参数:

操作系统模拟层:

LWIP为操作系统模拟层提供了详细说明,文件名为sys_arch.txt,在LWIP的doc文件下。 1、 操作系统模拟层移植说明

操作系统模拟层(sys_arch)存在的目的主要是为了方便 LwIP 的移植,它在底层操作系统和LwIP 之间提供了一个接口。这样,我们在移植 LwIP 到一个新的目标系统时,只需修改这个接口即可。不过,不依赖底层操作系统的支持也可以实现这个接口。

建立并返回一个新的信号量。参数 count指定信号量的初始状态。 sys_sem_t sys_sem_new(u8_t count);

发送一个信号

void sys_sem_signal(sys_sem_t sem);

释放信号量。

void sys_sem_free(sys_sem_t sem);

u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout); p

接受的数据包,p->payload 指向以太网包头或IP头的有效负荷; 收到数据包的网络接口;

inp Inifunc Arg

当线程tcpip_thread运行时完成初始时被调用(check tcpip是否完成init); 参数传递给initfunc; 初始化所有子模块;

启动tcpip处理线程(tcpip_thread);

等待指定的信号并阻塞线程。timeout 参数为 0,线程会一直被阻塞至收到指定的信号;非 0,则线程仅被阻塞至指定的 timeout时间(单位为毫秒)。在timeout 参数值非 0 的情况下,返回值为等待指定的信号所消耗的毫秒数。如果在指定的时间内并没有收到信号,返回值SYS_ARCH_TIMEOUT。如果线程不必再等待这个信号(也就是说,已经收到信号) ,返回值也可以为 0。注意,LwIP实现了一个名称与之相似的函数来调用这个函数,sys_sem_wait(),注意区别。

等待指定的信号并阻塞线程。timeout 参数为 0,线程会一直被阻塞至收到指定的信号;非 0,则线程仅被阻塞至指定的 timeout时间(单位为毫秒)。在timeout 参数值非 0 的情况下,返回值为等待指定的信号所消耗的毫秒数。如果在指定的时间内并没有收到信号,返回值SYS_ARCH_TIMEOUT。如果线程不必再等待这个信号(也就是说,已经收到信号) ,返回值也可以为 0。注意,LwIP实现了一个名称与之相似的函数来调用这个函数,sys_sem_wait(),注意区别。

本文来源:https://www.bwwdw.com/article/zpcg.html

Top