Handle BLE user event on FreeRTOS - bluetooth-lowenergy

I'm running FreeRTOS on a ST Nucleo board with the BlueNRG shield.
The initialization of the BLE stack works, the devices advertises itself and I can establish a connection. My problem is that as soon as user event arrives (e.g. service discovery) the program ends up in the hardfault_handler().
I have 3 tasks running on my RTOS of which one should be a dedicated BLE task handling the user events.
void hci_user_evt_proc(void)
{
tHciDataPacket * hciReadPacket = NULL;
/* process any pending events read */
while (list_is_empty(&hciReadPktRxQueue) == FALSE)
{
list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
if (hciContext.UserEvtRx != NULL)
{
hciContext.UserEvtRx(hciReadPacket->dataBuff);
}
list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
}
}
This is taken from an ST example code.
The whole thing works if I either
Just run this one task or
Give the BLE task a higher priority
Both solutions have the same outcome - and don't have a multitasking system anymore.
I don't know if a have to adapt the example code to run in a multitask system or if I have to run the BLE process interrupt driven, but if yes, how would I do that and how can I elaborate the root cause of a hardfault?
What I tried is to surround my user_evt_handler with a vTaskSuspendAll/xTaskResumeAll but that didn't change anything.

Issue solved by giving the BLE task more stack size

Related

Proper way of notifying the application that DPDK received messages

currently, I'am using dpdk by sending and receiving the packets in to the rte-rings. I'am having difficulty of finding the proper way of to notify the application that the DPDK received incoming messages.
In order to check the whether the rte_ring has received the data or not, I run a busy loop on the rte_ring.
here is the example below
while (1) {
if (rte_ring_dequeue(rx_ring, &_msg) < 0) {
usleep(5);
} else {
recv_msg = (char *) _msg;
if (chara_debug) printf("[%d] Server merge data::[%.24s...]__length::[%ld]\n", batched_packets, recv_msg, strlen(recv_msg));
collect_packets++;
if (collect_packets > MERGE_PACKETS) break;
}
}
However, my fellow developers say that this is not a efficient way nor the proper way of checking received messages. Busy polling should be only done in the DPDK API and not in the application.
Is there a way for DPDK to send a signal to the application so that the application can only check the rte_ring only when there is a received message?
Well, direct answer is to use DPDK event library: http://doc.dpdk.org/guides/prog_guide/eventdev.html
But it is not that smooth. Unless you have a hardware which directly supports the event model, you still need at least one RX core to poll (i.e. do the busy loop) as shown on this picture:
http://doc.dpdk.org/guides/prog_guide/eventdev.html#api-walk-through

Qt: Detect a QTcpSocket disconnection in a console app when the user closes it

My question title should be enough. I already tried (without success):
Using a C-style destructor in a function: __attribute__((destructor)):
void sendToServerAtExit() __attribute__((destructor)) {
mySocket->write("$%BYE_CODE%$");
}
The application destructor is called, but the socket is already disconnected and I can't write to the server.
Using the standard C function atexit(), but the TCP connection is already lost so I can't send anything to the server.
atexit(sendToServerAtExit); // is the same function of point 1
The solution I found is check every second if all connected sockets are still connected, but I don't want to do so inefficient thing. It's only a temporary solution. Also, I want that others apps (even web ones) can join the chat room of my console app, and I don't want to request data every second.
What should I do?
Handle the below signal (QTcpSocket is inherited from QAbstractSocket)
void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)
Inside the slot called, check if socketState is QAbstractSocket::ClosingState.
QAbstractSocket::ClosingState indicates the socket is about to close.
http://doc.qt.io/qt-5/qabstractsocket.html#SocketState-enum
You can connect a slot to the disconnect signal.
connect(m_socket, &QTcpSocket::disconnected, this, &Class::clientDisconnected);
Check the documentation.
You can also know which user has been disconnected using a slot like this:
void Class::clientDisconnected
{
QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
if(client)
{
// Do something
client->deleteLater();
}
else
{
// Handle error
}
}
This method is usefull if you have a connections pool. You can use it as well if you have a single connection, but do not forget nullptr after client->deleteLater().
If I understand you question correctly, you want to send data over TCP to notify the remote computer that you are closing the socket.
Technically this can be done in Qt by listenning to the QIODevice::aboutToClose() or QAbstractSocket::stateChanged() signals.
However, if you graciously exit your program and close the QTcpSocket by sending a FIN packet to the remote computer. This means that on the remote computer,
the running program will be notified that the TCP connection finished. For instance, if the remote program is also using QTcpSocket, the QAbstractSocket::disconnected()
signal will be emitted.
The real issues arise when one of the program does not graciously exit (crash, hardware issue, cable unplugged, etc.). In this case, the TCP FIN packet will
not be sent and the remote computer will never get notified that the other side of the TCP connection is disconnected. The TCP connection will just time-out after a few minutes.
However, in this case you cannot send your final piece of data to the server either.
In the end the only solution is to send a "I am here" packet every now and then. Even though you claim it is ineficient, it is a widely used technique and it also has the advantage that it works.

