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.

[参考译文] RTOS/SIMPLELINK-MSP432-SDK:信号量挂起不会等待信号量发布、并导致 Hwi 异常

Guru**** 2581045 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/611251/rtos-simplelink-msp432-sdk-semaphore-pend-is-does-not-wait-for-semaphore-post-and-causes-hwi-exception

器件型号:SIMPLELINK-MSP432-SDK

工具/软件:TI-RTOS

支持路径:/工具与软件/帮助我解决问题/嵌入式产品软件工具/RTOS/

大家好、

我正在尝试使用 MSP432 1.40.00.28 SDK 在 TI-RTOS 中运行两个 UART 端口。

其中一个被 Display_printf()使用,另一个被连接到一个外部 UART 上,该 UART 连接到 FTDI USB 的 TX 和 RX 以串行方式,我使用 PC 中的串行终端发送和接收命令。 我能够在两个端口上输出。

接下来、我需要执行 UART_Read。 当接收到字符时、我在 UART 读取回调函数中执行 Semaphore_post 操作。  

void UART_read_callback (UART_Handle handle、void * buffer、size_t num)
{
Semaphore_post (uart3gSemHandle);
}

然后在 UART 解析函数中完成 Semaphore_pend 函数,如果 Semaphore_pend 成功,它将知道有 UART 数据要接收,因此执行 UART_read。 在读取它时、我让它通过写操作将它回传到我的终端、这样我就知道它是被读取的。

void * Uart3gParserTask (void * arg0)
{

const char testString[]="Testing\r\n";
int16 uart3gReturn=0;
/*创建 UART 实例*/
UART_PARAMS_INIT (uart3gParams);
uart3gParams.writeMode = UART_MODE_CALLBACK;
uart3gParams.readMode = UART_MODE_CALLACK;
uart3gParams.writeDataMode = UART_DATA_BINARY;
uart3gParams.readDataMode = UART_DATA_BINARY;
uart3gParams.readCallback = UART_READ_CALLBACK;
uart3gParams.writeCallback = UART_Write_Callback;
uart3gParams.readReturnMode = UART_return_full;
uart3gParams.readEcho = UART_ECHO_OFF;
uart3gParams.baudrate = 115200;
uart3g = UART_open (Board_UART1、&uart3gParams);// UART1为 eusciA2


Semaphore_Params_init (uart3gSemParams);
uart3gSemParams.mode = ti_SysBIOS_KNL_Semaphore_Mode_binary;
uart3gSemParams.instance->name ="OurSem3g";
Semaphore_struction (&uart3gSemStruct, 1,&uart3gSemParams);
uart3gSemHandle = Semaphore_handle (&uart3gSemStruct);


if (uart3g ==空)
{
Display_printf (myDisplay、0、0、"错误- UART 未打开\r\n);
}

UART_WRITE (uart3g、testString、sizeof (testString)); //仅用于测试

while (1)
{
//在这里挂起一个信号量。 这将阻止 while 环路并让其他任务运行、直到在 UART 读取回调中发布信标
int semCount = Semaphore_getCount (uart3gSemHandle);
Semaphore_pend (uart3gSemHandle、BIOS_WAIT_FOREVE);
semCount = Semaphore_getCount (uart3gSemHandle);
uart3gReturn = UART_Read (uart3g,&uart3gRxChar,7);
GPIO_TOGGLE (Board_GPIO_LED1);
UART_WRITE (uart3g、&uart3gRxChar、sizeof (uart3gRxChar));

usleep(10);
}
}

1)   在 while (1)循环中、Semaphore_getCount 在 Semaphore_pend 前返回1。 在经过信标挂起后、它为0。 这就是要发生的事情。 但是、下次它绕过 while 循环时、即使 Semaphore_getCount 为0、它也会超过 Semaphore_pend。 这是非常令人困惑的、因为信标在信标被发布之前不会超过这个点。 在这种情况下、通过 UART 读取回调函数。 更令人困惑的是信标是第一次发生的、即使没有 UART_READ_CALLACK 函数触发一次、即使自程序启动以来、UART_READ_CALLACK 也是完成 Semaphore_POST 的唯一位置。 我使用断点在 Semaphore_Pend 前后检查 semCount 来观察这种现象。

