之前应用CH561出现问题,现在找销售要来最新的CH32V307的开发板 也是还有如下的问题:WCHNET_SocketUdpSendTo发送到一个不在线的 目的地IP 之后 整个socket 卡死,不能再发送 也不能恢复 直到重启。 这个bug 有没有其他使用者遇到过,还是根本不支持 直接
6月2日的evt测试表示没有问题
while(1)
{
WCHNET_MainTask();
if(WCHNET_QueryGlobalInt())
{
WCHNET_HandleGlobalInt();
}
if(keypress==1) //PA0作为按键输入 按一次 发送数据到以下两个IP地址
{
i = WCHNET_SocketUdpSendTo( SocketId,str,&len,roomaddr1,7888) ;
printf("roomaddr1=%d\r\n", i);
i=WCHNET_SocketUdpSendTo( SocketId,str,&len,roomaddr2,7888) ;
printf("roomaddr2=%d\r\n",i);
keypress=0;
}
}
这个是我的代码,是否是我使用上的问题 roomaddr1 roomaddr2 均为 与本机ip同网段的IP,这个是主动发送 。只要这两个IP设备都在线 发送没有问题,只有有其一不在线的 则不能再发送。
如果你是按照官方例程在接收回调函数里面再发送给对方,肯定没问题的!
我也测试了主动发送,没问题,只是打印出来GINT_STAT_UNREACH,估计你问题出在socketid身上
socketid 设置有什么 要求吗 就是按照官方设置了一个目的地地址 请指教
void WCHNET_CreateUdpSocket(void)
{
u8 i;
SOCK_INF TmpSocketInf;
memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
TmpSocketInf.SourPort = srcport;
TmpSocketInf.ProtoType = PROTO_TYPE_UDP;
TmpSocketInf.RecvStartPoint = (u32) SocketRecvBuf;
TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
TmpSocketInf.AppCallBack = WCHNET_UdpServerRecv;
i = WCHNET_SocketCreat(&SocketId, &TmpSocketInf);
printf("WCHNET_SocketCreat %d\r\n", SocketId);
mStopIfError(i);
}
创建socketid 都是用的官方的例程函数
#include "string.h"
#include "debug.h"
#include "WCHNET.h"
#include "eth_driver.h"
u8 str[] = "ch03";
u8 roomaddr1[4] = {192,168,100,241};
u8 roomaddr2[4] = {192,168,100,242};
int keypress=0;
u8 MACAddr[6]; //MAC address
u8 IPAddr[4] = { 192, 168, 100, 174 }; //IP address
u8 GWIPAddr[4] = { 192, 168, 100, 1 }; //Gateway IP address
u8 IPMask[4] = { 255, 255, 255, 0 }; //subnet mask
u8 IP255[4] = { 255, 255, 255, 255}; //subnet mask
u16 srcport = 1002; //source port
u8 SocketId;
u8 SocketRecvBuf[RECE_BUF_LEN]; //socket receive buffer
void mStopIfError(u8 iError)
{
if (iError == WCHNET_ERR_SUCCESS)
return;
printf("Error: %02X\r\n", (u16) iError);
}
void EXTI0_INT_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
EXTI_InitTypeDef EXTI_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* GPIOA ----> EXTI_Line0 */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = { 0 };
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseStructure.TIM_Period = SystemCoreClock / 1000000 - 1;
TIM_TimeBaseStructure.TIM_Prescaler = WCHNETTIMERPERIOD * 1000 - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
NVIC_EnableIRQ(TIM2_IRQn);
}
void WCHNET_UdpServerRecv(struct _SCOK_INF *socinf, u32 ipaddr, u16 port,
u8 *buf, u32 len)
{
u8 ip_addr[4], i;
printf("Remote IP:");
for (i = 0; i < 4; i++) {
ip_addr[i] = ipaddr & 0xff;
printf("%d ", ip_addr[i]);
ipaddr = ipaddr >> 8;
}
printf("srcport = %d len = %d socketid = %d\r\n", port, len,
socinf->SockIndex);
WCHNET_SocketUdpSendTo(socinf->SockIndex, buf, &len, ip_addr, port);
}
void WCHNET_CreateUdpSocket (void)
{
u8 i;
SOCK_INF TmpSocketInf;
memset((void *) &TmpSocketInf, 0, sizeof(SOCK_INF));
TmpSocketInf.DesPort = 1002;
TmpSocketInf.SourPort = 1002;
TmpSocketInf.ProtoType = PROTO_TYPE_UDP;
TmpSocketInf.RecvStartPoint = (u32) SocketRecvBuf;
TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
TmpSocketInf.AppCallBack = WCHNET_UdpServerRecv;
i = WCHNET_SocketCreat(&SocketId, &TmpSocketInf);
printf("WCHNET_SocketCreat %d\r\n", SocketId);
mStopIfError(i);
}
void WCHNET_HandleSockInt(u8 socketid, u8 intstat)
{
if (intstat & SINT_STAT_RECV) //receive data
{
}
if (intstat & SINT_STAT_CONNECT) //connect successfully
{
printf("TCP Connect Success\r\n");
}
if (intstat & SINT_STAT_DISCONNECT) //disconnect
{
printf("TCP Disconnect\r\n");
}
if (intstat & SINT_STAT_TIM_OUT) //timeout disconnect
{
printf("TCP Timeout\r\n");
}
}
void WCHNET_HandleGlobalInt(void)
{
u8 intstat;
u16 i;
u8 socketint;
intstat = WCHNET_GetGlobalInt(); //get global interrupt flag
if (intstat & GINT_STAT_UNREACH) //Unreachable interrupt
{
printf("GINT_STAT_UNREACH\r\n");
}
if (intstat & GINT_STAT_IP_CONFLI) //IP conflict
{
printf("GINT_STAT_IP_CONFLI\r\n");
}
if (intstat & GINT_STAT_PHY_CHANGE) //PHY status change
{
i = WCHNET_GetPHYStatus();
if (i & PHY_Linked_Status)
printf("PHY Link Success\r\n");
}
if (intstat & GINT_STAT_SOCKET) { //socket related interrupt
for (i = 0; i < WCHNET_MAX_SOCKET_NUM; i++) {
socketint = WCHNET_GetSocketInt(i);
if (socketint)
WCHNET_HandleSockInt(i, socketint);
}
}
}
int main(void)
{
u8 i;
u32 len;
len=4;
Delay_Init();
USART_Printf_Init(115200); //USART initialize
EXTI0_INT_INIT();
printf("UdpServer Test\r\n");
printf("SystemClk:%d\r\n", SystemCoreClock);
printf("net version:%x\n", WCHNET_GetVer());
if ( WCHNET_LIB_VER != WCHNET_GetVer()) {
printf("version error.\n");
}
WCHNET_GetMacAddr(MACAddr); //get the chip MAC address
printf("mac addr:");
for (int i = 0; i < 6; i++)
printf("%x ", MACAddr[i]);
printf("\n");
TIM2_Init();
i = ETH_LibInit(IPAddr, GWIPAddr, IPMask, MACAddr); //Ethernet library initialize
mStopIfError(i);
if (i == WCHNET_ERR_SUCCESS)
printf("WCHNET_LibInit Success\r\n");
WCHNET_CreateUdpSocket(); //Create UDP Socket
while(1)
{
WCHNET_MainTask();
if(WCHNET_QueryGlobalInt())
{
WCHNET_HandleGlobalInt();
}
if(keypress==1) //PA0作为按键输入 按一次 发送数据到以下两个IP地址
{
i = WCHNET_SocketUdpSendTo( SocketId,str,&len,roomaddr1,1002) ;
// i=WCHNET_SocketUdpSendTo( SocketId,str,&len,roomaddr2,7888) ;
// printf("roomaddr2=%d\r\n",i);
keypress=0;
}
}
}
/*以上是我整个main.c的全部代码,使用pa0中断 按下之后 发送一次数据,你可以修改IP地址 测试即可,对方使用电脑网络调试助手,现在即使不发给其他IP,第一次也发送不出去。一定要先收到电脑发来第一次数据之后,才可以 主动发送数据。现在测试到的就是 上电之后 一定要电脑先发数据过来,再按键 才可以发送数据到电脑。否则上电之后先按键发送了, 即使之后电脑再发数据, 按键的主动发送也不会成功,而且 如果上电之后 主动发送 会提示 TCP Timeout。
*/
以上是我整个main.c的全部代码,使用pa0中断 按下之后 发送一次数据,你可以修改IP地址 测试即可,对方使用电脑网络调试助手,现在即使不发给其他IP,第一次也发送不出去。一定要先收到电脑发来第一次数据之后,才可以 主动发送数据。现在测试到的就是 上电之后 一定要电脑先发数据过来,再按键 才可以发送数据到电脑。否则上电之后先按键发送了, 即使之后电脑再发数据, 按键的主动发送也不会成功,而且 如果上电之后 主动发送 会提示 TCP Timeout。
大概看了一下,其余都基本一样,除了这个函数 void WCHNET_CreatSocket(void)
这个是我使用的函数,全部功能正常,不会有第一次发送不了,也不会有超时发生,你说的问题,我这里一个也没有
void WCHNET_CreatSocket(void)
{
SOCK_INF TmpSocketInf;
memset((void *)&TmpSocketInf, 0, sizeof(SOCK_INF));
TmpSocketInf.SourPort = LocalPort;
TmpSocketInf.ProtoType = PROTO_TYPE_UDP;
TmpSocketInf.RecvBufLen = RECE_BUF_LEN;
TmpSocketInf.AppCallBack = WCHNET_UdpServerRecv;
WCHNET_SocketCreat(&SocketId, &TmpSocketInf);
WCHNET_ModifyRecvBuf(SocketId, (u32)SocketRecvBuf[SocketId], RECE_BUF_LEN);
}
改成你这样还是不行,可能是板子硬件不行,板子是刚刚拿到的沁恒的开发板,调这个东西真是心累
出现相似的问题了,要先收到一组数据后才能发出去,请教一下怎么解决,方便的话可以看看代码吗
您好,我这边测试没有发现这种情况,不知您是采用怎样的方式测试的,我是通过按键,按一下发送数据,因为您一开始主动发的时候不知道接收端的端口,所以会出现数据不可达的情况,如图1,若您想接收到数据,可以先通过调试助手发一次数据,获取已连通的接收端端口,修改代码中的端口号,重新编译烧录之后(网络调试助手别断开),通过按键发送即可接收到数据,若您是直接建立的固定端口,则不需要上述操作,直接通过按键发送即可接收到数据。测试结果如图2所示,测试例程已附上,您可以测试一下,后续有问题可以通过邮箱联系:kx@wch.cn
图1:
图2