WCH沁恒单片机
直播中

fdvcxhtg

9年用户 1106经验值
擅长:嵌入式技术
私信 关注
[问答]

WCHNET_SocketUdpSendTo发送到一个不在线的目的地IP之后整个socket卡死怎么解决?

之前应用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=%drn", i);
             i=WCHNET_SocketUdpSendTo( SocketId,str,&len,roomaddr2,7888) ;
             printf("roomaddr2=%drn",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 %drn", 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: %02Xrn", (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 = ipaddr & 0xff;
        printf("%d ", ip_addr);
        ipaddr = ipaddr >> 8;
    }
    printf("srcport = %d len = %d socketid = %drn", 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 %drn", 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 Successrn");
    }
    if (intstat & SINT_STAT_DISCONNECT)                         //disconnect
    {
        printf("TCP Disconnectrn");
    }
    if (intstat & SINT_STAT_TIM_OUT)                            //timeout disconnect
    {
        printf("TCP Timeoutrn");
    }
}
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_UNREACHrn");
    }
    if (intstat & GINT_STAT_IP_CONFLI)                            //IP conflict
    {
        printf("GINT_STAT_IP_CONFLIrn");
    }
    if (intstat & GINT_STAT_PHY_CHANGE)                           //PHY status change
    {
        i = WCHNET_GetPHYStatus();
        if (i & PHY_Linked_Status)
            printf("PHY Link Successrn");
    }
    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 Testrn");
    printf("SystemClk:%drn", SystemCoreClock);
    printf("net version:%xn", 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);
    printf("n");
    TIM2_Init();
    i = ETH_LibInit(IPAddr, GWIPAddr, IPMask, MACAddr);           //Ethernet library initialize
    mStopIfError(i);
    if (i == WCHNET_ERR_SUCCESS)
        printf("WCHNET_LibInit Successrn");
    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=%drn",i);
             keypress=0;
        }
    }
}


/*以上是我整个main.c的全部代码,使用pa0中断 按下之后 发送一次数据,你可以修改IP地址 测试即可,对方使用电脑网络调试助手,现在即使不发给其他IP,第一次也发送不出去。一定要先收到电脑发来第一次数据之后,才可以 主动发送数据。现在测试到的就是 上电之后 一定要电脑先发数据过来,再按键 才可以发送数据到电脑。否则上电之后先按键发送了, 即使之后电脑再发数据, 按键的主动发送也不会成功,而且 如果上电之后 主动发送 会提示  TCP Timeout。


*/
  
  以上是我整个main.c的全部代码,使用pa0中断 按下之后 发送一次数据,你可以修改IP地址 测试即可,对方使用电脑网络调试助手,现在即使不发给其他IP,第一次也发送不出去。一定要先收到电脑发来第一次数据之后,才可以 主动发送数据。现在测试到的就是 上电之后 一定要电脑先发数据过来,再按键 才可以发送数据到电脑。否则上电之后先按键发送了, 即使之后电脑再发数据, 按键的主动发送也不会成功,而且 如果上电之后 主动发送 会提示  TCP Timeout。
  
  
  
  

回帖(2)

张艳

2022-7-18 10:22:40
大概看了一下,其余都基本一样,除了这个函数 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);
}

举报

翁靠庭

2022-7-18 10:22:44
改成你这样还是不行,可能是板子硬件不行,板子是刚刚拿到的沁恒的开发板,调这个东西真是心累
举报

更多回帖

发帖
×
20
完善资料,
赚取积分