当前位置: 首页 > news >正文

好看的美食网站设计京东网上商城电脑版

好看的美食网站设计,京东网上商城电脑版,网络推广合作协议,多用户商城网站建设工程搭建及LWIP协议栈初始化过程 一、使用STM32CubeMX快速生成工程二、修改测试三、LWIP协议栈初始化过程分析3.1 tcpip_init()3.1.1 lwip_init()3.1.1.1 sys_init()3.1.1.2 mem_init()3.1.1.3 memp_init()3.1.1.4 netif_init()3.1.1.5 udp_init()3.1.1.6 tcp_init()3.1.1.7 ig… 工程搭建及LWIP协议栈初始化过程 一、使用STM32CubeMX快速生成工程二、修改测试三、LWIP协议栈初始化过程分析3.1 tcpip_init()3.1.1 lwip_init()3.1.1.1 sys_init()3.1.1.2 mem_init()3.1.1.3 memp_init()3.1.1.4 netif_init()3.1.1.5 udp_init()3.1.1.6 tcp_init()3.1.1.7 igmp_init()3.1.1.8 dns_init()3.1.1.9 ppp_init()3.1.1.10 sys_timeouts_init() 3.1.2 sys_mbox_new(tcpip_mbox, TCPIP_MBOX_SIZE)3.1.3 sys_mutex_new(lock_tcpip_core)3.1.4 tcpip_thread 3.2 netif_add()3.3 netif_set_default()和netif_set_up()函数3.4 netif_set_link_callback()和netif_set_status_callback()函数3.5 ethernet_link_thread线程3.6 dhcp_start() 一、使用STM32CubeMX快速生成工程 首先使用STM32CubeMX配置好FreeRTOS之后使能LWIP: 根据PHY芯片类型设置平台我使用的是LAN8720A选择8742就可以 根据需要选择是否使用DHCP和需要支持的协议类型 根据需要选择要支持的回调函数 生成工程。 二、修改测试 根据需要添加PHY芯片的复位操作比如LAN8720A硬件复位需要将 RESETn 引脚拉低至少 100μs。 修改网卡状态回调函数 static void netif_status_updated(struct netif *netif) {printf(\r\nenter netif_status_updated func\r\n);if (netif_is_up(netif)){printf(link available\r\n);printf(IP:%hhu.%hhu.%hhu.%hhu\r\n,ip4_addr1_val(netif-ip_addr),ip4_addr2_val(netif-ip_addr),ip4_addr3_val(netif-ip_addr),ip4_addr4_val(netif-ip_addr));printf(NM:%hhu.%hhu.%hhu.%hhu\r\n,ip4_addr1_val(netif-netmask),ip4_addr2_val(netif-netmask),ip4_addr3_val(netif-netmask),ip4_addr4_val(netif-netmask));printf(GW:%hhu.%hhu.%hhu.%hhu\r\n,ip4_addr1_val(netif-gw),ip4_addr2_val(netif-gw),ip4_addr3_val(netif-gw),ip4_addr4_val(netif-gw));}else{printf(link unavailable\r\n);} }上电后通过DHCP获取到IP地址之后会调用netif_status_updated()输出如下 断开或重新连接网线也会调用此函数 这个时候就可以Ping通板子了 三、LWIP协议栈初始化过程分析 使用STM32CubeMX生成的工程中调用MX_LWIP_Init()函数初始化LWIP协议栈。 void MX_LWIP_Init(void) {/* Initialize the LwIP stack with RTOS */tcpip_init( NULL, NULL );/* IP addresses initialization with DHCP (IPv4) */ipaddr.addr 0;netmask.addr 0;gw.addr 0;/* add the network interface (IPv4/IPv6) with RTOS */netif_add(gnetif, ipaddr, netmask, gw, NULL, ethernetif_init, tcpip_input);/* Registers the default network interface */netif_set_default(gnetif);/* We must always bring the network interface up connection or not... */netif_set_up(gnetif);/* Set the link callback function, this function is called on change of link status*/netif_set_link_callback(gnetif, ethernet_link_status_updated);/* Create the Ethernet link handler thread */ /* USER CODE BEGIN H7_OS_THREAD_DEF_CREATE_CMSIS_RTOS_V1 */osThreadDef(EthLink, ethernet_link_thread, osPriorityBelowNormal, 0, configMINIMAL_STACK_SIZE *2);osThreadCreate (osThread(EthLink), gnetif); /* USER CODE END H7_OS_THREAD_DEF_CREATE_CMSIS_RTOS_V1 *//* Start DHCP negotiation for a network interface (IPv4) */dhcp_start(gnetif);/* USER CODE BEGIN 3 */netif_set_status_callback(gnetif, netif_status_updated); /* USER CODE END 3 */ }3.1 tcpip_init() tcpip_init()函数用于初始化LWIP协议栈。 void tcpip_init(tcpip_init_done_fn initfunc, void *arg) {lwip_init();tcpip_init_done initfunc;tcpip_init_done_arg arg;if (sys_mbox_new(tcpip_mbox, TCPIP_MBOX_SIZE) ! ERR_OK) {LWIP_ASSERT(failed to create tcpip_thread mbox, 0);} #if LWIP_TCPIP_CORE_LOCKINGif (sys_mutex_new(lock_tcpip_core) ! ERR_OK) {LWIP_ASSERT(failed to create lock_tcpip_core, 0);} #endif /* LWIP_TCPIP_CORE_LOCKING */sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); }lock_tcpip_core互斥锁主要目的是确保在多任务环境下对 TCP/IP 协议栈核心部分如数据收发、连接管理等关键操作进行互斥访问。使用LOCK_TCPIP_CORE()和UNLOCK_TCPIP_CORE()两个宏配合使用。 Freertos多核SMP模式下Lwip出现共享资源违规访问问题 3.1.1 lwip_init() 初始化LWIP的所有功能模块。 3.1.1.1 sys_init() 在sys_init()函数中创建了一个LWIP系统的互斥信号量。 void sys_init(void) { #if (osCMSIS 0x20000U)lwip_sys_mutex osMutexCreate(osMutex(lwip_sys_mutex)); #elselwip_sys_mutex osMutexNew(NULL); #endif }3.1.1.2 mem_init() 初始化内存堆。 3.1.1.3 memp_init() 初始化内存池。 3.1.1.4 netif_init() 初始化环回接口。 当LWIP_HAVE_LOOPIF被定义时LWIP 协议栈将启用环回接口的相关功能。环回接口允许本地设备将数据发送到自己就好像数据是通过网络从其他设备发送过来的一样。这对于测试网络协议栈的功能非常有用。例如在开发基于 LWIP 的网络应用程序时可以使用环回接口来测试 TCP 或 UDP 协议的连接建立、数据发送和接收等功能而不需要实际连接到外部网络。环回接口可以用于在服务器端接收和处理来自本地客户端其实就是自己的数据请求。以一个简单的 HTTP 服务器为例通过环回接口可以在同一设备上测试服务器是否能够正确地接收请求、解析请求并返回响应就像真正有外部客户端在访问服务器一样。 LWIP_HAVE_LOOPIF有助于验证 LWIP 协议栈内部的数据流转机制。当数据通过环回接口发送时它会在 LWIP 协议栈内部经过一系列的协议层处理如 IP 层的路由、TCP 层的连接管理等。通过观察和分析数据在环回接口通信过程中的处理情况可以检查协议栈各个协议层之间的协同工作是否正常是否存在数据丢失或处理错误等问题。 void netif_init(void) { #if LWIP_HAVE_LOOPIF #if LWIP_IPV4 #define LOOPIF_ADDRINIT loop_ipaddr, loop_netmask, loop_gw,// 定义用于IPv4的环回接口的IP地址、子网掩码、网关地址的变量ip4_addr_t loop_ipaddr, loop_netmask, loop_gw;// 将环回接口的网关地址设置为127.0.0.1IP4_ADDR(loop_gw, 127, 0, 0, 1);// 将环回接口的IP地址设置为127.0.0.1IP4_ADDR(loop_ipaddr, 127, 0, 0, 1);// 将环回接口的子网掩码设置为255.0.0.0IP4_ADDR(loop_netmask, 255, 0, 0, 0); #else /* LWIP_IPV4 */ #define LOOPIF_ADDRINIT #endif /* LWIP_IPV4 */ #if NO_SYS// 添加网卡用于处理接收到的数据等操作使用ip_input作为输入函数来处理接收到的数据等情况netif_add(loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, ip_input); #else /* NO_SYS */// 如果不是无操作系统的情况添加环回网络接口时使用tcpip_input作为输入函数来处理接收到的数据等情况netif_add(loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, tcpip_input); #endif /* NO_SYS */#if LWIP_IPV6// 设置环回网络接口loop_netif的IPv6地址这里将主机部分设置为0x00000001ULIP_ADDR6_HOST(loop_netif.ip6_addr, 0, 0, 0, 0x00000001UL);// 将环回网络接口的第一个IPv6地址状态设置为有效IP6_ADDR_VALID表明该地址可用loop_netif.ip6_addr_state[0] IP6_ADDR_VALID; #endif /* LWIP_IPV6 */// 将环回网络接口loop_netif的链路状态设置为“已连接up”netif_set_link_up(loop_netif);// 将环回网络接口loop_netif设置为“启用up”状态使其可以正常进行网络通信等操作netif_set_up(loop_netif); #endif /* LWIP_HAVE_LOOPIF */ }3.1.1.5 udp_init() 在udp_init()函数中生成一个本地的随机UDP端口动态端口或私有端口是49152(0xC000)到65535(0xFFFF)之间的端口。 动态端口在网络通信中的作用 灵活分配端口资源 在网络通信中服务器通常需要为不同的客户端连接提供服务。如果每个服务都使用固定端口端口资源很快就会耗尽。动态端口可以根据需要灵活分配。支持并发连接和多服务通信 许多网络应用需要支持多个并发连接。以即时通讯软件为例一个用户可能同时与多个好友进行聊天、语音通话或视频通话。动态端口允许软件为每个并发的通信任务分配一个端口使得这些任务可以同时进行而不会相互干扰。适应动态网络环境和应用需求 网络环境是复杂多变的应用程序的功能和通信需求也可能随时改变。动态端口能够很好地适应这种变化。例如在移动网络环境中移动设备的网络连接可能会频繁切换如从 Wi - Fi 切换到移动数据应用程序可以使用动态端口根据新的网络条件快速调整通信方式。而且当应用程序需要临时增加新的通信功能如软件更新过程中的数据下载动态端口可以及时分配满足应用程序的通信需求。 私有端口在网络通信中的作用 内部网络通信安全保障 私有端口主要用于内部网络如企业内部局域网、家庭网络等中的通信。在这些网络中使用私有端口可以增加通信的安全性。避免与公共网络服务冲突 由于私有端口范围是预定义的并且不用于公共网络服务所以可以避免与互联网上广泛使用的公共服务端口如 Web 服务的 80 端口、FTP 服务的 21 端口等发生冲突。实现自定义网络应用和服务 私有端口为用户在内部网络中自定义网络应用和服务提供了便利。例如在一个物联网智能家居环境中用户可以使用私有端口来设置智能设备之间的通信方式。 void udp_init(void) { #ifdef LWIP_RANDudp_port UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); #endif /* LWIP_RAND */ }3.1.1.6 tcp_init() 在tcp_init()函数中生成一个本地的随机TCP端口动态端口或私有端口是49152(0xC000)到65535(0xFFFF)之间的端口。 void tcp_init(void) { #ifdef LWIP_RANDtcp_port TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); #endif /* LWIP_RAND */ } 3.1.1.7 igmp_init() 在igmp_init()函数中设置了两个组播地址allsystems(224.0.0.1)和allrouters(224.0.0.2)。 在 IP 网络中“allsystems” 通常是指本地网络中的所有主机系统。从广播地址的角度理解它类似于有限广播地址255.255.255.255的概念。这个地址用于将数据包发送给本地网络中的每一个设备。例如在一个小型的办公室局域网中如果一台设备想要向局域网内的所有其他设备发送一个通知消息就可以使用与 “allsystems” 相关的广播方式。 LWIP 协议栈支持向 “allsystems” 发送数据包的功能。这可能涉及到应用程序使用 UDPUser Datagram Protocol或其他合适的协议来发送广播消息。当应用程序调用 LWIP 的相关 API 发送广播消息到 “allsystems” 时LWIP 会根据网络接口的配置和当前的网络状态将数据包以广播的形式发送出去。例如在实现一个简单的本地网络设备发现协议时设备可以通过向 “allsystems” 广播自己的存在信息让其他设备能够接收到这个消息并做出响应。 “allrouters” 主要是指网络中的所有路由器。在 IP 网络中路由器在转发数据包方面起着关键的作用。向 “allrouters” 发送消息通常用于网络配置、路由更新等场景。例如在动态路由协议如 RIP - Router Information Protocol的操作中路由器可能会向 “allrouters” 发送路由更新信息以便其他路由器能够获取最新的路由信息并更新自己的路由表。 在 LWIP 协议栈中如果涉及到网络层的路由相关功能向 “allrouters” 发送消息的功能可能会被启用。不过这通常需要更复杂的网络设置和应用场景。例如在一个支持动态路由的嵌入式网络设备中当设备检测到网络拓扑结构发生变化时它可能会通过 LWIP 协议栈向 “allrouters” 发送路由更新消息以确保整个网络的路由信息能够及时更新。同时LWIP 也需要根据网络接口的类型如以太网接口、Wi - Fi 接口等和网络的实际情况如是否为多子网环境等来正确地处理向 “allrouters” 发送消息的操作。 void igmp_init(void) {LWIP_DEBUGF(IGMP_DEBUG, (igmp_init: initializing\n));IP4_ADDR(allsystems, 224, 0, 0, 1);IP4_ADDR(allrouters, 224, 0, 0, 2); }3.1.1.8 dns_init() 初始化DNS模块创建一个UDP协议控制块。 DNS 模块与 LWIP 中的其他网络模块紧密协作。它和 UDPUser Datagram Protocol模块密切相关因为 DNS 查询和响应消息通常是通过 UDP 协议传输的在某些情况下也可以使用 TCP 协议。当应用程序发起一个 DNS 请求时DNS 模块会构建一个 UDP 数据包将请求发送到 DNS 服务器。 同时DNS 模块也和 IPInternet Protocol模块协同。它需要使用 IP 模块来确定数据包的源和目的 IP 地址以及处理数据包在网络中的路由。在收到 DNS 服务器的响应后IP 模块将数据包传递给 DNS 模块进行解析提取出域名对应的 IP 地址并返回给应用程序。 3.1.1.9 ppp_init() 通过不同的宏如PPPOS_SUPPORT、PPPOE_SUPPORT、PPPOL2TP_SUPPORT 等确认是否支持 PPP over Serial基于串口的 PPP 协议、PPPoE以太网上的 PPP 协议、PPP over L2TP基于第二层隧道协议的 PPP 协议等不同的 PPP 衍生协议或功能并定义相应功能的内存池。 3.1.1.10 sys_timeouts_init() LWIP 内部维护了定时器相关的数据结构。通常包括定时器的间隔时间以毫秒为单位、定时器的状态是否正在运行、是否已过期等以及一个指向回调函数的指针。这个回调函数是超时处理的核心当定时器过期时就会调用这个函数来执行特定的超时操作。 在 LWIPLightweight IP协议栈中超时处理是确保网络通信可靠性和稳定性的关键机制。例如在 TCPTransmission Control Protocol协议中需要通过超时处理来判断数据是否丢失并进行重传。当发送端发送数据后如果在规定的时间内没有收到接收端的确认ACK消息就会触发超时重传机制以保证数据的可靠传输。 对于动态主机配置协议DHCP而言超时处理用于管理 IP 地址的租约时间。当租约时间快要到期时设备需要向 DHCP 服务器请求续租否则 IP 地址可能会失效。这涉及到一个超时定时器用于跟踪租约剩余时间确保设备能够及时更新租约维持网络连接的正常状态。 3.1.2 sys_mbox_new(tcpip_mbox, TCPIP_MBOX_SIZE) 创建消息邮箱由于Freertos中没有邮箱所以是通过消息队列实现的。 err_t sys_mbox_new(sys_mbox_t *mbox, int size) { #if (osCMSIS 0x20000U)osMessageQDef(QUEUE, size, void *);*mbox osMessageCreate(osMessageQ(QUEUE), NULL); #else*mbox osMessageQueueNew(size, sizeof(void *), NULL); #endif #if SYS_STATSlwip_stats.sys.mbox.used;if(lwip_stats.sys.mbox.max lwip_stats.sys.mbox.used){lwip_stats.sys.mbox.max lwip_stats.sys.mbox.used;} #endif /* SYS_STATS */if(*mbox NULL)return ERR_MEM;return ERR_OK; }osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {(void) thread_id;#if( configSUPPORT_STATIC_ALLOCATION 1 ) ( configSUPPORT_DYNAMIC_ALLOCATION 1 )if ((queue_def-buffer ! NULL) (queue_def-controlblock ! NULL)) {return xQueueCreateStatic(queue_def-queue_sz, queue_def-item_sz, queue_def-buffer, queue_def-controlblock);}else {return xQueueCreate(queue_def-queue_sz, queue_def-item_sz);} #elif ( configSUPPORT_STATIC_ALLOCATION 1 )return xQueueCreateStatic(queue_def-queue_sz, queue_def-item_sz, queue_def-buffer, queue_def-controlblock); #else return xQueueCreate(queue_def-queue_sz, queue_def-item_sz); #endif }3.1.3 sys_mutex_new(lock_tcpip_core) 创建一个互斥信号量用于保护内核线程在 LWIPLightweight IP协议栈中由于可能存在多个任务或者中断同时访问 TCP/IP 核心部分如协议栈的关键数据结构、正在处理的网络连接等为了避免数据不一致和并发访问导致的错误需要一种机制来进行访问控制。 3.1.4 tcpip_thread 创建LWIP的内核线程内核线程等待邮箱中的消息如果收到消息就调用tcpip_thread_handle_msg()函数处理。 3.2 netif_add() 过调用 netif_add 函数向 LWIP 协议栈添加一个网络接口对于使用DHCP的工程默认网卡的IP网关和子网掩码均设置为0使用ethernetif_init函数设置底层的网口最终调用low_level_init()函数。在low_level_init()函数中除了设置硬件相关还会创建两个信号量用于控制网口发送和接收同时创建ethernetif_input()任务该任务在获取到接收信号量之后调用low_level_inpu()函数从底层收包使用tcpip_input作为输入函数来处理接收到的数据。 netif_add(gnetif, ipaddr, netmask, gw, NULL, ethernetif_init, tcpip_input);3.3 netif_set_default()和netif_set_up()函数 将刚添加的网络接口 gnetif 设置为默认网络接口将网络接口 gnetif 的状态设置为 “启用up”。这一步操作使得网络接口具备了进行网络通信的基本条件不管当前是否已经成功建立网络连接比如是否已经通过 DHCP 获取到 IP 地址等先将接口在协议栈层面设置为可工作状态后续可以基于这个状态继续完成网络配置和实际通信的相关操作。 3.4 netif_set_link_callback()和netif_set_status_callback()函数 在 LWIPLightweight IP协议栈中netif_set_link_callback函数主要用于设置一个回调函数这个回调函数会在网络接口netif的链路状态发生变化(up/down)时被调用。例如当以太网接口的网线被插拔或者 Wi - Fi 接口的连接状态从已连接变为断开连接时链路状态发生了改变此时就会触发这个回调函数。STM32CubeMX默认设置会打开这个回调函数。 netif_set_status_callback函数用于设置一个回调函数当网络接口的综合状态发生变化时会被调用。这里的 “综合状态” 比单纯的链路状态更广泛可能包括网络接口的配置状态变化、接口的启用 / 禁用状态变化等多种情况。例如当网络接口的 IP 地址通过 DHCPDynamic Host Configuration Protocol重新配置后或者网络接口被手动禁用通过系统命令或者配置文件这个回调函数就会被触发。STM32CubeMX中要设置LWIP_NETIF_STATUS_CALLBACK为ENABLE。 3.5 ethernet_link_thread线程 这个线程主要用于处理以太网链路相关的事务比如实时监测链路状态、执行链路维护操作等。默认100ms轮询。 3.6 dhcp_start() 调用 dhcp_start 函数针对网络接口 gnetif 启动动态主机配置协议DHCP的协商过程。由于前面已经将 IP 地址等相关信息初始化为 0通过这个函数启动后网络接口会向网络中的 DHCP 服务器发送请求尝试获取合适的 IP 地址、子网掩码、网关地址等网络配置信息以完成自身的网络配置使得设备能够在网络中正常通信。
http://www.hkea.cn/news/14428892/

相关文章:

  • 沃尔玛官网网上商城seo怎么做网站的tdk
  • 珠海市网站建设哪家好wordpress route
  • 公司做网站的好处桂林市网站建设公司
  • 网站建设费需要摊销吗为什么石家庄突然封了
  • 制作网站公寻找锦州网站建设
  • 大气的网站设计企业咨询公司收费标准
  • 太原市建设北路小学网站如何编写代码
  • seo建站公司推荐什么是网站解析
  • 网站网络推广企业西安网站公司排名
  • 如何把自己电脑做网站服务器吗可不可以异地建设网站
  • 电商网站制作案例免费wordpress cms主题
  • 陵水网站建设网络营销外包总代理
  • 成都科技网站建设电话多少西安做网络推广的
  • 网站 服务 套餐网站 编码文档
  • 常德网站建设详细策划石狮网站建设制作
  • 网站管理建设总结在哪做网站关键词
  • 河南安阳市滑县网站seo优化有哪些
  • 自己建设网站怎么挣钱上海松江品划做网站
  • 手机建站平台哪个便宜python如何创建网页
  • 济南百度整站seo推广电商数据分析怎么做
  • 中文企业网站模板下载有什么wordpress
  • 买空间的网站好网站开发人员 组织架构
  • 辽宁住房和城乡建设部网站怎么在百度上做推广
  • 网站制作与建设教程下载网站建设和数据容量整合
  • 如何做装修网站wordpress支持的语言包
  • 服装网站建设企业需求调查金融做市场广告挂哪些网站
  • 网络软文推广网站好的建站平台
  • 网站建设费开票收候开在哪个类别里模仿一个网站建设多少钱
  • 巨鹿县住房与城乡建设厅网站学做网站要懂英语吗
  • 无锡做网站的wordpress媒体插件