当前位置:首页 > 单片机 > 单片机
[导读]uIP 由瑞典计算机科学学院(网络嵌入式系统小组)的Adam Dunkels (http://dunkels.com/adam/uip/)开发。其源代码由C 语言编写,并完全公开,有了这个TCP/IP协议栈,让嵌入式可以实现的功能更为丰富。可以作为WebClie

uIP 由瑞典计算机科学学院(网络嵌入式系统小组)的Adam Dunkels (http://dunkels.com/adam/uip/)开发。其源代码由C 语言编写,并完全公开,有了这个TCP/IP协议栈,让嵌入式可以实现的功能更为丰富。可以作为WebClient向指定网站提交数据,可以作为WebServer作为网页服务器,提供一个小型的动态页面访问功能。由于是开源的免费协议栈,据说Uip没有考虑协议安全的问题。

首先介绍下移植的环境: stm32 + ENC28J60网络模块

Enc28j60是带SPI 接口的独立以太网控制器,可以用mcu控制spi来实现tcp/ip数据流的收发,所以要先完成Enc28j60的驱动程序,再整合Uip。Uip是用标准的C语言实现,所以移植Uip在51单片机和stm32上类似。

经过几天的琢磨,已经将Uip的几个示例稳定运行。Uip中apps下的例子相互之间存在冲突,源程序中也有一些Error 要修改,我将Uip的文件结构做了一些调整。

Uip文件结构

先介绍下Uip下各个目录文件的功能:

├─apps apps目录 下为uip提供的一些应用示例
│├─dhcpc
│├─hello-world
│├─resolv
│├─smtp
│├─telnetd
│├─webclient
│└─webserver
│ └─httpd-fs
├─doc doc下放置的为说明文档,程序中用不上
│└─html
├─lib lib下为内存块管理函数源码
├─uip uip下为uip和核心实现源码
└─unix unix环境里的uip应用例子,可以参照这个例子实现应用

Uip+stm32 MDK下工程建立



Uip移植
Uip的移植可以参考uip的unix的文件结构。

1. Uip的数据通过网卡Enc28j60从物理层剥离,所以需要先配置Uip和Enc28j60的数据交互。这个部分在tapdev.c文件中:

[C]纯文本查看复制代码

?

01020304050607080910111213141516171819202122#include "uip.h"#include "ENC28J60.h"/*---------------------------------------------------------------------------*/voidtapdev_init(unsigned char *my_mac){enc28j60Init(my_mac);}/*---------------------------------------------------------------------------*/unsigned inttapdev_read(void){return enc28j60PacketReceive(UIP_CONF_BUFFER_SIZE,uip_buf);}/*---------------------------------------------------------------------------*/voidtapdev_send(void){enc28j60PacketSend(uip_len,uip_buf);}/*---------------------------------------------------------------------------*/




写网卡驱动程序,与具体硬件相关。这一步比较费点时间,不过好在大部分网卡芯片的驱动程序都有代码借鉴或移植。驱动需要提供三个函数,以Enc28j60 驱动为例。
tapdev_init():网卡初始化函数,初始化网卡的工作模式。
tapdev_read(void):读包函数。将网卡收到的数据放入全局缓存区uip_buf 中,返回包的长度,赋给uip_len。
void tapdev_send(void):发包函数。将全局缓存区uip_buf 里的数据(长度放在uip_len 中)发送出去。


2.由于uIP 协议栈需要使用时钟,为TCP 和ARP 的定时器服务。因此使用单片机的定时器或是stm32的滴答定时器用作时钟,每20ms 让计数tick_cnt 加1,这样,25 次计数(0.5S)满了后可以调用TCP 的定时处理程序。10S 后可以调用ARP 老化程序。uIP1.0 版本,增加了timer.c/timer.h,专门用来管理时钟,修改clock-arch.c如下:

[C]纯文本查看复制代码

?

0102030405060708091011#include "clock-arch.h"#include "stm32f10x.h"extern __IO int32_t g_RunTime;/*---------------------------------------------------------------------------*/clock_time_tclock_time(void){return g_RunTime;}/*---------------------------------------------------------------------------*/


使用stm32 滴答定时器中断代码:

User/stm32f10x_it.c

[C]纯文本查看复制代码

?

010203040506070809101112131415__IO int32_t g_RunTime = 0;void SysTick_Handler(void){static uint8_t s_count = 0;if (++s_count >= 10){s_count = 0;g_RunTime++; /* 全局运行时间每10ms增1 */if (g_RunTime == 0x80000000){g_RunTime = 0;}}}


3.uipopt.h/uip-conf.h 是配置文件,用来设置本地的IP 地址、网关地址、MAC 地址、全局缓冲区的大小、支持的最大连接数、侦听数、ARP 表大小等。可以根据需要配置。

#define UIP_FIXEDADDR 1
决定uIP是否使用一个固定的IP地址。
如果uIP使用一个固定的IP地址,应该置位(set)这些uipopt.h中的选项。如果不的话,则应该使用宏uip_sethostaddr(),uip_setdraddr() 和 uip_setnetmask()。

#define UIP_PINGADDRCONF 0 Ping IP地址赋值。
#define UIP_FIXEDETHADDR 0 指明uIP ARP模块是否在编译时使用一个固定的以太网MAC地址。
#define UIP_TTL 255 uIP发送的IP packets的IP TTL (time to live)。
#define UIP_REASSEMBLY 0 uIP支持IP packets的分片和重组。
#define UIP_REASS_MAXAGE 40 一个IP fragment在被丢弃之前可以在重组缓冲区中存在的最大时间。
#define UIP_UDP 0 是否编译UDP的开关。
#define UIP_ACTIVE_OPEN 1 决定是否支持uIP打开一个连接。
#define UIP_CONNS 10 同时可以打开的TCP连接的最大数目。由于TCP连接是静态分配的,减小这个数目将占用更少的RAM。每一个TCP连接需要大约30字节的内存。
#define UIP_LISTENPORTS 10 同时监听的TCP端口的最大数目。每一个TCP监听端口需要2个字节的内存。
#define UIP_RECEIVE_WINDOW 32768 建议的接收窗口的大小。如果应用程序处理到来的数据比较慢,那么应该设置的小一点(即,相对与uip_buf缓冲区的大小来说),相反如果应用程序处理数据很快,可以设置的大一点(32768字节)。
#define UIP_URGDATA 1 决定是否支持TCP urgent data notification。
#define UIP_RTO 3 The initial retransmission timeout counted in timer pulses.不要改变
#define UIP_MAXRTX 8 在中止连接之前,应该重发一个段的最大次数。不要改变
#define UIP_TCP_MSS (UIP_BUFSIZE – UIP_LLH_LEN – 40) TCP段的最大长度。它不能大于UIP_BUFSIZE – UIP_LLH_LEN – 40.
#define UIP_TIME_WAIT_TIMEOUT 120 一个连接应该在TIME_WAIT状态等待多长。不要改变
#define UIP_ARPTAB_SIZE 8 ARP表的大小。如果本地网络中有许多到这个uIP节点的连接,那么这个选项应该设置为一个比较大的值。
#define UIP_BUFSIZE 1500 uIP packet缓冲区不能小于60字节,但也不必大于1500字节。
#define UIP_STATISTICS 1 决定是否支持统计数字。统计数字对调试很有帮助,并展示给用户。
#define UIP_LOGGING 0 输出uIP登陆信息。
#define UIP_LLH_LEN 14 链接层头部长度。对于SLIP,应该设置成0。


uip-conf.h 中增加几个主要结构体定义,不include任何应用

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在嵌入式开发中,STM32的时钟系统因其灵活性和复杂性成为开发者关注的焦点。然而,看似简单的时钟配置背后,隐藏着诸多易被忽视的陷阱,轻则导致系统不稳定,重则引发硬件损坏。本文从时钟源选择、PLL配置、总线时钟分配等关键环...

关键字: STM32 时钟系统

在嵌入式系统开发中,STM32系列微控制器的内部温度传感器因其低成本、高集成度特性,广泛应用于设备自检、环境监测等场景。然而,受芯片工艺差异和电源噪声影响,其原始数据存在±1.5℃的固有误差。本文从硬件配置、校准算法、软...

关键字: STM32 温度传感器

在能源效率与智能化需求双重驱动下,AC-DC转换器的数字控制技术正经历从传统模拟方案向全数字架构的深刻变革。基于STM32微控制器的PFM(脉冲频率调制)+PWM(脉冲宽度调制)混合调制策略,结合动态电压调整(Dynam...

关键字: AC-DC STM32

当前智能家居产品需求不断增长 ,在这一背景下 ,对现有浇花装置缺陷进行了改进 ,设计出基于STM32单片机的全 自动家用浇花机器人。该设计主要由机械结构和控制系统构成 ,机械结构通过麦克纳姆轮底盘与喷洒装置的结合实现机器...

关键字: STM32 麦克纳姆轮 安全可靠 通过性强

用c++编程似乎是让你的Arduino项目起步的障碍吗?您想要一种更直观的微控制器编程方式吗?那你需要了解一下Visuino!这个图形化编程平台将复杂电子项目的创建变成了拖动和连接块的简单任务。在本文中,我们将带您完成使...

关键字: Visuino Arduino ESP32 STM32

基于STM32与LoRa技术的无线传感网络凭借其低功耗、广覆盖、抗干扰等特性,成为环境监测、工业自动化等场景的核心解决方案。然而,如何在复杂电磁环境中实现高效休眠调度与动态信道优化,成为提升网络能效与可靠性的关键挑战。本...

关键字: STM32 LoRa

在实时控制系统、高速通信协议处理及高精度数据采集等对时间敏感的应用场景中,中断响应延迟的优化直接决定了系统的可靠性与性能上限。STM32系列微控制器凭借其灵活的嵌套向量中断控制器(NVIC)、多通道直接内存访问(DMA)...

关键字: STM32 DMA

数字电源技术向高功率密度、高效率与高动态响应方向加速演进,STM32微控制器凭借其基于DSP库的算法加速能力与对LLC谐振变换器的精准控制架构,成为优化电源动态性能的核心平台。相较于传统模拟控制或通用型数字控制器,STM...

关键字: STM32 数字电源

STM32微控制器凭借其针对电机控制场景的深度优化,成为高精度、高可靠性驱动系统的核心选择。相较于通用型MCU,STM32在电机控制领域的核心优势集中体现在FOC(磁场定向控制)算法的硬件加速引擎与PWM死区时间的动态补...

关键字: STM32 电机控制

无线充电技术加速渗透消费电子与汽车电子领域,基于Qi协议的无线充电发射端开发成为智能设备能量补给的核心课题。传统模拟控制方案存在响应滞后、参数调整困难等问题,而基于STM32的数字PID控制结合FOD(Foreign O...

关键字: STM32 无线充电
关闭