您好!
我的客户使用 STM32 + CC2564MODN (SPP 配置文件)
应用程序工作正常-与 PC 的连接和数据传输正常。
应用逻辑需要关闭 CC2564MODN 并在 somw 时间内重新启动它(当下一个数据准备就绪时)。
问题:当应用程序尝试重新启动模块时、BT 堆栈挂起。
问题描述和已完成的操作:
第一个 BT 堆栈启动包括:
startBtWork(); (它启动 InitializeApplication() 和 OpenStack (HCI_DriverInformation)。
在 Later 函数中:
BTPS_Init ; (创建互斥内核)
BSC_Initialize (HCI_DriverInformation、0); (创建额外的4个互斥量、3个任务、 4个事件对象和1个二进制信标)
通过以下方式关闭堆栈:
CloseCurrentServer(); //设置 ServerPortID = 0
HCITR_COMClose (1);
CloseStack();
//在 CloseStack()内部:
- bsc_Shutdown ();//在执行期间,我在调试器中看到:删除2个互斥量和1个事件(在堆栈中使用)
- BTPS_DeInit();// 我尝试清理代码中的任务,但它没有帮助。 它目前是空函数
TurnOff3_1B (); //电源关闭(关闭3.1V; 1.8V 永久打开)
我看到关闭开关堆栈不会删除:
-在模块初始化期间创建的 tasksm (BT1任务的摘录 -在 UART 中使用)
-互斥信标
-事件对象
我尝试手动删除上述对象、但重复的堆栈重启无论如何都失败。 在 BSC_Initialize 中发生挂起、 在这里调用我的函数来打开模块电源、然后我只暂停 vTaskDelay (100 / portTIK_PERIOD_MS);Programm 无法从 vTaskDelay 代码返回。
//====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
/*以下函数负责关闭 SS1 //
//*蓝牙协议栈。 此函数要求使用 //
////*蓝牙协议栈之前已通过*/
//* Openstack()函数初始化。 此函数在*/
/*成功执行时返回0、在所有错误上返回负值。 //
int CloseStack (void)
{// From InitializeApplication() and Openstack()
int ret_val = 0;
/*首先检查堆栈是否已打开。 //
if (BluetoothStackID)
{
/*只需关闭堆栈 *
BSC_Shutdown (BluetoothStackID);
vTaskDelay (1000 / portTIK_PERIOD_MS);//测试
/*免费 BTPSKRNL 分配的内存。 *
BTPS_DeInit();
vTaskDelay (1000 / portTIK_PERIOD_MS);//测试
Display (("Stack Shutdown.\r\n"));//因为 MessageOutputCallback = NULL --它不起作用
/*标记堆栈不再初始化。 *
BluetoothStackID = 0;
/*向呼叫者标记成功。 *
RET_val = 0;
//saveParamDataToFlash();// 2016 08
}
否则
{
/*有效的堆栈 ID 不存在,请通知用户。 *
RET_val = unaged_TO_initialize_stack;
}
ret_val;
}//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
/*以下函数负责打开 HCI
Bluetopia 将用于发送和接收*/
/* COM (串行)数据的*//*传输层。
此函数必须按*//*顺序成功发布、Bluetopia 才能正常工作。 此函数接受
将用于*//*
以打开端口的 HCI COM 传输 COM 信息作为其*/*参数。 最后两个参数指定了 HCI 在
从 UART 接收数据时,分别调用*//*传输数据回调和回调参数。 成功调用
此函数的*//*将返回非零的正值,*/
*指定与其余函数一起使用的 HCITransportID 本
模块中的*//*传输功能。 此函数返回 用于
表示错误的*//*负返回值。 //
int BTPSAPI HCITR_COMOpen (HCI_COMMDriverInformation_t * COMMDriverInformation、HCITR_COMDataCallback_t COMDataCallback、unsigned long CallbackParameter)
{
int ret_val;
/*首先,确保端口尚未打开,并确保*/*
指定了有效的 COMM 驱动程序信息。 //
if ((!HCITransportOpen)&&(COMMDriverInformation)&&(COMDataCallback)
){
/*初始化成功的返回值。 *
RET_val = transport ID;
/*标志 HCI 传输已打开。 *
HCITransportOpen = 1;
/*初始化上下文结构。 *
clrUartContext (false);// BTPS_MemInitialize (&UartContext、0、sizeof (UartContext_t));
UartContext.COMDataCallbackFunction = COMDataCallback;
UartContext.COMDataCallbackParameter = CallbackParameter;
UartContext.TxBytesFree = output_buffer_size;
UartContext.RxBytesFree = input_buffer_size;
UartContext.SuspendState = hssNormal;
/*创建用于指示数据已到达的事件。 *
vSemaphoreCreateBinary (UartContext.DataReceivedEvent);
if (UartContext.DataReceivedEvent)
{
/*确保事件处于复位状态。 *
xSemaphoreTake (UartContext.DataReceivedEvent、1);
/*创建一个将处理接收到的数据的线程。 *
UartContext.ReceiveThreadHandle = BTPS_CreateThread (RxThread、1600、NULL);
if (!UartContext.ReceiveThreadHandle)
{
/*无法启动线程,请删除信标。 *
vQueueDelete (UartContext.DataReceivedEvent);
RET_val = HCITR_ERROR_ENCOLOD_TO_OPEN_transport;
HCITransportOpen = 0;
}
}
其他
{
RET_val = HCITR_ERROR_ENCOLOD_TO_OPEN_transport;
HCITransportOpen = 0;
}
/*如果没有错误,则继续设置端口。 *
if (ret_val!= HCITR_ERROR_ENCOLOG_TO_OPEN_transport)
{
btIsReset ();// nSHUTD_Pin = 0
turnon_BT ();// MX_LPUART1_UART_Init (vender_default_BAUDRATE)
if (statusWorkCode!= SuccessRezult)
{
RET_val = HCITR_ERROR_ENCOLOD_TO_OPEN_transport;
waitStopReceiveTask();
}
}
其他
{
waitStopReceiveTask();
}
}
否则
{
RET_val = HCITR_ERROR_ENCOLOD_TO_OPEN_transport;
}
ret_val;
}//============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
/*以下函数负责关闭通过
成功调用打开的特定 HCI*/*传输层 //
//* HCITR_COMOpen()函数(由第一个参数指定)。 //
//* Bluetopia 在任何时候都调用此函数 //
//* Bluetopia is closed,or an error Occurs during initialization and */
/* the driver has been opened (仅在这种情况下)。 一旦此*/
/*功能完成,关闭的传输层将不再处理*/
/*接收的数据,直到传输层结束 通过
调用 HCITR_COMOpen()函数可重新打开*///*。 */
**注意*此函数*必须*关闭指定的 COM 端口。 此*/
* 然后、模块将调用注册的 COM 数据回调*/
/* 用0作为数据长度、用 NULL 作为*/
* 数据指针。 这将向 HCI 驱动程序表明是*/*
该模块完成了端口和 */
* 信息(更重要的是),没有进一步的数据*//*
将发出回调。 换言之、最后一个*/
/* 从此模块发出的数据回调*必须*为*/
/* 为数据指定零和 NULL 的数据回调 */
* 长度和数据缓冲器。 */
void BTPSAPI HCITR_COMClose (unsigned int HCITransportID)
{
HCITR_COMDataCallback_t COMDataCallback;
HAL_NVIC_DisableIRQ (HCITR_UART_IRQ);// LPUART1_IRQn
/*似乎有效,继续并关闭端口。 *
_HAL_UART_DISABLE_IT (&hlpuart1、UART_IT_RXNE);
_HAL_UART_DISABLE_IT (&hlpuart1、UART_IT_TXE);
/*将蓝牙设备置于重置状态。 *
btIsReset();
//添加 UART 可能已关闭
/*检查以确保指定的运输 ID 有效。 *
if ((HCITransportID =transport_ID)&&(HCITransportOpen))
{
/*标志 HCI 传输不再打开。 *
HCITransportOpen = 0;// while (HCITransportOpen) UartContext.ReceiveThreadHandle = NULL;
waitStopReceiveTask();
/*注意回叫信息。 *
COMDataCallback = UartContext.COMDataCallbackFunction;
UartContext.COMDataCallbackFunction =空;
/*全部完成后,执行回调以让上层知道*/
/*此模块将不再发出数据回调,并且是*/
/*已完全清理。 *
if (COMDataCallback)
(* COMDataCallback)(HCITransportID、0、NULL、UartContext.COMDataCallbackParameter);
UartContext.COMDataCallbackParameter = 0;
}
HAL_UART_DeInit (&hlpuart1);
}