上面的程序是最简单的使用lwIP来循环发送UDP数据报,下面对它进行完善后,使它具有接收UDP数据报的功能,并在需要的时候来发送UDP数据包的一个简单例子,并顺便学习几个重要的字符串处理函数的使用。
#include <string.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_nvic.h" #include "inc/hw_types.h" #include "inc/hw_sysctl.h"
#include "driverlib/ethernet.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/gpio.h" #include "driverlib/sysctl.h"
#include "utils/lwiplib.h" #include "utils/ustdlib.h"
#define My_Mac_ID {0X00,0x14,0x97,0x0F,0x1D,0xE3} //存储以太网控制器的物理地址,即MAC地址
#define MY_IP_ID {192,168,0,100} //以太网通信的IP地址 #define IP_MARK_ID {255,255,255,0} //255.255.255.0,子网掩码 #define MY_GATEWAY_ID {192,168,0,1} //以太网通信的网关地址 static const unsigned char pucMACAddress[]=My_Mac_ID; static const unsigned char IPAddress[] = MY_IP_ID; static const unsigned char NetMaskAddr[] = IP_MARK_ID; static const unsigned char GwWayAddr[] = MY_GATEWAY_ID;
//const static unsigned char UDPData[]="LwIP UDP客户端在Luminary微控制器上的测试\r\n";
#define SYSTICKHZ 100 #define SYSTICKMS (1000 / SYSTICKHZ) #define SYSTICKUS (1000000 / SYSTICKHZ) #define SYSTICKNS (1000000000 / SYSTICKHZ)
static struct udp_pcb *g_psPCB = NULL; void SysTickIntHandler(void) { lwIPTimer(SYSTICKMS);
} static void APP_recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port) { char *pcData = p->payload; struct pbuf *p_out; static char pcBuf[100]; unsigned long ulIPAddr; unsigned char pucMACAddr[6]; ulIPAddr = lwIPLocalIPAddrGet(); if(ulIPAddr == 0) { return; } lwIPLocalMACGet(pucMACAddr); usprintf(pcBuf,"\r\nTHE TARGET IP IS:%d.%d.%d.%d AND THE MAC IS:%02X%02X%02X%02X%02X%02X", ((ulIPAddr >> 0) & 0xFF), ((ulIPAddr >> 8) & 0xFF), ((ulIPAddr >> 16) & 0xFF), ((ulIPAddr >> 24) & 0xFF), pucMACAddr[0], pucMACAddr[1], pucMACAddr[2], pucMACAddr[3], pucMACAddr[4], pucMACAddr[5]); //说明是外设控制 p_out = pbuf_alloc(PBUF_TRANSPORT, strlen(pcBuf), PBUF_RAM); if(p_out != NULL) { memcpy(p_out->payload,pcBuf, strlen(pcBuf)); udp_send(g_psPCB, p_out); pbuf_free(p_out); } if(strncmp(pcData, "CONTROL LED ON", 14) == 0) { GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, GPIO_PIN_0); pbuf_free(p); return; }
if(ustrstr(pcData, "OFF") != NULL) { GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0); pbuf_free(p); return; } pbuf_free(p); return; } void io_init(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_0); GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 0); }
int main(void) { struct ip_addr ulIPAddr,ulNetMask,ulGWAddr; struct udp_pcb *Pcb1; struct ip_addr ipaddr1; // struct pbuf *p;
if(REVISION_IS_A2) { SysCtlLDOSet(SYSCTL_LDO_2_75V); }
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ); SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH); SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinTypeEthernetLED(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3);
io_init();
SysTickPeriodSet(SysCtlClockGet() / SYSTICKHZ); SysTickEnable(); SysTickIntEnable();
IntMasterEnable(); IP4_ADDR(&ulIPAddr,IPAddress[3],IPAddress[2],IPAddress[1],IPAddress[0]); IP4_ADDR(&ulNetMask,NetMaskAddr[3],NetMaskAddr[2],NetMaskAddr[1],NetMaskAddr[0]); IP4_ADDR(&ulGWAddr,GwWayAddr[3],GwWayAddr[2],GwWayAddr[1],GwWayAddr[0]); lwIPInit(pucMACAddress,ulIPAddr.addr, ulNetMask.addr, ulGWAddr.addr, IPADDR_USE_STATIC); // p = pbuf_alloc(PBUF_RAW,sizeof(UDPData),PBUF_RAM); // p->payload=(void *)UDPData; IP4_ADDR(&ipaddr1,192,168,0,127); g_psPCB=Pcb1 = udp_new(); udp_recv(Pcb1, APP_recv_udp, NULL); udp_bind(Pcb1,IP_ADDR_ANY,1025); /* 绑定本地IP地址 */ udp_connect(Pcb1,&ipaddr1,1025); /* 连接远程主机 */
while(1) { // udp_send(Pcb1,p); // SysCtlDelay(SysCtlClockGet()/3); }
}
当在TCP&UDPdebug中发送:CONTROL LED ON时,会点亮开发板上的LED。并返回开发板的IP地址和MAC地址。
当我们发送的字符中含有:OFF时,就会关闭LED。
我这么做,是为了把几个重要的字符串处理函数都包括进来。其中它们基本上都在utils/ustdlib.c中,还有个别在string.h中引用。简单介绍下:
usprintf:是对标准的sprintf的改写,主要作用就是格式化打印字符串。
strncmp:C标准库中的字符串比较函数。
用 法: int strncmp(char *str1, char *str2, int maxlen);
说明:比较字符串str1和str2的大小,如果str1小于str2,返回值就<0,反之如果str1大于str2,返回值就>0,如果str1等于str2,返回值就=0,maxlen指的是str1与str2的比较的字符数。此函数功能即比较字符串str1和str2的前maxlen个字符。
ustrstr:也是对C库函数中的原来改写的,作用是在一个字符串中寻找另一个字符串。
在发送一个UDP数据报的时候,我们就分配一个合适大小的pbuf,但发送完了之后,记得释放它,否则发送的数据多了,会把RAM耗尽的,这就是为什么有的朋友会发现数据发送一段时间后,就自动停止发送了,内存用完了,能不停止吗?
[ 本帖最后由 academic 于 2010-12-2 17:53 编辑 ] |