Thread 中讨论的其他器件:SYSBIOS、 CC2650、 SysConfig、 SIMPLELINK-CC13XX-CC26XX-SDK
您好、Ryan、
很抱歉,我在7月29日刚刚失踪,但我发生了一个事故,因为我已经做了彻底的髋关节替换和膝关节手术。
我现在可以在计算机上工作几个小时、我想重新处理这个未解决的问题。
谢谢、
戴尔
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.
您好、Ryan、
很抱歉,我在7月29日刚刚失踪,但我发生了一个事故,因为我已经做了彻底的髋关节替换和膝关节手术。
我现在可以在计算机上工作几个小时、我想重新处理这个未解决的问题。
谢谢、
戴尔
Ryan、
1.上一个主题中的最后一篇文章问我 :“在 UARTCC26XX.C 中,您是否在不包含'threadSafeStdbyDisRelease (&uartRxPowerConstraint);'的情况下获得了相同的行为?”
是的,如果没有 'hreadSafeStdbyDisRelease(&uartRxPowerConstraint),我将获得与 UARTCC26XX_Close()最后一行相同的意外行为。
这种意外行为是在调用 UARTCC26XX_close()后不会清除我的 uartHandle。
2.您还询问了"您从何种上下文调用 UART_Close?"
在 ProjectZero_taskFxn 的主应用程序循环中、我调用一个函数以进入睡眠模式、并在其中使用以下代码:
if (uartHandle != NULL) {
doneUARTreads = 1;
UART_readCancel(uartHandle);
UART_writeCancel(uartHandle);
UART_close(uartHandle);
}
你还说"这个 API 调用[Hwi/Swi/时钟]_strapt、此函数不应 从 Hwi/Swi 线程本身使用、而只能从任务或主函数中使用。"
我不理解这一说法。 当我调用 UARTCC26XX_Close()时,如何使用该语句来帮助我更改代码以清除 uartHandle。?
4.您还说"请参阅 ti.sysbios.hal.hwi 模块(以及其他模块)构成 TI-RTOS 驱动程序配置 API (CDOC)"
这是我的脑海中最重要的,因为我不理解上面的#3。。。。
谢谢、
戴尔
老实说、我不记得我最近的回复是怎么做的。 我建议我们暂时不要这样做。
您能否在 UART_open 以及 UART_close 之前/之后从存储器浏览器中提供 UARTCC26XX_Object 的内容、以便我们验证它是否已返回其默认状态? UART_Close 不应破坏 uartHandle、但其状态应指示它是否准备好再次使用 UART_open 进行调用。
此致、
Ryan
我无法在 CSS 版本7.0.0.00042的内存浏览器中搜索 UARTCC26XX_Object。 我只能直接搜索地址。
但是、我在 UARTCC26XX_open()末尾放置了一个断点、并且能够在 "Variables"选项卡上获取 UARTCC26XX_Object 的状态、如下所示:

在 UARTCC26XX_CLOC()进入睡眠模式期间:
编辑:我注意到下图中不现实的波特率 、然后决定在同一个断点处检查 "Expressions"选项卡上的 UART_params 结构中的波特率值是多少、 当时为19200、因此我假设 294592的 UARTCC26XX_Object 波特率参数报告有误、因为就在该断点之前、19200处有 UART 通信...

在 UARTCC26XX_CLOC()之后、在进入睡眠模式代码期间:

