CH32V307 以太网接近满速后,几秒或几十秒后就死机

 CH32V307内置PHY,使用RT Thread  系统,其它全部采用默认配置,主任务只有一个以太网任务,不管是只接收、只发送、回传,数据量大了(接近满速)后,几秒或几十秒后就死机。

请帮忙分析是什么问题,谢谢。



代码:

while(1)
    {
        rt_thread_delay(500);   //* wait eth phy enable

        host = (struct hostent*)gethostbyname(url);

        serveraddr.sin_family = AF_INET;
        serveraddr.sin_port = htons(port);
        serveraddr.sin_addr = *((struct  in_addr *)host->h_addr);
        rt_memset(&(serveraddr.sin_zero), 0, sizeof(serveraddr.sin_zero));

        if((sock=socket(AF_INET,SOCK_STREAM,0)) == -1)
        {
            rt_kprintf("Socket error sock=%d\n",sock);
            break;
        }

        if (connect(sock, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr)) == -1)
        {
            rt_kprintf("Connect fail!\n");
            closesocket(sock);
            continue;
        }
        else
        {
            rt_kprintf("Connect sock_%d  successful\n",sock);
        }

        while(1)
        {
            /*bytes_received = recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0);

            if (bytes_received < 0)
            {
                // receive timeout, continue the receiving of next socket
                break;
            }

            else {
                rx_buffer[bytes_received] = 0;
            }*/
           //int err = send(sock, rx_buffer, strlen(rx_buffer), 0);
            int err = send(sock, rx_buffer, 100, 0);
            //rt_thread_mdelay(100);
            if (err < 0) {
                rt_kprintf("Error occurred during sending: errno % .\r\n", err);
                rt_kprintf("Shutting down socket and restarting...");
               // shutdown(sock, 0);
                closesocket(sock);
                rt_thread_mdelay(1000);
                break;
            }
        }

    }
打印信息,但经常不完整。
 \ | /
- RT -     Thread Operating System
 / | \     4.0.4 build Mar 25 2022
 2006 - 2021 Copyright by rt-thread team
lwIP-2.1.2 initialized!
MCU: CH32V307
SysClk: 144000000Hz
msh >Connect fail!
Connect fail!
Connect sock_0  successful
state!
Assertion: 1836 in ../rt-thread/components/net/lwip-2.1.2/src/api/api_msg.c, thread etx
 hardfult
mepc:0bd3fca8
mcause:00000001
mtval:0bd3fca8


LWIP 配置

image.png


测速速度

image.png

您好,您可以尝试以下几个方法:

  1. 您可以在死机时,PING   CH32V307的IP地址,看看能否PING通,来鉴别协议栈是否还在正常处理

  2. 您可以在以太网的线程里面加打印调试,看任务是否正常运行

  3. 您可以在芯片HardFault中断里面加打印,看芯片在“死机”时,是否有进入HardFault中断。


/*******************************************************************************
* Function Name  : HardFault_Handler
* Description    : This function handles Hard Fault exception.
* Input          : None
* Return         : None
*******************************************************************************/
void HardFault_Handler(void)
{
    GET_INT_SP();
    rt_interrupt_enter();
    rt_kprintf(" hardfult\r\n");
    rt_kprintf("mepc:%08x\r\n",__get_MEPC());
    rt_kprintf("mcause:%08x\r\n",__get_MCAUSE());
    rt_kprintf("mtval:%08x\r\n",__get_MTVAL());
    while(1);
    rt_interrupt_leave();
    FREE_INT_SP();
}

从打印信息,明显是进入了HardFault_Handler,此时协议栈及串口都停止了


您好,您可以看一下此时硬件错误中断的打印值,看是否是内存管理等原因导致的。


我想知道,这几个是什么含义,我也遇见此问题。

    rt_kprintf("mepc:%08x\r\n",__get_MEPC());
    rt_kprintf("mcause:%08x\r\n",__get_MCAUSE());
    rt_kprintf("mtval:%08x\r\n",__get_MTVAL());



您好,mepc、mcause、mtval均为CSR寄存器,其中,mepc寄存器值为当前遇到异常时的指令 PC 值,或中断前下一条预执行的指令 PC 值,退出异常或中断后微处理器的返回地址保存在mepc中。mcause寄存器值为当前异常种类或中断编号值,可以通过该值查看引起异常的原因或判断中断的来源。mtval寄存器值主要反映引起当前异常的存储器访问地址或指令编码,当进入异常和中断时,硬件将自动更新mtval的值。关于这三个CSR寄存器的具体介绍,可参考我们QingKeV4微处理器手册,手册下载链接如下:

http://www.wch.cn/downloads/QingKeV4_Processor_Manual_PDF.html

 


谢谢你,TECH62。socket每1秒收发一次数据,运行一会儿就进入硬件故障中断了(可能几分钟,可能十几分钟)


中断函数:

void HardFault_Handler(void)

{

    GET_INT_SP();

    rt_interrupt_enter();

    rt_kprintf(" hardfult\r\n");

    rt_kprintf(" %s\r\n", rt_thread_self()->name);

    rt_kprintf("mepc:%08x\r\n",__get_MEPC());

    rt_kprintf("mcause:%08x\r\n",__get_MCAUSE());

    rt_kprintf("mtval:%08x\r\n",__get_MTVAL());

    while(1);

    //NVIC_SystemReset(); // 硬件错误就重启模块

    rt_interrupt_leave();

    FREE_INT_SP();

}


输出:

 hardfult

 tcpip

mepc:706e7074

mcause:00000002(异常?保留?)

mtval:00000000


对应文档:

企业微信截图_1651050411662.png


您好,mepc的值为706e7074说明异常的返回地址为706e7074,这个已经超出了我们FLASH的地址范围,地址溢出了;mcause的值为2,说明是非法指令导致异常;mtval的值为00000000,即非法指令的指令编码为00000000。导致异常的原因可能是内存地址溢出了,访问越界了,可检查以下程序中是不是定义的数组长度不够导致的,或查看一下数组下标是否越界。后续若有问题,可通过邮箱和我沟通(lzs@wch.cn)。


我这边也遇到了同样的问题,V307+RTT+LWIP,即使不创建任何任务,仅仅在main里电灯,后台依然会报出硬件错误,PC指针会指向非法地址。


下面是报错信息和源码

1652329929195598.png

1652329929135083.png

1652329929113196.png

1652329930265627.png



您好,可以看一下8楼的分析,根据打印的信息,感觉你的问题和那个差不多。若方便,可以将你的程序发到我的邮箱(lzs@wch.cn),这边看一下。


源工程已发至lzs@wch.cn,目前工程基于RT Thread Studio下的CH32V307工程创建:打开LWIP,创建呼吸灯线程,链接脚本修改RAM大小至128K。

目前调试进展:打开RTT的内存跟踪和堆栈溢出检测后,插上网线后,稳定复现stack overflow,因此hardfault确实是由于堆栈溢出导致的,但溢出原因未明。

调试截图:

1652405290681596.png

1652405290200572.png

1652405290528762.png




不知道前面的几位有解决这个问题吗。虽然我已经切换至裸机开发了,但我还是想用rt-thread开发。


移植cherryUSB的过程中,也是莫名会进入hardfult,后来发现是空闲线程的stack size太小了,增大后没有出现了


只有登录才能回复,可以选择微信账号登录