CH579-LAN-DHCP

DHCP

  1 /********************************** (C) COPYRIGHT ******************************
  2 * File Name          : DHCP_Client.C
  3 * Author             : WCH
  4 * Version            : V1.0
  5 * Date               : 2018/12/01
  6 * Description        : CH57xNET库演示文件
  7 *                      (1)、CH579 Examples by KEIL;
  8 *                      (2)、串口1输出监控信息,115200bps;
  9 *                      (3)、本程序用于演示DHCP客户端从网关获取IP地址
 10 *******************************************************************************/
 11 
 12 
 13 
 14 /******************************************************************************/
 15 /* 头文件包含*/
 16 #include <stdio.h>
 17 #include <string.h>
 18 #include "CH57x_common.h"
 19 #include "core_cm0.h"
 20 #include "CH57xNET.H"
 21 
 22 #define KEEPLIVE_ENABLE  1  // 开启KEEPLIVE功能 
 23 
 24 /* 下面的缓冲区和全局变量必须要定义,库中调用 */
 25 __align(16)UINT8    CH57xMACRxDesBuf[(RX_QUEUE_ENTRIES )*16];  //MAC接收描述符缓冲区,16字节对齐 
 26 __align(4) UINT8    CH57xMACRxBuf[RX_QUEUE_ENTRIES*RX_BUF_SIZE]; //MAC接收缓冲区,4字节对齐 
 27 __align(4) SOCK_INF SocketInf[CH57xNET_MAX_SOCKET_NUM];  //Socket信息表,4字节对齐 
 28 
 29 UINT16 MemNum[8] = {CH57xNET_NUM_IPRAW,
 30                     CH57xNET_NUM_UDP,
 31                     CH57xNET_NUM_TCP,
 32                     CH57xNET_NUM_TCP_LISTEN,
 33                     CH57xNET_NUM_TCP_SEG,
 34                     CH57xNET_NUM_IP_REASSDATA,
 35                     CH57xNET_NUM_PBUF,
 36                     CH57xNET_NUM_POOL_BUF
 37                     };
 38  UINT16 MemSize[8] = {CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IPRAW_PCB),
 39                     CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_UDP_PCB),
 40                     CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB),
 41                     CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_PCB_LISTEN),
 42                     CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_TCP_SEG),
 43                     CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_IP_REASSDATA),
 44                     CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(0),
 45                     CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_PBUF) + CH57xNET_MEM_ALIGN_SIZE(CH57xNET_SIZE_POOL_BUF)
 46                     };
 47 __align(4)UINT8 Memp_Memory[CH57xNET_MEMP_SIZE];
 48 __align(4)UINT8 Mem_Heap_Memory[CH57xNET_RAM_HEAP_SIZE];
 49 __align(4)UINT8 Mem_ArpTable[CH57xNET_RAM_ARP_TABLE_SIZE];
 50 /******************************************************************************/
 51 /* 本演示程序的相关宏 */
 52 #define RECE_BUF_LEN   536  //接收缓冲区的大小 
 53 /* CH57xNET库TCP的MSS长度为536字节,即一个TCP包里的数据部分最长为536字节 */
 54 /* TCP协议栈采用滑动窗口进行流控,窗口最大值为socket的接收缓冲区长度。在设定 */
 55 /* RX_QUEUE_ENTRIES时要考虑MSS和窗口之间的关系,例如窗口值为4*MSS,则远端一次会发送 */
 56 /* 4个TCP包,如果RX_QUEUE_ENTRIES小于4,则必然会导致数据包丢失,从而导致通讯效率降低 */
 57 /* 建议RX_QUEUE_ENTRIES要大于( 窗口/MSS ),如果多个socket同时进行大批量发送数据,则 */ 
 58 /* 建议RX_QUEUE_ENTRIES要大于(( 窗口/MSS )*socket个数) 在多个socket同时进行大批数据收发时 */
 59 /* 为了节约RAM,请将接收缓冲区的长度设置为MSS */
 60 
 61 /* CH579相关定义 */
 62 UINT8 MACAddr[6] = {0x84,0xc2,0xe4,0x02,0x03,0x04};  //CH579MAC地址 
 63 UINT8 IPAddr[4] = {0};  //CH579IP地址 
 64 UINT8 GWIPAddr[4] = {192,168,1,1}; //CH579网关
 65 UINT8 IPMask[4] = {255,255,255,0}; //CH579子网掩码 
 66 UINT8 DESIP[4] = {192,168,1,100}; //目的IP地址 
 67 
 68 UINT8 SocketId;  //保存socket索引,可以不用定义 
 69 UINT8 SocketRecvBuf[RECE_BUF_LEN]; //socket接收缓冲区 
 70 UINT8 MyBuf[RECE_BUF_LEN]; //定义一个临时缓冲区 
 71 
 72 
 73 //extern const UINT16 *memp_num;
 74 
 75 /*******************************************************************************
 76 * Function Name  : IRQ_Handler
 77 * Description    : IRQ中断服务函数
 78 * Input          : None
 79 * Output         : None
 80 * Return         : None
 81 *******************************************************************************/
 82 void ETH_IRQHandler( void )    //以太网中断
 83 {
 84     CH57xNET_ETHIsr();    //以太网中断中断服务函数
 85 }
 86 
 87 void TMR0_IRQHandler( void ) //定时器中断
 88 {
 89     CH57xNET_TimeIsr(CH57xNETTIMEPERIOD); //定时器中断服务函数
 90     R8_TMR0_INT_FLAG |= 0xff;    //清除定时器中断标志
 91 }
 92 
 93 
 94 
 95 /*******************************************************************************
 96 * Function Name  : mStopIfError
 97 * Description    : 调试使用,显示错误代码
 98 * Input          : iError 错误代码
 99 * Output         : None
100 * Return         : None
101 *******************************************************************************/
102 void mStopIfError(UINT8 iError)
103 {
104     if (iError == CH57xNET_ERR_SUCCESS) return;  //操作成功 
105   PRINT("mStopIfError: %02X\r\n", (UINT16)iError); //显示错误 
106 }
107 
108 
109 /*******************************************************************************
110 * Function Name  : CH57xNET_CreatTcpSocket
111 * Description    : 创建TCP Client socket
112 * Input          : None
113 * Output         : None
114 * Return         : None
115 *******************************************************************************/
116 void CH57xNET_CreatTcpSocket(void)
117 {
118    UINT8 i;                                                             
119    SOCK_INF TmpSocketInf;//创建临时socket变量 */
120 
121    memset((void *)&TmpSocketInf,0,sizeof(SOCK_INF)); //库内部会将此变量复制,所以最好将临时变量先全部清零
122    memcpy((void *)TmpSocketInf.IPAddr,DESIP,4); //设置目的IP地址
123    TmpSocketInf.DesPort = 1000;                     
124    TmpSocketInf.SourPort = 2000; //设置源端口
125    TmpSocketInf.ProtoType = PROTO_TYPE_TCP; //设置socekt类型
126    TmpSocketInf.RecvStartPoint = (UINT32)SocketRecvBuf; //设置接收缓冲区的接收缓冲区
127    TmpSocketInf.RecvBufLen = RECE_BUF_LEN;//设置接收缓冲区的接收长度
128    i = CH57xNET_SocketCreat(&SocketId,&TmpSocketInf);//创建socket,将返回的socket索引保存在SocketId中
129    mStopIfError(i);//检查错误
130 #ifdef  KEEPLIVE_ENABLE
131    CH57xNET_SocketSetKeepLive( SocketId, 1 ); //开启socket的KEEPLIVE功能(V06版本支持)
132 #endif
133 
134    i = CH57xNET_SocketConnect(SocketId); //TCP连接
135    mStopIfError(i); // 检查错误
136    i = CH57xNET_SetSocketTTL( SocketId,10 );
137    mStopIfError(i); //检查错误
138 }
139 
140 
141 /*******************************************************************************
142 * Function Name  : net_initkeeplive
143 * Description    : keeplive初始化
144 * Input          : None      
145 * Output         : None
146 * Return         : None
147 *******************************************************************************/
148 #ifdef  KEEPLIVE_ENABLE
149 void net_initkeeplive(void)
150 {
151     struct _KEEP_CFG  klcfg;
152     klcfg.KLIdle = 20000; //空闲 
153     klcfg.KLIntvl = 10000; //间隔 
154     klcfg.KLCount = 5; //次数 
155     CH57xNET_ConfigKeepLive(&klcfg);
156 }
157 #endif
158 
159 /*******************************************************************************
160 * Function Name  : CH57xNET_LibInit
161 * Description    : 库初始化操作
162 * Input          : ip      ip地址指针
163 *                :gwip    网关ip地址指针
164 *                : mask    掩码指针
165 *                : macaddr MAC地址指针 
166 * Output         : None
167 * Return         : 执行状态
168 *******************************************************************************/
169 UINT8 CH57xNET_LibInit(UINT8 *ip,UINT8 *gwip,UINT8 *mask,UINT8 *macaddr)
170 {
171     UINT8 i;
172     struct _CH57x_CFG cfg;
173 
174     if(CH57xNET_GetVer() != CH57xNET_LIB_VER)return 0xfc; //获取库的版本号,检查是否和头文件一致
175     CH57xNETConfig = LIB_CFG_VALUE; //将配置信息传递给库的配置变量
176     cfg.RxBufSize = RX_BUF_SIZE; 
177     cfg.TCPMss   = CH57xNET_TCP_MSS;
178     cfg.HeapSize = CH57x_MEM_HEAP_SIZE;
179     cfg.ARPTableNum = CH57xNET_NUM_ARP_TABLE;
180     cfg.MiscConfig0 = CH57xNET_MISC_CONFIG0;
181     CH57xNET_ConfigLIB(&cfg);
182     i = CH57xNET_Init(ip,gwip,mask,macaddr);
183 #ifdef  KEEPLIVE_ENABLE
184     net_initkeeplive( );
185 #endif
186     return (i);                      
187 }
188 
189 /*******************************************************************************
190 * Function Name  : CH57xNET_HandleSockInt
191 * Description    : Socket中断处理函数
192 * Input          : sockeid  socket索引
193 *                :initstat 中断状态
194 * Output         : None
195 * Return         : None
196 *******************************************************************************/
197 void CH57xNET_HandleSockInt(UINT8 sockeid,UINT8 initstat)
198 {
199     UINT32 len;
200     UINT32 totallen;
201     UINT8 *p = MyBuf;
202 
203     if(initstat & SINT_STAT_RECV) //接收中断 
204     {
205         len = CH57xNET_SocketRecvLen(sockeid,NULL); //查询长度 
206         PRINT("Receive Len = %d\r\n",len);                           
207         totallen = len;
208         CH57xNET_SocketRecv(sockeid,MyBuf,&len); //将接收缓冲区的数据读到MyBuf中
209         while(1)
210         {
211             len = totallen;
212             CH57xNET_SocketSend(sockeid,p,&len); //将MyBuf中的数据发送 
213             totallen -= len; //将总长度减去以及发送完毕的长度 
214             p += len; //将缓冲区指针偏移
215             if(totallen)continue; //如果数据未发送完毕,则继续发送
216             break; //发送完毕,退出 
217         }
218     }
219     if(initstat & SINT_STAT_CONNECT) //TCP连接中断 
220     { //产生此中断表示TCP已经连接,可以进行收发数据 
221         PRINT("TCP Connect Success\n");                           
222     }
223     if(initstat & SINT_STAT_DISCONNECT)//TCP断开中断 
224     { //产生此中断,CH579库内部会将此socket清除,置为关闭
225         PRINT("TCP Disconnect\n"); //应用曾需可以重新创建连接 
226     }
227     if(initstat & SINT_STAT_TIM_OUT) //TCP超时中断 
228     { //产生此中断,CH579库内部会将此socket清除,置为关闭
229         PRINT("TCP Timout\n"); //应用曾需可以重新创建连接 
230     }
231 }
232 
233 
234 /*******************************************************************************
235 * Function Name  : CH57xNET_HandleGloableInt
236 * Description    : 全局中断处理函数
237 * Input          : None
238 * Output         : None
239 * Return         : None
240 *******************************************************************************/
241 void CH57xNET_HandleGlobalInt(void)
242 {
243     UINT8 initstat;
244     UINT8 i;
245     UINT8 socketinit;
246     initstat = CH57xNET_GetGlobalInt(); //读全局中断状态并清除
247     if(initstat & GINT_STAT_UNREACH)  //不可达中断
248     {
249         PRINT("UnreachCode :%d\n",CH57xInf.UnreachCode); //查看不可达代码
250         PRINT("UnreachProto :%d\n",CH57xInf.UnreachProto);//查看不可达协议类型
251         PRINT("UnreachPort :%d\n",CH57xInf.UnreachPort); //查询不可达端口      
252     }
253     if(initstat & GINT_STAT_IP_CONFLI)  //IP冲突中断
254     {
255    
256     }
257     if(initstat & GINT_STAT_PHY_CHANGE)  //PHY改变中断
258     {
259         i = CH57xNET_GetPHYStatus();   //获取PHY状态
260         PRINT("GINT_STAT_PHY_CHANGE %02x\n",i);
261     }
262     if(initstat & GINT_STAT_SOCKET)  //Socket中断
263     {
264         for(i = 0; i < CH57xNET_MAX_SOCKET_NUM; i ++)                     
265         {
266             socketinit = CH57xNET_GetSocketInt(i); //读socket中断并清零
267             if(socketinit)CH57xNET_HandleSockInt(i,socketinit); //如果有中断则清零
268         }    
269     }
270 }
271 
272 /*******************************************************************************
273 * Function Name  : Timer0Init
274 * Description    : 定时器1初始化
275 * Input          : time 定时时间
276 * Output         : None
277 * Return         : None
278 *******************************************************************************/
279 void Timer0Init(UINT32 time)
280 {
281     R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;//清除所有计数值 
282     R8_TMR0_CTRL_MOD = 0;    //设置定时器模式 
283     R32_TMR0_CNT_END = FREQ_SYS/1000000*time;    //设置定时时间 
284     R8_TMR0_INT_FLAG = R8_TMR0_INT_FLAG;//清除标志 
285     R8_TMR0_INTER_EN = RB_TMR_IE_CYC_END;//定时中断 
286     R8_TMR0_CTRL_MOD |= RB_TMR_COUNT_EN;
287     NVIC_EnableIRQ(TMR0_IRQn);    
288 }
289 
290 
291 /*******************************************************************************
292 * Function Name  : CH57xNET_DHCPCallBack
293 * Description    : DHCP回调函数
294 * Input          : None
295 * Output         : None
296 * Return         : 执行状态
297 *******************************************************************************/
298 UINT8 CH57xNET_DHCPCallBack(UINT8 status,void *arg)
299 {
300     UINT8 *p;
301    
302     if(!status){ //成功
303         p = arg; //产生此中断,CH57xNET库内部会将此socket清除,置为关闭
304         PRINT("DHCP Success\n");
305         memcpy(IPAddr,p,4);
306         memcpy(GWIPAddr,&p[4],4);
307         memcpy(IPMask,&p[8],4); //产生此中断,CH57xNET库内部会将此socket清除,置为关闭
308         PRINT("IPAddr = %d.%d.%d.%d \n",(UINT16)IPAddr[0],(UINT16)IPAddr[1],
309               (UINT16)IPAddr[2],(UINT16)IPAddr[3]);
310         PRINT("GWIPAddr = %d.%d.%d.%d \n",(UINT16)GWIPAddr[0],(UINT16)GWIPAddr[1],
311               (UINT16)GWIPAddr[2],(UINT16)GWIPAddr[3]);
312         PRINT("IPAddr = %d.%d.%d.%d \n",(UINT16)IPMask[0],(UINT16)IPMask[1],
313               (UINT16)IPMask[2],(UINT16)IPMask[3]);
314         PRINT("DNS1: %d.%d.%d.%d\n",p[12],p[13],p[14],p[15]);
315         PRINT("DNS2: %d.%d.%d.%d\n",p[16],p[17],p[18],p[19]);
316 //  CH57xNET_CreatTcpSocket();   //可以在此处,在DHCP完成后进行TCP连接 
317 //    PRINT("creat tcp sockrt!\r\n"); 
318     }
319     else{ //产生此中断,CH57xNET库内部会将此socket清除,置为关闭           
320         PRINT("DHCP Fail %02x\n",status);
321     }                                                          
322     return 0;
323 }
324 
325 /*******************************************************************************
326 * Function Name  : SystemClock_UART1_init
327 * Description    : 系统时钟和串口1初始化,串口1用于打印输出
328 * Input          : None
329 * Output         : None
330 * Return         : None
331 *******************************************************************************/
332 void SystemClock_UART1_init(void)
333 {
334   PWR_UnitModCfg(ENABLE, UNIT_SYS_PLL); //PLL上电 
335   DelsyMs(3); 
336   SetSysClock(CLK_SOURCE_HSE_32MHz); //外部晶振 PLL 输出32MHz 
337   GPIOA_SetBits( GPIO_Pin_9 );
338   GPIOA_ModeCfg( GPIO_Pin_9, GPIO_ModeOut_PP_5mA ); //串口1的IO口设置
339     UART1_DefInit( ); //串口1初始化 
340 }
341 
342 /*******************************************************************************
343 * Function Name  : main
344 * Description    : 主函数
345 * Input          : None
346 * Output         : None
347 * Return         : None
348 *******************************************************************************/
349 int main(void) 
350 {
351   UINT8 i = 0;
352 
353     SystemClock_UART1_init(); 
354   i = CH57xNET_LibInit(IPAddr,GWIPAddr,IPMask,MACAddr); //库初始化 
355   mStopIfError(i);  //检查错误 
356   PRINT("CH57xNETLibInit Success\r\n");  
357     Timer0Init( 10000 );    //初始化定时器:10ms 
358     NVIC_EnableIRQ(ETH_IRQn);    
359     while ( CH57xInf.PHYStat < 2 ) DelsyMs(50);
360     if(!i)CH57xNET_DHCPStart(CH57xNET_DHCPCallBack); //启动DHCP                                              
361   PRINT("CH579 dhcp client create!\r\n");       
362   while(1)
363   {
364         CH57xNET_MainTask();//CH57xNET库主任务函数,需要在主循环中不断调用 
365         if(CH57xNET_QueryGlobalInt())CH57xNET_HandleGlobalInt(); //查询中断,如果有中断,则调用全局中断处理函数 
366   }
367 }
368 /*********************************** endfile **********************************/

 

CH57xNETLibInit Success

CH579 dhcp client create!

GINT_STAT_PHY_CHANGE 02
DHCP Success
IPAddr = 192.168.1.11 
GWIPAddr = 192.168.1.1 
IPAddr = 255.255.255.0 
DNS1: 168.126.63.1
DNS2: 168.126.63.2

 

上一篇:CH579/CH57x 蓝牙从机使用注意事项


下一篇:CH579-SPI0 & SPI1