大家好、
环境: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