Unable to send data using QSerialPort

I am trying to write a QT application that will be able to communicate with my embedded system using serial port. For now I am testing the config with Null Modem emulator as I don't have the embedded system ready yet.
The emulator works fine as I have tested it in other software like Terraterm, RealTerm or Putty. My problem is that my example code doesn't work - it doesn't send the string to another com port.
This is my code:
void CSettingsDialog::on_pbSerialCheck_clicked()
{
QSerialPort serial;
serial.setPortName(ui->cbSerialPort->currentText());
if (!serial.open(QIODevice::ReadWrite))
{
QMessageBox::warning(this, tr("Serial port"),
tr("Serial port %1 is busy!")
.arg(ui->cbSerialPort->currentText()));
}
else
{
serial.setBaudRate(QSerialPort::Baud115200);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
serial.write("TEST\n");
serial.close();
}
}
I am certain that I have everything set correctly looking at the QT examples.
I am certain that I have everything set correctly looking at the QT
examples. I would aprichiate all help!
When reading flush documentation, it seems that calling "write" buffers, with writes possible finishing asynchronously.
Also see "Certain subclasses of...are asynchronous", with comments on waitForBytesWritten

Detecting Serial port disconnect in Chrome App

I'm using Chrome's Serial Port API (http://developer.chrome.com/apps/serial.html) in a Web App.
The problem I have is that pretty much all serial ports now are implemented via USB devices. If the user disconnects (or just resets) the USB device, I don't have any way of knowing. Not only that, because the app hasn't disconnected in Chrome (because it didn't know), if the USB device is plugged back in, bad things happen (on Linux it just gets a different name, but in Windows it is not usable at all).
The best I can manage is:
var checkConnection = function() {
chrome.serial.getControlSignals(connectionInfo.connectionId, function (sigs) {
var connected = "cts" in sigs;
if (!connected) console.log("Disconnected");
});
} // called every second or so
Is there a better way? a callback would be ideal!
It looks it should be safe on all platforms to assume that getting a read callback with 0 bytes means EOF, which in turn is a good indication that the device has been disconnected.
chrome.serial.read(connectionId, function(readInfo) {
if (readInfo.bytesRead === 0) {
/// Safely assume the device is gone. Clean up.
chrome.serial.close(connectionId);
/// ...
}
});
The serial API will be improving over the next few weeks (in Canary at least) to add stability improvements, an event-based read API, and the ability to more clearly detect timeouts and error conditions (like a disconnected device). You can track that progress at http://crbug.com/307184.

Re-opening Closed Serial Port

i have an application that detects a USB 3G Dongle that will be used for sending SMS. My application queries the Dongle via AT Commands to determine if it is the RIGHT dongle, this means that that certain dongle can only be used in my application (even if the Dongle is of the same model). Sending and receiving is fine, no problems or whatsoever. If the 3G Dongle is removed from the USB port, the system detects this and executes the proper procedures.
Here's my problem. When the 3G Dongle is re-inserted, say on the same port (COM5), my application detects this and executes some AT Command to determine that the re-inserted dongle is the RIGHT dongle. But an error occurs stating:
THE RESOURCE IS IN USE
The application must be terminated or closed to be able to use the same port (say COM5). Then I encountered an application, almost with the same function, but is able to use the dongle when re-inserted.
BTW, my dongle is ZTE MF190, and the application I saw is from Huawei. I am using C#. Is there any work around on this? or better, is there a better logic on this? say using a service, etc..
EDIT:
every query done to the Dongle is done in a separate thread so as to be able to use my application while sending and receiving..
Thanks!
I too had a similar issue with the windows serial port component. There appears to be bugs in the C# code.
Long story short, I managed to get around this by closing the port in a background thread.
Here is my code, note that you may need to modify to fit your application:
private bool ClosePort()
{
_Closing = true;
_SerialPort.DiscardInBuffer();
_SerialPort.DiscardOutBuffer();
if (!_SerialPort.IsOpen) return true;
//We run this in a new thread to avoid issue when opening and closing
//The .NET serial port sucks apparently - and has issues such as hanging and random exceptions
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(DoClosePort));
t.Start();
//here we wait until is **SHOULD*** be closed - note the better way is to fire an internal event when its finished
//We may need to tinker with this wait time
System.Threading.Thread.Sleep(500);
return _SerialPort.IsOpen;
}
private void DoClosePort()
{
try
{
//System.Threading.Thread.Sleep(500);
_SerialPort.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error closing " + _SerialPort.PortName + ". Error Message: " + ex.Message + "\r\n");
}
}
Note that if you try sending/receiving while you are closing, check the _Closing class variable before you attempt the send.
Hope this helps anyone.

Resources