打印
[蓝牙芯片]

【沁恒蓝牙SOC—CH579M篇】以太网例程-DHCP测评

[复制链接]
136|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
  在CH57x系列微控制器功能框图:

一、DHCP功能概述
   动态主机配置协议(DHCP,Dynamic Host Configuration Protocol)是一种基于客户端-服务器架构的网络管理协议,用于自动分配IP地址及其他网络配置参数,允许服务器向客户端动态分配IP地址、子网掩码、网关和DNS服务器等网络配置信息。在CH57x系列微控制器中,通过配置和启动DHCP客户端,可以自动从网络中的DHCP服务器获取这些配置信息,从而简化网络配置过程。
二、DHCP功能实现步骤
1. 初始化网络库:
    在使用DHCP功能之前,需要初始化CH57xNET库,配置MAC地址、缓冲区等。
2. 启动DHCP客户端:
    调用`CH57xNET_DHCPStart`函数启动DHCP客户端,并设置回调函数处理DHCP事件。
3. 处理DHCP回调:
    在DHCP回调函数中,根据DHCP的状态(如成功获取IP地址、失败等)执行相应的操作。例如,成功获取IP地址后,可以打印日志或进行后续网络操作。
程序设计:
#include "main.h"
#include "CH57x_common.h"
#include "uart.h"
#include "time.h"

#include "net_init.h"


__align(4) UINT8  RxBuffer[ MAX_PACKET_SIZE ];  // IN, must even address
__align(4) UINT8  TxBuffer[ MAX_PACKET_SIZE ];  // OUT, must even address
                                                                               
//缓存数据使用
unsigned char main_buffer[main_buffer_len];//缓存数据,全局通用
uint32_t  main_len;      //全局通用变量
unsigned char *main_str;    //全局通用变量


void uart0_data(void);//串口数据处理


char net_phy_state=0;

UINT8 net_dhcp_ip[4];   /* CH579IP地址 */
UINT8 net_dhcp_gw[4];   /* CH579网关 */
UINT8 net_dhcp_mask[4]; /* CH579子网掩码 */


/*******************************************************************************
* Function Name  : CH57xNET_DHCPCallBack
* Description    : DHCP回调函数
* Input          : None
* Output         : None
* Return         : 执行状态
*******************************************************************************/
UINT8 CH57xNET_DHCPCallBack(UINT8 status,void *arg)
{
        UINT8 *p;
        if(!status){/* 成功*/
                p = arg;
                PRINT("DHCP Success\n");
                memcpy(net_dhcp_ip,p,4);//获取分配的IP地址
                memcpy(net_dhcp_gw,&p[4],4);//获取网关
                memcpy(net_dhcp_mask,&p[8],4);//获取子网掩码
                printf("IPAddr = %d.%d.%d.%d \r\n",(UINT16)net_dhcp_ip[0],(UINT16)net_dhcp_ip[1],(UINT16)net_dhcp_ip[2],(UINT16)net_dhcp_ip[3]);
                printf("GWIPAddr = %d.%d.%d.%d \r\n",(UINT16)net_dhcp_gw[0],(UINT16)net_dhcp_gw[1],(UINT16)net_dhcp_gw[2],(UINT16)net_dhcp_gw[3]);
                printf("IPAddr = %d.%d.%d.%d \r\n",(UINT16)net_dhcp_mask[0],(UINT16)net_dhcp_mask[1],(UINT16)net_dhcp_mask[2],(UINT16)net_dhcp_mask[3]);
                printf("DNS1: %d.%d.%d.%d\r\n",p[12],p[13],p[14],p[15]);
                printf("DNS2: %d.%d.%d.%d\r\n",p[16],p[17],p[18],p[19]);
        }
        else{/* 产生此中断,CH57xNET库内部会将此socket清除,置为关闭*/
                PRINT("DHCP Fail %02x\n",status);
        }                                                      
        return 0;
}

