完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
首先,为什么要做无OS的LWIP呢?原因很简单,因为stm32f103c8t6只有20K的RAM,很难支持OS + LWIP。
无OS的LWIP的一个优点是,可以提高单片机的以太网的响应速度。 LWIP的介绍就不说了,网上查一大把。 我的无OS移植LWIP基于ST官网的一个示例: STSW-STM32026STM32F107xx (AN3102) 的 LwIP TCP/IP 堆栈演示 大家可以到官网下载。 这个示例是运行在STM32F107上面的,如果要运行到STM32F103上,还需要进行一些修改。下面是移植的主要步骤。 1.从ST官网项目中的LWIP-1.3.1目录整个复制到你的项目中 2. 修改文件lwip-1.3.1portethernetif.c,我的网卡是enc28j60,主要修改如下 2.1 添加 uint8_t mac[6] = {0x00, 0xe0, 0x3d, 0xf4, 0xdd, 0xf7}; //网卡的mac地址 uint8_t Tx_Data_Buf[512]; //网卡发送 uint8_t Rx_Data_Buf[512]; //网卡接收缓冲区 2.2修改low_level_init 静态无效 low_level_init(结构用作netif *用作netif) { / *集合MAC硬件地址长度* / netif-》 hwaddr_len = ETHARP_HWADDR_LEN; /* 设置 MAC 硬件地址 */ netif-》hwaddr[0] = mac[0]; netif-》hwaddr[1] = mac[1]; netif-》hwaddr[2] = mac[2]; netif-》hwaddr[3] = mac[3]; netif-》hwaddr[4] = mac[4]; netif-》hwaddr[5] = mac[5]; /* 最大传输单元 */ netif-》mtu = 1500; /* 设备功能 */ /* 如果此设备不是以太网设备,则不要设置 NETIF_FLAG_ETHARP */ netif-》flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; enc28j60_init(netif-》hwaddr); } 2.3 修改low_level_output static err_t low_level_output(struct netif *netif, struct pbuf *p) { struct pbuf *q; 无符号整数 i = 0; #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* 删除填充字 */ #endif for(q = p; q != NULL; q = q-》next) { /* 将数据从 pbuf 发送到接口,一次一个 pbuf 。每个 pbuf 中数据的大小保存在 -》len 变量中。*/ memcpy(& Tx_Data_Buf , (u8_t*)q-》payload, q-》len); i = i + q-》len; } enc28j60_packet_send(Tx_Data_Buf,i); #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* 回收填充字 */ #endif LINK_STATS_INC(link.xmit); 返回 ERR_OK; } 2.4 修改low_level_input static struct pbuf * low_level_input(struct netif *netif) { struct pbuf *p, *q; u16_t len; 无符号整数 i = 0; /* Obtain the size of the packet and put it into the “len” variable. */ len = enc28j60_packet_receive( Rx_Data_Buf,512); if(len == 0) return 0; #if ETH_PAD_SIZE len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif /* We allocate a pbuf chain of pbufs from the pool. */ p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); if (p != NULL) { #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif /* We iterate over the pbuf chain until we have read the entire * packet into the pbuf. */ for(q = p; q != NULL; q = q-》next) { /* Read enough bytes to fill this pbuf in the chain. The * available data in the pbuf is given by the q-》len * variable. * This does not necessarily have to be a memcpy, you can also preallocate * pbufs for a DMA-enabled MAC and after receiving truncate it to the * actually received size. In this case, ensure the tot_len member of the * pbuf is the sum of the chained pbuf len members. */ memcpy((u8_t*)q-》payload, (u8_t*)&Rx_Data_Buf, q-》len); i = i + q-》len; } #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif LINK_STATS_INC(link.recv); } else { //drop packet(); LINK_STATS_INC(link.memerr); LINK_STATS_INC(link.drop); } return p; } 3. 修改stm32f10x_it.c 添加: __IO uint32_t LocalTime = 0; 修改SysTick_Handler: void SysTick_Handler(void) { LocalTime += 1; } 4. 制作main函数 struct netif netif; __IO uint32_t TCPTimer = 0; __IO uint32_t ARPTimer = 0; void LwIP_Init(void) { struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; /* Initializes the dynamic memory heap defined by MEM_SIZE.*/ mem_init(); /* Initializes the memory pools defined by MEMP_NUM_x.*/ memp_init(); IP4_ADDR(&ipaddr, 192, 168, 2, 8); IP4_ADDR(&netmask, 255, 255, 255, 0); IP4_ADDR(&gw, 192, 168, 2, 1); /* - netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw, void *state, err_t (* init)(struct netif *netif), err_t (* input)(struct pbuf *p, struct netif *netif)) Adds your network interface to the netif_list. Allocate a struct netif and pass a pointer to this structure as the first argument. Give pointers to cleared ip_addr structures when using DHCP, or fill them with sane numbers otherwise. The state pointer may be NULL. The init function pointer must point to a initialization function for your ethernet netif interface. The following code illustrates it‘s use.*/ netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); /* Registers the default network interface.*/ netif_set_default(&netif); /* When the netif is fully configured this function must be called.*/ netif_set_up(&netif); } void LwIP_Periodic_Handle(__IO uint32_t localtime) { /* TCP periodic process every 250 ms */ if (localtime - TCPTimer 》= TCP_TMR_INTERVAL) { TCPTimer = localtime; tcp_tmr(); } /* ARP periodic process every 5s */ if (localtime - ARPTimer 》= ARP_TMR_INTERVAL) { ARPTimer = localtime; etharp_tmr(); } } int main() { RCC_Config(); LwIP_Init(); SysTick_Config(SystemCoreClock / 1000); HelloWorld_init(); while (1) { /* Periodic tasks */ ethernetif_input(&netif); LwIP_Periodic_Handle(LocalTime); } } 5. 修改lwipopts.h文件,因为只有20K的RAM,把一些数改小点,不然编译不通过 #define MEM_SIZE (10*1024) #define PBUF_POOL_SIZE 8 #define PBUF_POOL_BUFSIZE 300 #define TCP_MSS (300 - 40) //#define CHECKSUM_BY_HARDWARE 6. 编译,下载,在命令行里ping和telnet限制,运行正常 7. 总结,LWIP的无OS移植还是比较简单的,对比UIP的无OS移植,编写应用程序要简单得多。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1574 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1519 浏览 1 评论
949 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
672 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1565 浏览 2 评论
1852浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
622浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
507浏览 3评论
512浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
494浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-14 13:01 , Processed in 0.507483 second(s), Total 48, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号