协议栈文件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(),注意区别。
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库LWIP结构在线全文阅读。
相关推荐: