This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TM4C129ENCPDT:将 tcpEcho 和 uartEchoDma 示例工程组合到单个工程中-调用系统中止、不知道原因

Guru**** 2033340 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1454067/tm4c129encpdt-combining-the-tcpecho-and-uartechodma-example-projects-into-a-single-project---system-abort-being-called-and-not-sure-why

器件型号:TM4C129ENCPDT

工具与软件:

您好!

我将使用此 MCU 接收基于以太网的命令、然后发送相关但不同的 UART 数据(这最终是一条具有此总线上其他嵌入式模块的 RS -485总线)。 为了实现这一目标、我将 tcpEcho 和 uartEchoDma 示例工程组合在一起。 我已让每一个都独立工作。

问题是、当我同时包含两组代码时、项目将运行大约3秒、并且项目将跳至中止。 我已将 tcpTask 设置为优先级1、将 uartTask 设置为优先级2。 没有使用信标、我认为这样没什么问题、因为 tcpTask 在没有活动时似乎会退出。

我是否需要使用信标或事件来协调这两个任务? tcpTask 应该具有优先级、但如果没有任何以太网活动、我需要执行 uartTask。 我已提供软件文件。

谢谢!

挪亚

e2e.ti.com/.../6318.tcpEchoHooks.c

e2e.ti.com/.../5751.tcpEcho.c