int main()
{
        int i;
        PWR_UnitModCfg(ENABLE, UNIT_SYS_PLL);//使能PLL(给以太网提供时钟)                              
        DelayMs(3);
//    SetSysClock(CLK_SOURCE_HSE_32MHz);/* 外部晶振 PLL 输出32MHz */
        uart_init();//初始化串口
        net_init();//初始化以太网
        time0_init();//初始化定时器
        printf("start\r\n");
        while(1)
        {
                CH57xNET_MainTask();/* CH57xNET库主任务函数,需要在主循环中不断调用 */
               
                if(net_phy_state != CH57xInf.PHYStat){//网线连接状态改变
                        net_phy_state = CH57xInf.PHYStat;
                        if(net_phy_state==2){//连接
                                printf("net_phy_connected\r\n");
                                CH57xNET_DHCPStart(CH57xNET_DHCPCallBack);/* 启动DHCP */
                        }
                        else{//断开
                                printf("net_phy_disconnected\r\n");
                                CH57xNET_DHCPStop();//关闭DHCP
                        }
                }
        }
}


/**
* [url=home.php?mod=space&uid=247401]@brief[/url]   串口数据处理
* @param   None
* @retval  None
* [url=home.php?mod=space&uid=157211]@warning[/url] None
* @example
**/
void uart1_data(void)
{
        //读取串口接收的数据
        if(usart1_idle_flag){
                usart1_idle_flag=0;
               
                /*获取模组返回的数据*/
                main_len = rbCanRead(&rb_t_usart1_read);
                memset(usart1_read_buff_copy,0,rb_t_usart1_read_buff_len);
                if(main_len > 0)//如果里面的数据个数大于0
                {
                        rbRead(&rb_t_usart1_read, usart1_read_buff_copy, main_len);
                       
                }
        }
}


初始化:需要初始化CH57xNET库,配置MAC地址、缓冲区等。
启动DHCP:调用CH57xNET_DHCPStart函数启动DHCP客户端,并设置回调函数处理DHCP事件。
回调处理:在DHCP回调函数中,处理DHCP成功或失败的情况,例如获取到IP地址后,可以打印日志或进行后续网络操作。
处理DHCP交互流程
发现阶段:设备发送DHCP DISCOVER请求IP地址。
提供阶段:服务器返回DHCP OFFER,包含IP、子网掩码、网关等参数。
请求阶段:设备发送DHCP REQUEST确认选择。
确认阶段:服务器返回DHCP ACK,完成IP分配。
超时与重试机制
若未收到响应,设备通过定时器超时后重新发送DHCP DISCOVER,直至成功或达到最大重试次数。
结果:



三、DHCP功能实现中的注意事项
1. 网络稳定性:
    确保网络连接稳定,避免因网络波动导致DHCP请求失败。
    可以加入看门狗逻辑,防止设备因异常而死机。
2. DHCP服务器配置:
    检查DHCP服务器是否正常运行,并确保有足够的IP地址可供分配。
    如果网络中使用了DHCP中继,需要检查中继设备是否正常工作。
3. MAC地址处理:
    某些路由器可能对MAC地址有特殊要求,可以尝试修改MAC地址的前几字节以避免冲突。
4. 重连机制:
    在网络断开或DHCP失败时,需要实现重连机制。这通常涉及关闭原先的Socket、重新初始化网络库(如果需要)、重新启动DHCP客户端等步骤。
5. 错误处理:
    在DHCP回调函数中,需要处理各种可能的错误情况,如DHCP服务器无响应、IP地址分配失败等。
四、DHCP功能优化
1. 超时设置:
    调整DHCP的超时时间,避免长时间等待。
2. 日志记录:
    在DHCP回调函数中加入日志记录功能,方便调试和排查问题。
3. 电源稳定性:
    确保设备的电源稳定,避免因电源波动导致网络异常。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:项目经理
简介:资深嵌入式开发工程师

88

主题

171

帖子

3

粉丝