大家好、
环境:simplelink_cc32xx_sdk_6_10_00_05
CCS 版本:12.2.0.00009
在 UART2 的阻塞模式下、名为 UART2_readCancel 的线程、但 B 线程 UART2_Read 和 UART2_readTimeout 都无法接收 UART2_STATUS_ECANCELED。 UART2_readTimeout 可能会接收 UART2_STATUS_ETIMEOUT。
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.
大家好、
环境:simplelink_cc32xx_sdk_6_10_00_05
CCS 版本:12.2.0.00009
在 UART2 的阻塞模式下、名为 UART2_readCancel 的线程、但 B 线程 UART2_Read 和 UART2_readTimeout 都无法接收 UART2_STATUS_ECANCELED。 UART2_readTimeout 可能会接收 UART2_STATUS_ETIMEOUT。
您好!
文档中的定义为:
取消 UART2_READ() 函数调用的函数。
此函 数在 UART2_Mode_callback 中取消异步 UART2_read()操作,或在 UART2_Mode_Blocking 中取消阻止 UART2_read()调用。 在 UART2_Mode_callback 中 ,UART2_readCancel() 使用到目前为止收到的字节数调用已注册的读取回调函数。 应用程序负责检查回调函数中的 count 参数、并处理仅接收字节子集的情况。 回调函数将传递 UART2_STATUS_ECANCELED 的状态。
在 UART2_Mode_Blocking 中 、UART2_Read() 将返回 UART2_STATUS_ECANCELED、bytesRead 参数将设置为迄今为止接收的字节数。
该 API 对 UART2_Mode_NonBlocking 没有影响。
[在] | 手柄 | 由 UART2_open ()返回的 UART2_handle |
因此、对于阻塞模式、您应该得到事件、但我没有自己对其进行测试。
只是为了理解,您在一个任务上以阻塞模式调用 UART2_read(),而在另一个任务上,您取消了读操作,但读操作仍然被阻塞?
Shlomi
您好 、Shlomi、
/* * Copyright (c) 2017-2019, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* * ======== mailbox.c ======== */ /* XDC module Headers */ #include <xdc/std.h> #include <xdc/runtime/System.h> /* BIOS module Headers */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Mailbox.h> #include <ti/sysbios/knl/Clock.h> #include <ti/drivers/Board.h> #include <ti/drivers/Uart2.h> #include "ti_drivers_config.h" #define NUMMSGS 5 #define TASKSTACKSIZE 512 /* * This type is accessed by the application. When changing the data members of * this structure, considerations should be made for padding and data alignment. */ typedef struct MsgObj { Int id; Char val; } MsgObj; /* * Mailbox messages are stored in a queue that requires a header in front of * each message. Mailbox_MbxElem is defined such that the header and its size * are factored into the total data size requirement for a mailbox instance. * Because Mailbox_MbxElem contains Int data types, padding may be added to * this struct depending on the data members defined in MsgObj. */ typedef struct MailboxMsgObj { Mailbox_MbxElem elem; /* Mailbox header */ MsgObj obj; /* Application's mailbox */ } MailboxMsgObj; /* This buffer is not directly accessed by the application */ MailboxMsgObj mailboxBuffer[NUMMSGS]; Mailbox_Struct mbxStruct; Mailbox_Handle mbxHandle; Task_Struct task0Struct, task1Struct; Char task0Stack[TASKSTACKSIZE], task1Stack[TASKSTACKSIZE]; Void readerTask(UArg arg0, UArg arg1); Void writerTask(UArg arg0, UArg arg1); UART2_Handle UartHandle; void uart2_init(void) { UART2_Params uartParams; // 确保调用UART_Params_init之前有调UART_init UART2_Params_init(&uartParams); uartParams.readMode = UART2_Mode_BLOCKING; // 回调模式 uartParams.writeMode = UART2_Mode_BLOCKING; // 写模式使用回调模式 uartParams.readCallback = NULL; // 回调函数 uartParams.writeCallback = NULL; // 回调函数 uartParams.readReturnMode = UART2_ReadReturnMode_FULL; uartParams.baudRate = 2000000; // 波特率 uartParams.dataLength = UART2_DataLen_8; // 数据长度为8位 uartParams.stopBits = UART2_StopBits_1; // 1位停止位 uartParams.parityType = UART2_Parity_NONE; // 奇偶校验位 // 到时候这里使用为UART调试口的初始化 UartHandle = UART2_open(CONFIG_UART2_0, &uartParams); /* remove uart receive from LPDS dependency */ // UART2_control(app_CB.paramUartHandle, UART_CMD_RXDISABLE, NULL); } /* * ======== main ======== */ int main() { Task_Params taskParams; Mailbox_Params mbxParams; /* Call Driver init functions */ Board_init(); uart2_init(); /* Construct read and writer tasks */ Task_Params_init(&taskParams); taskParams.stackSize = TASKSTACKSIZE; taskParams.stack = &task0Stack; Task_construct(&task0Struct, (Task_FuncPtr)writerTask, &taskParams, NULL); taskParams.stack = &task1Stack; Task_construct(&task1Struct, (Task_FuncPtr)readerTask, &taskParams, NULL); /* Construct a Mailbox instance */ Mailbox_Params_init(&mbxParams); mbxParams.buf = (Ptr)mailboxBuffer; mbxParams.bufSize = sizeof(mailboxBuffer); Mailbox_construct(&mbxStruct, sizeof(MsgObj), NUMMSGS, &mbxParams, NULL); mbxHandle = Mailbox_handle(&mbxStruct); BIOS_start(); return(0); } /* * ======== readerTask ======== */ Void readerTask(UArg arg0, UArg arg1) { size_t bytesRead = 0; char input[16]; while (1) { System_printf("UART2_read Enter\n"); System_flush(); int status = UART2_read(UartHandle, &input, 16, &bytesRead); System_printf("UART2_read return:%d,bytesRead:%d\n",status,bytesRead); System_flush(); } System_printf("All messages received. Exiting...\n"); BIOS_exit(0); } /* * ======== writerTask ======== */ Void writerTask(UArg arg0, UArg arg1) { while (1) { System_printf("UART2_readCancel Enter\n"); System_flush(); UART2_readCancel(UartHandle); System_printf("UART2_readCancel return\n"); System_flush(); Task_sleep((10000 / Clock_tickPeriod)*100); } }
上面的代码位于邮箱项目中。 我修改了 mailbox.c 文件 进行测试、结果如下。 UART2_READ 未取消。
测试 结果:
UART2_readCancel 输入
UART2_readCancel 返回
UART2_Read Enter
UART2_readCancel 输入
UART2_readCancel 返回
UART2_readCancel 输入
UART2_readCancel 返回
除非 uartParams.readReturnMode = UART2_ReadReturnMode_Partial、 否则 UART2_Read 返回 UART2_STATUS_SUCCESS、而不是 UART2_STATUS_ECANCELED。
测试 结果:
UART2_readCancel 输入
UART2_readCancel 返回
UART2_Read Enter
UART2_readCancel 输入
UART2_readCancel 返回
UART2_READ 返回:0、字节读取:0
UART2_Read Enter
UART2_readCancel 输入
UART2_readCancel 返回
UART2_READ 返回:0、字节读取:0
最棒的
凯瑟琳
您好!
是的、你是对的。
我深入探讨了 UART2驱动程序的实现、ECANCELED 错误似乎仅在回调模式下传播。
在阻塞模式下、readSem 将被布置、读取将随着接收到的字节计数而中断、直至达到该点(在本例中为0)。
void __attribute__((weak) UART2_readCancel (UART2_Handle handle)
{
UART2_Object *对象= handle->object;
uintptr_t 密钥;
if ((object->state.readMode!= UART2_Mode_Blocking)&&
(object->state.readMode!= UART2_Mode_callback)){
返回;
}
KEY = Hwip_disable();
if (object->readInUse=false){
Hwip_restore (key);
返回;
}
object->readInUse = false;
object->ReadCount = 0;
if (object->state.rxCanceled == false){
object->state.rxCanceled = true;
SemaphoreP_POST (&object->readSem);
if (object->state.readMode = UART2_Mode_callback){
object->readCallback (handle、object->readBuf、object->bytesRead、
object->userArg, UART2_STATUS_ECANCELED);
}
}
Hwip_restore (key);
}
Shlomi