STM32 , main loop does fire if receive data quickly using DMA - dma

I am using DMA in circular mode with STM32 sim800c module. i can send/receive AT commands/response without any issue, but getting issue when i tried to download file using AT command, when start receiving data from UART, DMA RxCpltCallback function getting call very quickly and main loop does not getting fired until all data received. once all data received then loop function get fired and then i check response which contain last chunk of file (64 bytes).
how can i handle this situation?

Increase the size of the DMA buffer. The interrupt will be invoked less frequently. IF your UART speed is really high (about 10Mb) use flow control (CTS/RTS) to control the communication.l

Related

Can I read the bytes transmitted over the CAN-bus on the transmitting side?

Sorry for my question (and my English too). I am a newbie in CAN-bus. I have theoretical question. If I pass any data to one CAN-socket, will I be able to read the same data from the same socket?. After all, the transmitted data appears not only on other nodes of the CAN-bus, but also on the one from which they were transmitted?
Thank you all, I understand. I wrote a small program in C and it turned out that after successfully (it's important!) sending the data to the socket corresponding to the CAN interface, you can immediately read back the same data transmitted to the CAN bus. Perhaps this is how the CAN driver is implemented on Linux (can4linux).
Moreover, in order to be able to read the sent data back, it is important that the CAN interface is not alone in the network, since the transmitter node sets the ACK bit value in the transmitted frame to a recessive state and listens to its own transmission, waiting for all receiving nodes to set the ACK confirmation bit in the dominant state in this transmitted frame, which means that there is no error. When listening to its transmission reveals that the ACK bit is in the dominant state (meaning the transmission was successful), the transmitted frame is placed by the CAN interface driver in the input buffer and can be read back from the our socket.
If the transmission fails (the ACK bit remains in a recessive state), the CAN controller will attempt to transmit the frame in a loop. In the program, this will look like the write function has ended, but when trying to immediately read the data, the program blocks inside the read function if the blocking read mode is set.

transmission reception in one task freertos

I'm working on a freeRTOS project and the SAM4S Xplained Pro.
In a task called every x ms, I would like to:
initiate transmission of datas
extract data from a reception buffer (if an end of frame has been detected)
I'm wandering if there is a way to wake up this task not only periodically, but also when an end of frame has been detected ? And when this task is woken up by this event, only extraction of data would be performed, not the data transmission.
Is the best way consists in creating two tasks ? One for emission, other for reception.
I've not writen any code yet, I'm looking for some advices on how to deal with FreeRTOS and communication issues, as I'm a begginer in it...
You can have the task block on a stream buffer or message buffer (https://www.freertos.org/RTOS-stream-message-buffers.html) and have the interrupt send data to the buffer to unblock the task. Set the read timeout to the period at which you want to transmit, that way the task will unblock when either it is time to transmit again or when data has arrived. You can use https://www.freertos.org/xTaskCheckForTimeOut.html to adjust the timeout to account for any time already spent in the Blocked state (i.e. if the task initially blocks for 100ms, but data arrives after 40ms which causes the task to unblock, then adjust the next block time to 60ms before blocking again to make up the whole 100ms).

Google Nearby connections - Not able to transfer large bytes between 2 devices

When I try to send an object with multiple images(converted to string using Base64) as STREAM type, from the onPayloadTransferUpdate() method, I can see "Failure" result and the devices(tested only when 2 devices are connected) automatically disconnect after that. Is Google Nearby connections not the right option to send large bytes?
Nearby Connections should be able to handle that. There's no explicit size limit on STREAM payloads.
I would suggest chunking the bytes (eg. send a couple KB at a time) and seeing if that helps. You can get into weird situations when you send entire files at once because it loads the bytes into memory twice (once inside your app, and once inside the Nearby process) which can cause out of memory errors. Binder, the interprocess communication layer on Android, also has a limited buffer to send data between processes.
You can also save it as a temporary file and send it as a FILE payload, in which case we will handle the chunking for you.
Disclaimer: I work on Nearby Connections.
1) You don't need to Base64-encode the data for the sake of Nearby Connections -- your STREAM can have raw binary data, and that'll work just fine.
2) How big is this data you're sending, and at what byte offset (you can see this in the PayloadTransferUpdate you get with Status.ERROR) does it fail at? It sounds like your devices are just getting disconnected.
3) What Strategy are you using?
4) If you still have discovery ongoing (i.e. you haven't called stopDiscovery()), try stopping that and then sending your Payload -- discovery is a heavyweight operation that can make it hard to reliably maintain connections between devices for long intervals.

Corebluetooth terminate large data transfer without terminate bluetooth connection

I am developing an app that needs to send large amounts of data between an iPhone and a device (it takes approximately 10 seconds to send the data). But I want to be able to cancel the data communication anytime. I am aware I can simply drop the connection to the device at anytime with
centralManager.cancelPeripheral(peripheral)
but that is not what I am actually looking for, as I want to stop sending data but without terminating the bluetooth connection.
Is there a way to terminate the data transmission without dropping the connection to the device?
the codes of sending data is as follow:
for (var Hex: UInt8 = 0x01; Hex <= 0x14; Hex+=1){
var outbuffer = [UInt8](count: 16, repeatedValue: 0x00)
outbuffer[0] = (0x68)
outbuffer[1] = (Hex)
let data = NSData(bytes: outbuffer, length: 7)
print("data\(data)")
connectingPeripheral.writeValue(data, forCharacteristic: connectingCharacteristicPassword , type: CBCharacteristicWriteType.WithResponse)
}
I figured that I would go ahead and give my input on this. There is no way in CoreBluetooth to stop the transmission of a data packet that has already been written to the output buffer. The reason for why this is the case is simply because it is not needed and it would be a useless functionality. The only reason for why you are having this issue is because your methodology is wrong in my opinion. Do not put everything in a for-loop and push the data all at once. Instead you should implement some sort of flow control mechanism.
In Bluetooth LE there are two main ways of writing data to a peripheral: “Write Commands” and “Write Requests”. You can look at it a bit like the TCP vs UDP protocols. With write commands you are just sending data without knowing whether or not the data was received by the application on the other side of the bluetooth link. With write requests you are sending data and letting the peripheral know that you want to be notified (ack’ed) that the data was in fact received. These two types are in CoreBluetooth called CBCharacteristicWriteWithResponse and CBCharacteristicWriteWithoutResponse. When writing data using the CBCharacteristicWriteWithResponse (like you are doing in your code) you will get a peripheral:didWriteValueForCharacteristic:error: callback which verifies that the data has arrived at the other side. At this point you now have the option to go ahead and send the next packet if you want to, but if you for some reason want to stop sending data, then you can do that as well. Doing it this way you are in control of the whole flow and not just simply pushing everything though a for-loop.
But wait, why would you ever want to use write commands then? Well, since write requests requires the receiver to respond back to the sender it means that data must be sent in both directions. In this case, since the ack is sent by the application layer, you have to wait for the next connection interval before the ack can be sent. This means that when sending large amounts of data you can only send one packet per every two connection intervals which will give you a very poor overall bit rate.
With write commands, since they are not ack’ed, you can send as manny packets as possible within one connection event window. In most cases you should be able to send about 10-20 packets per connection window. But be aware that if you send too many packets then you will fill the outgoing buffer and packets will be lost. So, something that you can try is to directly send 9 packets with the WriteWithoutResponse type, followed by 1 packet of the WriteWithResponse type. After doing this you can wait for the peripheral:didWriteValueForCharacteristic:error: callback in which you can then send 10 more packets the same way. This way you will manage to send 10 packets per every 2 connection intervals while still being able to control the flow better.
You can of course experiment with the ratio a bit, but remember that the buffer is shared between multiple applications on the iOS device so you don’t want to be too close to the limit.

CoreBluetooth CBCharacteristicWriteWithoutResponse: Do requests return instantly or after write?

As the title suggests, I would like to know whether writes to CBPeripherals using CBCharacteristicWriteWithoutResponse return instantly (and do the writing on another thread) or return only when the write is complete.
I would expect the latter, but a colleague of mine has given me reason to believe the former might be true (he's seeing packets not being sent by the iOS device when repeatedly writing).
While Michal is right about the asynchronous nature of write request, I would like to elaborate a bit more on why packets might be not sent during repeatable writes without response.
I have recently experimented with BLE throughput under different conditions and found the following. When you repeatably write data for characteristic supporting write without response, it first gathers in the internal buffer. If you write too fast, this buffer overflows and all the data that doesn't make it into the buffer gets silently discarded. This has nothing to do with synchronous/asynchronous structure of BLE writes, it's just an iOS implementation of the internal buffer. As I figured out, on iPhone 6 running iOS 9 and connected to a single peripheral device, the available buffer size is around 3kb for uni-directional transfer, for bi-directional transfer its size decreases. So to prevent data loss you should ensure the buffer doesn't get overflown. You cannot control it at iOS side, but you can add some integrity checks to the data transfer protocol you use and orchestrate flow control from the peripheral side to e.g. retransmit lost packets.
It's funny, by the way, that in case of writes with responses you can write whatever large data to your characteristics (well, I didn't try too big values, but tried ones exceeding the MTU) and these data will be split into chunks and transmitted to the peer transparently for your code by iOS means without data loss. However, if the data sent to the characteristic will exceed MTU, you won't receive delivery callback.
Bluetooth Low Energy supports writing to the characteristic's value with or without response. In the latter case, the central won't receive any response from the peripheral, so it won't know whether write succeeded. In the former case, the central will be notified and Core Bluetooth will call peripheral:didWriteValueForCharacteristic:error: method from CBPeripheralDelegate; in the latter case, this method won't be called.
The documentation says:
When you call this method to write the value of a characteristic, the
peripheral calls the peripheral:didWriteValueForCharacteristic:error:
method of its delegate object only if you specified the write type as
CBCharacteristicWriteWithResponse.
I understand your colleague may have thought that instead of getting the write result in delegate method, you will get it in the return value. But actually you won't get any write result when using CBCharacteristicWriteWithoutResponse.
So writing to the characteristic's value will always be asynchrounous and the method will return immediately. If it didn't, it could block the main thread. And Core Bluetooth is designed to be used safely in from the main thread if you want to. For example, if you don't specify a dispatch queue for handling CBCentralManager's events, it will handle them in the main queue by default.

Resources