EMS 知识库
首页 / knowledge/代码解析/midware/ethernt/lan

dhcp.h

源文件路径:midware/ethernt/lan/dhcp.h 所属模块:midware/ethernt/lan(W5500 以太网协议栈应用层 — DHCP/DNS/Socket) 代码行数:152

1. 文件职责

本文件是 WIZnet W5500 官方 DHCP 客户端库的头文件,声明了 DHCP 客户端对外暴露的全部 API:初始化、周期运行、1 秒计时、回调注册、停止、以及从 DHCP 服务器取回 IP/网关/掩码/DNS/租期。

在 EMS 中它不是直接被业务层调用,而是由 midware/ethernt/ethernet.c 引入:W5500_Init() 中调用 reg_dhcp_cbfunc() + DHCP_init(),dhcp_function() 中周期调用 DHCP_run(),internet_time_handle() 中调用 DHCP_time_handler();DHCP 拿到的地址最终经 my_ip_assign() 写入 g_stNetInfo 并触发 network_init()。

因此本文件处在"上电网络参数协商"这一环节,是"静态 IP 配置 / 动态 DHCP 获取"两种模式下动态那条路径的接口契约;文件本身不含任何逻辑,只有宏常量、返回值枚举与函数原型。

2. 关键数据结构与宏

名称类型说明
_DHCP_DEBUG_宏调试开关,被注释掉(第 53 行)。一旦打开会引入 <stdio.h>,dhcp.c 中所有 #ifdef _DHCP_DEBUG_ 的串口打印才会编译进来
MAX_DHCP_RETRY宏单轮 DHCP 超时重发上限,值 2(第 57 行)
DHCP_WAIT_TIME宏每级状态等待超时,值 10,单位秒(第 58 行)
DHCP_SERVER_PORT宏DHCP 服务器端口 67(第 62 行)
DHCP_CLIENT_PORT宏DHCP 客户端端口 68(第 63 行)
MAGIC_COOKIE宏DHCP option 魔数 0x63825363,即线上字节 99.130.83.99(第 66 行)
DCHP_HOST_NAME宏客户端主机名字符串 "WIZnet\0",注意宏名拼写为 DCHP(第 68 行,官方笔误被保留)
DHCP_run() 返回值枚举枚举匿名枚举(第 73-81 行):DHCP_FAILED=0、DHCP_RUNNING、DHCP_IP_ASSIGN、DHCP_IP_CHANGED、DHCP_IP_LEASED、DHCP_STOPPED(依次为 1~5)

本文件没有定义结构体、联合体或位域;DHCP 报文结构体 RIP_MSG 定义在 dhcp.c(第 172-188 行),不对外暴露。

3. 函数清单

本文件只有函数声明,没有函数定义。

函数名作用域说明(一句话)
DHCP_init(uint8_t s, uint8_t * buf)全局(声明,第 88 行)DHCP 客户端初始化:绑定 socket 号与报文缓冲区,复位状态机到 STATE_DHCP_INIT
DHCP_time_handler(void)全局(声明,第 94 行)1 秒节拍回调,需注册到系统 1s tick 中,供 DHCP 超时计时
reg_dhcp_cbfunc(assign, update, conflict)全局(声明,第 102 行)注册三个回调:首次分到 IP、IP 变更、IP 冲突
DHCP_run(void)全局(声明,第 116 行)主循环函数,由用户主任务周期调用,内部驱动 DHCP 状态机并返回上表枚举值
DHCP_stop(void)全局(声明,第 122 行)关闭 DHCP socket 并置状态为 STATE_DHCP_STOP;重启需重新 DHCP_init()
getIPfromDHCP(uint8_t* ip)全局(声明,第 129 行)取回 DHCP 分配的 IP 地址(4 字节)
getGWfromDHCP(uint8_t* ip)全局(声明,第 134 行)取回 DHCP 下发的网关地址
getSNfromDHCP(uint8_t* ip)全局(声明,第 139 行)取回 DHCP 下发的子网掩码
getDNSfromDHCP(uint8_t* ip)全局(声明,第 144 行)取回 DHCP 下发的 DNS 服务器地址
getDHCPLeasetime(void)全局(声明,第 150 行)取回租期,单位秒;返回 0xFFFFFFFF 表示无限租期

4. 核心逻辑解析

本文件不含可执行逻辑,此处只说明它约定的接口契约与调用时序,具体实现见 dhcp.c 文档。

4.1 返回值契约与调用方分派

DHCP_run() 的返回值是整个 DHCP 模块对外唯一的"事件通道"(无回调以外的信号机制)。调用方 ethernet.c:310 的 dhcp_pro_fun() 按值分派:

DHCP_IP_ASSIGN / DHCP_IP_CHANGED 在头文件注释中被描述为"若未注册回调则表现为默认行为",但实现上 reg_dhcp_cbfunc() 无论传什么都会先把三个函数指针重置为 default_*,因此不注册回调也不会空指针。

4.2 计时契约

DHCP_time_handler() 的约定是"注册到系统 1s tick"。本工程的接线是:ethernet.c:1086 的 internet_time_handle()(由 task_system_aux,优先级 8,midware/auxiliary/system_aux.c:2075 调用)中以 OSTimeGet() - s_u32Ticks > SENCOND_1S(1000 tick,OS_TICKS_PER_SEC=1000 即 1 秒)为闸门,每秒调用一次 DHCP_time_handler()。

关键点:DHCP 状态机运行在 task_ethernet(优先级 17,更低),而秒计数由优先级更高的 task_system_aux 递增,这决定了 dhcp.c 中忙等方式等待秒计数能被推进(详见 dhcp.c.md 的 check_DHCP_leasedIP() 分析)。

4.3 参数常量与帧大小的隐含耦合

头文件只给出 MAX_DHCP_RETRY/DHCP_WAIT_TIME 两个时间常量,报文缓冲区大小 MAX_DHCP_BUF_SIZE(548)定义在 ethernet.h:103,与 dhcp.c 里的 RIP_MSG_SIZE = 236 + OPT_SIZE(312) = 548 严格相等。缓冲区由 ethernet.c:37 的 u8 g_u8DHCPBuf[MAX_DHCP_BUF_SIZE] 提供并透传给 DHCP_init(),两侧任一处改动都会造成越界,属跨文件的隐式契约。

5. 对外接口

本文件导出的函数(均在 dhcp.c 中实现):

本文件导出的宏/枚举(供调用方判断状态):MAX_DHCP_RETRY、DHCP_WAIT_TIME、DHCP_SERVER_PORT、DHCP_CLIENT_PORT、MAGIC_COOKIE、DCHP_HOST_NAME,以及匿名枚举中的 DHCP_FAILED/DHCP_RUNNING/DHCP_IP_ASSIGN/DHCP_IP_CHANGED/DHCP_IP_LEASED/DHCP_STOPPED。

本文件不引用任何外部函数或变量(不 include 任何头文件,纯自包含声明),因此被 include 时没有顺序敏感性。

6. 依赖关系

7. 备注与风险点