这一点非常有趣、因为我想您说我的意外行为实际上是 UART 驱动程序的预期行为。 换言之,我认为你说的是,在第一个 uartOpen()之后,uartHandle 将保持不变,永远不会被清除。
这意味着我必须找到另一个条件、我可以使用它来确定 UART 是否在任何时候都实际打开、而不是我一直使用的条件、即"if (uartHandle!= NULL) {"。 这与 I2C 驱动程序不一致、后者在 I2C_Close()之后确实清除了 i2cHandle。 我希望 UART 驱动程序在其句柄的使用寿命方面与 I2C 驱动程序的作用相同。 也许我 应该访问 条件语句的 UARTCC26XX_Object 的'open'参数...
戴尔
第二个映像"在 进入睡眠代码期间 UARTCC26XX_CLOSE ()之前"在波特率之外为 false。 可以观察到 hwAttrs 和对象地址与其他两个地址相比发生了变化,因此对象中显示的值不正确。
UART_Close 之后、uartHandle 不应为 NULL。 "UARTCC26XX_CLOSE" 图像显示 、对象->已打开为 false、因此所有其他对象应在下次调用 UART_OPEN 时复位。 如果 UART 已打开 、则 UARTCC26XX_OPEN 将返回 NULL。
此致、
Ryan
谢谢,在我决定是否真的需要在代码中使用 object>opened 参数后,我将使用该函数。
事实证明、我错误地使用 uartHandle 来确定 UART 是否已打开并准备好发送和接收数据、这是唤醒后 HWI 异常的原因。
唤醒后,我调用了一个重新打开 UART 的函数,因为我假设它在我进入睡眠状态时使用 UART_CLOSE ()函数后已关闭。
以下是该函数:
void uartOpenAndRead(void)
{
uartParams.readMode = UART_MODE_CALLBACK;
uartParams.readCallback = uartRXcallback;
uartParams.writeMode= UART_MODE_BLOCKING;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.baudRate = 19200;
uartParams.dataLength = UART_LEN_8;
uartParams.parityType = UART_PAR_NONE;
uartParams.stopBits = UART_STOP_ONE;
if (uartHandle != NULL) {
UART_readCancel(uartHandle);
UART_close(uartHandle);
}
uartHandle = UART_open(Board_UART0, &uartParams);
if (uartHandle != NULL) {
UART_read(uartHandle, &uartrxByte, 1); //turn on continuous 1 byte reads
}
}
第一条'if'语句是导致 HWI 异常的原因(我认为这是在唤醒后第一次尝试使用 Tx 线路)、因为输入了'if' 、导致再次调用 UART_Close (在我们进入睡眠模式之前已经关闭了)。
一旦我删除 了"if (uartHandle!= NULL) {"语句、在我们唤醒且应用程序主循环正常后、没有 HWI 异常。
我当前的问题是、我似乎无法使 UART Rx 和 Tx 线路正常工作。 我确实调用我的 uartOpenAndRead()函数(在唤醒后没有'if'语句,以便再次打开 UART ,这会导致 object>opened 参数再次设置为1) 但我的读取回调函数不响应 Rx 线路上的数据、并且在执行 UART 写入函数时、数据不会发送到 Tx 线路上、这两个函数在我们进入睡眠状态之前都可以正常工作。
我当前的问题是,在 UART_Close()之后再次打开 UART 的正确方法是什么,因为 UART_open()即使将 object>opened 设置为1,也似乎不起作用?
戴尔
感谢 Dale 的更新。 如前所述、请通过*(object)的 Debugger Variables 视图确认后续 UART_open 调用中是否包含正确的 readCallback/writeCallback/readBuf/writeBuf 值。 如果 UART_open 未将所有 uartHandle 参数返回到正确的初始化、则可能需要进一步调试 UART_open。
此致、
Ryan
您可以查看 UARTCC26XX.c、TI-RTOS v2.21.1.8版本如下所示:
UART_Handle UARTCC26XX_open(UART_Handle handle, UART_Params *params)
{
unsigned int key;
/* Use union to save on stack allocation */
union {
Hwi_Params hwiParams;
Swi_Params swiParams;
Semaphore_Params semParams;
Clock_Params clkParams;
} paramsUnion;
UARTCC26XX_Object *object;
UARTCC26XX_HWAttrsV2 const *hwAttrs;
/* Get the pointer to the object and hwAttrs */
object = handle->object;
hwAttrs = handle->hwAttrs;
/* Disable preemption while checking if the UART is open. */
key = Hwi_disable();
/* Check if the UART is open already with the base addr. */
if (object->opened == true) {
Hwi_restore(key);
Log_warning1("UART:(%p) already in use.", hwAttrs->baseAddr);
return (NULL);
}
object->opened = true;
Hwi_restore(key);
/* Check that a callback is set */
Assert_isTrue((params->readMode != UART_MODE_CALLBACK) ||
(params->readCallback != NULL), NULL);
Assert_isTrue((params->writeMode != UART_MODE_CALLBACK) ||
(params->writeCallback != NULL), NULL);
/* Initialize the UART object */
object->readMode = params->readMode;
object->writeMode = params->writeMode;
object->readTimeout = params->readTimeout;
object->writeTimeout = params->writeTimeout;
object->readCallback = params->readCallback;
object->writeCallback = params->writeCallback;
object->readReturnMode = params->readReturnMode;
object->readDataMode = params->readDataMode;
object->writeDataMode = params->writeDataMode;
object->baudRate = params->baudRate;
object->dataLength = params->dataLength;
object->stopBits = params->stopBits;
object->parityType = params->parityType;
/* Set UART transaction variables to defaults. */
object->writeBuf = NULL;
object->readBuf = NULL;
object->writeCount = 0;
object->readCount = 0;
object->writeSize = 0;
object->readSize = 0;
object->writeCR = false;
object->readRetPartial = false;
object->readFifoThreshold = UART_TH_FIFO_4_8;
object->writeFifoThreshold = UART_FIFO_TX1_8;
/* Register power dependency - i.e. power up and enable clock for UART. */
Power_setDependency(hwAttrs->powerMngrId);
/* Initialize the UART hardware module */
UARTCC26XX_initHw(handle);
/* Configure IOs, make sure it was successful */
if(!UARTCC26XX_initIO(handle)) {
/* Trying to use UART driver when some other driver or application
* has already allocated these pins, error!
*/
Log_warning0("Could not allocate pins, already in use.");
/* Disable UART */
UARTDisable(hwAttrs->baseAddr);
/* Release power dependency - i.e. potentially power down serial domain. */
Power_releaseDependency(hwAttrs->powerMngrId);
/* Mark the module as available */
key = Hwi_disable();
object->opened = false;
Hwi_restore(key);
/* Signal back to application that UART driver was not succesfully opened */
return (NULL);
}
/* Create Hwi object for this UART peripheral. */
Hwi_Params_init(&(paramsUnion.hwiParams));
paramsUnion.hwiParams.arg = (UArg)handle;
paramsUnion.hwiParams.priority = hwAttrs->intPriority;
Hwi_construct(&(object->hwi), hwAttrs->intNum, UARTCC26XX_hwiIntFxn,
&(paramsUnion.hwiParams), NULL);
/* Create Swi object for this UART peripheral */
Swi_Params_init(&(paramsUnion.swiParams));
paramsUnion.swiParams.arg0 = (UArg)handle;
paramsUnion.swiParams.priority = hwAttrs->swiPriority;
Swi_construct(&(object->swi), UARTCC26XX_swiIntFxn, &(paramsUnion.swiParams), NULL);
/* Initialize semaphore */
Semaphore_Params_init(&(paramsUnion.semParams));
paramsUnion.semParams.mode = Semaphore_Mode_BINARY;
/* If write mode is blocking create a semaphore and set callback. */
if (object->writeMode == UART_MODE_BLOCKING) {
Semaphore_construct(&(object->writeSem), 0, &(paramsUnion.semParams));
object->writeCallback = &writeSemCallback;
}
/* If read mode is blocking create a semaphore and set callback. */
if (object->readMode == UART_MODE_BLOCKING) {
Semaphore_construct(&(object->readSem), 0, &(paramsUnion.semParams));
object->readCallback = &readSemCallback;
}
/* Create clock object to be used for write FIFO empty callback */
Clock_Params_init(¶msUnion.clkParams);
paramsUnion.clkParams.period = 0;
paramsUnion.clkParams.startFlag = false;
paramsUnion.clkParams.arg = (UArg) handle;
Clock_construct(&(object->txFifoEmptyClk),
(Clock_FuncPtr) &writeFinishedDoCallback,
10, &(paramsUnion.clkParams));
/* Create circular buffer object to be used for read buffering */
RingBuf_construct(&object->ringBuffer, hwAttrs->ringBufPtr, hwAttrs->ringBufSize);
/* Register notification function */
Power_registerNotify(&object->uartPostObj, PowerCC26XX_AWAKE_STANDBY, (Fxn)uartPostNotify, (uint32_t)handle);
/* UART opened successfully */
Log_print1(Diags_USER1, "UART:(%p) opened", hwAttrs->baseAddr);
/* Return the handle */
return (handle);
}
TI-RTOS v2.21.0.6 (在 dev.ti.com 上为 CC2650提供)发行说明 介绍了"CCS 6.1.3或更高版本"的相关性、因此它们也应该能够在 CCS v7上工作。 这是 TI-RTOS 产品发布下载页面。
此致、
Ryan
好的、将会执行并报告。
但是,我想知道为什么在 UART_open()期间更改 uartParams,因为我在调用 UART_open 之前重置所有 uartParams,正如您在这里看到的:
void uartOpenAndRead(void)
{
uartParams.readMode = UART_MODE_CALLBACK;
uartParams.readCallback = uartRXcallback;
uartParams.writeMode= UART_MODE_BLOCKING;
uartParams.readEcho = UART_ECHO_OFF;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.baudRate = 19200;
uartParams.dataLength = UART_LEN_8;
uartParams.parityType = UART_PAR_NONE;
uartParams.stopBits = UART_STOP_ONE;
uartHandle = UART_open(Board_UART0, &uartParams);
UART_read(uartHandle, &uartrxByte, 1); //turn on continuous 1 byte reads
}
这些更改是否对您有意义、还是 UART_Params 参数与我的 uartParams 不同?
我将 UARTCC26XX_OPEN 的 TI-RTOS v2.21.0.6与 UARTCC26XX_OPEN 的 TI-RTOS v2.21.1.8进行了比较、 只有2个差异。
1.您的 hwAttrs 定义 为 UARTCC26XX_HWAttrsV2、而我的定义为 UARTCC26XX_HWAttrsV1。
2.你的在行尾附近有一条额外的线(你上面关于 RingBuf_consucrct 的列表中有128条),而我没有那条线。
那么、我认为这不会导致 我们唤醒后 UART_OPEN 出现 UART_Params 错误、会吗?
此外、我刚刚在第一次 UART_open 后通过 man.c 启动代码从完全重启检查了该对象。
您可以在此处看到、它们与 UART_Close 之后调用的 UART_open 相同的错误值(如上图所示):