2) 2)     我遇到的另一个问题是、如果我删除断点、它将向我的终端打印几个字符并跳转到 Hwi 异常处理程序。 在这里、它卡在连续环路中。 当然、我没有处理该异常、但为什么会发生这种情况、我无法理解。

void Hwi_exHandler (UINT * exstack、UINT LR)
{
Hwi_module->exACTIVe[0]= true;

/*如果没有插入异常处理程序,请在此处旋转*/
while (Hwi_excHandlerFunc == NULL ){
;
}

Hwi_exHandlerFunc (exstack、LR);
} 

我想我应该附加一个 ROV 的屏幕截图、ROV 在 Hwi 异常处理程序的连续循环中卡住后被捕获、因为它可能很有用。 我对 TI-RTOS 非常陌生、因此仍处于早期阶段。 是否有人能够帮助我解决这两个问题?  如果我可以提供任何其他信息、请告诉我。  提前感谢您。

此致、

Guyan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我发现将 Semaphore_construction (&uart3gSemStruct, 1,&uart3gSemParams)中的第二个参数更改为 Semaphore_construct(&uart3gSemStruct, 0,&uart3gSemParams),使信标计数0开始。
    然而、还有其他问题存在、它将经过信标挂起、而没有信标发布触发和 Hwi 异常。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您也可以附加 UART_Write_callback 函数吗?

    在结构上、0表示信号量的初始计数。 0表示它不可用(在本例中是您想要的)。 当信标用于管理资源(或资源)时、非零值很有用。 例如、在互斥类型用法中、您希望计数为1、因为对 Semaphore_pend 的第一次调用不应阻止。

    这就是为什么要使用回调而不是仅使用默认阻塞模式的原因? 根据您的 UART_READ_CALLACK 函数、您将执行与阻塞模式相同的操作。

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

    您好!

    ROV 快照将非常有用。

    另外、我在一段时间前将 这个示例代码放在一起

    它基于 uartecho

    在 EUSCI_A0上显示输出

    3.使用回调将 EUSCI_A3配置为 UART

    4、添加了信标定义、它正在 UART 写回调中使用。

    我希望这可以帮助我们跟踪你的 Hwi 异常。

     此致、

       David

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

    非常感谢您的回复。 我的 UART_Write_callback 函数目前不包含任何内容。 感谢对信标的解释。

    我决定使用回叫的原因是、我不希望整个系统在等待 UART 输入时暂停。 由于我不熟悉 TI-TROS、我将使用一个与寄存器级别类似的内容来解释我如何理解 UART 回调模式和阻塞模式之间的差异。(这可能是误解)

    据我所知、UART 回调方法与 RXIFG 变为高电平类似、会导致中断、从而使程序跳转到 UCxy 的 ISR。 据我所知、UART_READ_CALLY()函数与 UCxy 的中断服务例程类似、我要在其中设置信号量。 然后、它可以指示 UART 的数据需要读取。

    UART 阻塞方法、因为 I understool 类似于轮询。 例如 while (!(UCxyIFG & UCRXIFG));

    在阅读您的回答后、我觉得我不正确。 那么、为了进行确认、UART 阻塞模式不会通过卡在等待循环中直到接收到字符来停止程序中的所有其他操作?

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

    非常感谢您的示例。 了解回电如何满足这一要求非常有帮助。 我将 UART 路由到我有 FTDI USB 串行端口、并使用断点、逐步了解情况。 我一直在寻找这样的示例! 我的带回调的 UART 读取现在工作。 谢谢!

    另一个注意事项是、在使用另一个 TI-RTOS 项目时、我发现当我将一些字符串移出线程时、Hwi 异常消失了。 我认为任务的堆栈大小不够。 那么、现在我已经放置了更多的堆栈大小。

    今天、在阅读了大家的两个回答后、我继续使用 UART 解释器、并决定使用阻塞模式、因为根据我的 Todd 建议、阻塞模式的功能应该与我尝试通过 UART 回调模式执行的操作相同。 它还将消除信标使用和回调函数的额外步骤。

    再次感谢大家!

    此致、
    Guyan