e2e.ti.com/.../5751.uartEcho.ce2e.ti.com/.../5751.main.ce2e.ti.com/.../EK_5F00_TM4C129EXL.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Noah、

     抱歉、我目前正在度假一整周。 当我下周回来时、我会调查你的问题。 请预计我的回复会有延迟。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    祝您度过愉快的假期!

    我已经在两个任务之间执行了信标、现在、项目位于"semaphore_pend (uartSys.sema、BIOS_wait_forever);"之后的空闲任务内。

    TCP 任务的"后台"似乎有很多事情要做(我的意思是调用所有功能以促进 TCP 操作)。  所需的操作是为 TCP 任务指定优先级、但是当此任务没有连接、也没有活动时、我希望 UART 任务被执行。   

    下面是我对这两个任务所做的更改。 它们使用相同的信标、并在另一模块中初始化。

    //________________________________________________====
    /**
    @返回
    -无效

    处理 TCP 连接的任务。 可以有多个正在运行的任务
    这个函数。
    */
    void echFxn
    (
    UArg arg0、//<TI RTOS 参数0
    UArg arg1 ///< TI RTOS 参数1
    )


    UART_Params uartParams;
    const char echoPrompt[]="\fEchoing characters:\r\n";

    InitUartParams(&uartParams);

    #ifdef MIKROE_DEV
    uart_handle uart2、uart4;
    uint32_t count = 0;
    uint32_t size = 0;
    //uint32_t delay = 0;
    char outputString[16];
    char inputString[16];
    static bool initComplete = false;

    /// semaphore_post (uartSys.sema);

    // Task_sleep(GetSleepTickCount());

    /*循环永远回显*/
    while (1)

    system_printf ("正在运行 echoFxn 函数\n");
    system_flush();

    如果(Semaphore_getCount (uartSys.sema)=0){
    system_printf ("Sem blocked in echoFxn\n");
    system_flush();
    }

    /*获取资源的访问权限*/
    Semaphore_pend (uartSys.sema、BIOS_wait_forever);

    if (false == initComplete)

    initComplete = true;

    uart2 = UART_open (Board_UART2、&uartParams);
    if (uart2 == NULL){
    system_abort ("打开 UART 时出错");
    }

    InitUartParams(&uartParams);
    uart4 = UART_open (Board_UART4、&uartParams);
    if (uart4 == NULL){
    system_abort ("打开 UART 时出错");
    }

    UART_write (uart2、echoPrompt、sizeof (echoPrompt));
    }

    snprintf (outputString、16、"计数为:%u"、count);
    count++;
    size = strlen (outputString);
    UART_write (uart2、outputString、size);
    UART_read (uart4、inputString、16);

    snprintf (outputString、16、"%s"、inputString);

    system_printf ("发送的字符串为:%s\r\n"、outputString);
    system_flush();

    Semaphore_post (uartSys.sema);

    Task_sleep(GetSleepTickCount());

    }
    #else
    字符输入;
    uart_handle uart0;

    uart0 = UART_open (Board_UART0、&uartParams);

    if (uart0 => NULL){
    system_abort ("打开 UART 时出错");
    }

    UART_write (uart0、echoPrompt、sizeof (echoPrompt));

    /*循环永远回显*/
    while (1){
    UART_READ (uart0、&input、1);
    UART_WRITE (uart0、&INPUT、1);
    }
    #endif

    }

    //________________________________________________====
    /**
    @返回
    -无效

    处理 TCP 连接的任务。 可以有多个正在运行的任务
    这个函数。
    */
    空 tcpWorker
    (
    UArg arg0、//<任务参数0
    UArg arg1 ///<任务参数1
    )

    int32_t clientfd =(int32_t) arg0;
    int32_t bytesRcvd;
    int32_t 字节 Sent;
    char buffer[TCPPACKETSIZE];

    system_printf ("tcpWorker: start clientfd = 0x%x\n"、clientfd);

    while ((bytesRcvd = recv (clientfd、buffer、TCPPACKETSIZE、0))> 0){
    bytesSent = send (clientfd、buffer、bytesRcvd、0);
    if (bytesSent < 0 || bytesSent!= bytesRcvd){
    system_printf ("错误:发送失败。\n");
    休息;
    }
    }
    system_printf ("tcpWorker stop clientfd = 0x%x\n"、clientfd);

    close (clientfd);
    }
    //________________________________________________====
    /**
    @返回
    -无效
    创建新任务来处理新的 TCP 连接。
    */
    void tcpHandler
    (
    UArg arg0、//<任务参数0
    UArg arg1 ///<任务参数1
    )

    int32_t status;
    int32_t clientfd;
    int32_t 服务器;
    结构 Sockaddr_in localAddr;
    struct sockaddr_in clientAddr;
    int32_t optval;
    int32_t optlen = sizeof (optval);
    socklen_t addrlen = sizeof (clientAddr);
    Task_Handle 任务处理;
    Task_Params 任务参数;
    Error_Block EB;

    system_printf ("正在运行 tcpHandler 函数\n");
    system_flush();

    如果(Semaphore_getCount (tcpTaskSys.sema)=0){
    system_printf ("在 tcpHandler\n"中阻止 Sem);
    system_flush();
    }

    /*获取资源的访问权限*/
    Semaphore_pend (tcpTaskSys.sema、BIOS_wait_forever);

    Server =套接字(AF_INET、SOCK_STREAM、IPPROTO_TCP);
    if (server ==-1){
    system_printf ("错误:未创建套接字。\n");
    shutdown (server);//goto shutdown;
    }


    memset (&localAddr、0、sizeof (localAddr));
    localAddr.sin_family = AF_INET;
    localAddr.sin_addr.s_addr = htonl (INADDR_ANY);
    localAddr.sin_port = htons (arg0);

    status = bind (server、(struct sockaddr *)&localAddr、sizeof (localAddr));
    if (status ==-1){
    system_printf ("错误:绑定失败。\n");
    shutdown (server);//goto shutdown;
    }

    状态=监听(服务器、NUMTCPWORKERS);
    if (status ==-1){
    system_printf ("错误:监听失败。\n");
    shutdown (server);//goto shutdown;
    }

    optval = 1;
    if (setsockopt (server, SOL_SOCKET、SO_KEEPALIVE、&optval、optlen)< 0){
    system_printf ("错误:setsockopt 失败\n");
    shutdown (server);//goto shutdown;
    }

    while (clientfd =
    接受(server、(struct sockaddr *)&clientAddr、&addrlen)!=-1)

    system_printf ("tcpHandler: creating thread clientfd =%d\n"、clientfd);

    /*初始化 Error_Block */
    error_init (&E);

    /*初始化默认值并设置参数。 */
    Task_Params_(TaskParams(&T);
    taskParams.arg0 =(UArg) clientfd;
    taskParams.STACKSIZE = 1280;
    taskParams.priority = 1;
    taskHandle = Task_create ((Task_Func Ptr) tcpWorker、&taskParams、&eb);
    if (taskHandle == NULL)

    system_printf ("错误:无法创建新任务\n");
    close (clientfd);
    }

    /* addrlen 是值结果参数、必须为下一个接受调用重置*/
    addrlen = sizeof (clientAddr);

    }

    Semaphore_post (tcpTaskSys.sema);

    Task_sleep(GetSleepTickCount());

    system_printf ("错误:接受失败。\n");
    system_flush();

    //停机:
    // if (服务器> 0){
    //关闭(服务器);
    //}
    }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    问题在于、当我同时包含两组代码时、项目将运行约3秒、并且跳至中止状态。

    我想知道您分配的系统堆栈大小。 如果您单独运行以太网和 UART 并看到它们正常工作、那么我认为任务堆栈大小应该足够了。 它是我想知道的系统堆栈。 增加系统堆栈该怎么办。 它会产生影响吗? 它仍然会中止吗? 或者、中止将需要超过3秒的时间? 请参见下面的、在这里您可以更改系统堆栈和堆大小。 也许还可以增加任务堆栈并确保它们足够。 您可以使用 ROV 来找出实际使用的堆栈数量。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Charles

    我今天花了大约一个小时来讨论这件事(当然不是足够长的时间来根源这件事)。 我将系统堆栈扩展到6200个。 在观察 ROV 时可以看到空闲任务用红色突出显示。 我稍后会做一些更多的故障排除,但这里有一些线索,我不能完全理解。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Noah、

     您能否看一下这两个帖子、看看它们是否有帮助。  

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/211175/sysbios-idle-task-stack-overflow

    https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/727866/rtos-cc2640r2f-idle-task-stack-overflow

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Charles

    简而言之、问题是我在项目的某个时间点包含了 USB 日志记录、但我忘记了这么做。 正是由于此原因导致空闲任务过高并致使工程调用 abort 函数。  

    删除与 USB 日志记录相关的代码后、您的建议提示我调查为什么调用空闲任务。 毕竟、只有在没有正在执行的任务时才调用空闲任务。 结果表明、信标的挂起和发布已造成意外的无效状态、在这种状态下、TCP 和 UART 任务同时暂停。

    我删除了对信标的所有调用。 将两个任务置于同一优先级、并且通过使用 UART 任务中的任务休眠函数、该任务开始工作。 tcpEcho 和 UART 都正常工作。  

    其他问题包括 UART 任务没有延迟、因此它占用 MCU 的所有带宽。 我添加了一个10ms 的任务睡眠、以便能够调用 TCP 任务。

    在最后一条注释中、在任务中使用 snprintf 是否有任何限制? 我观察到一些奇怪的行为,似乎是一个记忆泄漏。 我将对此进行深入研究、但想知道 TI 的 RTOS 是否有任何限制。

    感谢您的支持!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、Noah、

     很高兴您取得了良好的进展。  

    在最终备注中、在使用 snprintf 执行任务时是否存在任何限制? 我观察到一些奇怪的行为,似乎是一个记忆泄漏。 我将进一步对此进行探讨、但想知道 TI 的 RTOS 是否有任何限制

     snprintf()是一个 C 库函数、用于将 printf()函数的输出重定向到缓冲区。  我真的不觉得在使用它时有问题。 TivaWare 库有一个较简单版本的 snprintf、称为 usnprintf。 请查阅 C:\ti\TivaWare_C_Series-2.2.0.295\utils\ustdlib.c 文件以了解各种 printf 函数。 我认为这些更简单的函数将占用更少的内存空间、并有望避免出现的某些内存问题。