编辑:在这第一个 UART_open 之后、UART Tx 和 Rx 线路都工作。 在睡觉之前、我有很多通信都通过这两种方式进行、但在醒来后没有通信。
您是否尝试重复我的问题?
在 UART_OPEN 之后、您的参数值是否与像这样的 uartParams 不同?
谢谢、
戴尔
否
但是、我现在已经解决了整个问题...
我最近重新阅读了我有关该项目的所有注释(不一定只放置在代码注释中)、我发现多年来、我在从应用程序主循环中启动某些代码时遇到了许多问题。 对于是否可以从应用程序主循环调用 UART_open()问题,甚至有一条注释。
在使用 UART 打开/关闭的这一轮意外行为中、第一个 UART_open 是在应用程序主循环之前完成的、但 UART_close 是由应用程序主循环'if'语句发起的、该语句每2秒查看一次'WAKEUP 引脚'(IOID_14)上的电压。 如果电压低、则执行 gotosleep 代码。 调用 UART_OPEN 的唤醒代码通常由 IOID_14上的反跳上升沿触发器执行、该触发器将此唤醒代码置于应用程序主循环之外。
昨天、我花时间将 IOID_14上的去抖中断代码更改为 POS 和 NEG 边沿触发、然后确保所有 UART_OPEN 和 UART_CLOSE 调用仅在中断代码中的应用程序主循环之外。 UART 引脚在唤醒后突然开始工作:)
另请注意、通过此更改、我可以使用未更改的 UART 驱动程序!
最后、为了在使用 UART 驱动程序时获得<10ua 的睡眠电流、我必须在执行 UART_CLOSE 函数后更改 gotosleep 代码中 UART Tx 和 Rx 引脚的引脚状态、并在 UART_OPEN 之前在唤醒代码中恢复它们的引脚状态。
总之、这就是解决方案:
PIN_State txsleep; PIN_State rxsleep;
PIN_add(&txsleep, Board_UART_TX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MAX | PIN_NOPULL);
PIN_add(&rxsleep, Board_UART_RX | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_OPENDRAIN | PIN_DRVSTR_MAX | PIN_NOPULL);PIN_Status removestatus = PIN_remove(&txsleep, Board_UART_TX); removestatus = PIN_remove(&rxsleep, Board_UART_RX);
这似乎已经解决了这个问题(哈哈,但我以前说过)
如果我不在一周内报告其他的 gremlins 出现了,那么我认为这个话题最终可以结束...
Ryan、感谢您一如既往的帮助和指导、
戴尔
您好、Dave、
感谢您对解决方案路径的详细更新、我希望此修复程序会持续存在、其他人可以将其用作参考
您好 Frederic、
此问题的一个复杂之处是、它涉及不支持 SimpleLink SDK 或 SysConfig 的较旧器件。 如果您发现 SIMPLELINK-CC13XX-CC26XX-SDK 存在任何功耗问题(根据帖子历史记录进行猜测)、请创建新的 E2E 帖子、TI 工程师将帮助您解决该问题。
此致、
Ryan