Now we have a simple Python loopback test on the PC, lets tackle the microcontroller next.
The aim here is to get some code running in the microcontroller which will decode COBS frames from the PC,
verify the CRC, then send the same message back. We can then use the Python loopback test (in previous post) to check the microcontroller code.
I am using STMCube + free Keil for STM32L053, source code attached.
UART data from PC is received by DMA directly into a circular RAM buffer.
The background code polls the circular buffer for new bytes and pushes them through the COBS decoder.
When a complete frame has been received, the message CRC is checked.
If the CRC is OK, the message data is copied out and then COBS encoded and sent back to the PC.
The bulk of the code is in msgrx.c and msgtx.c
It should be fairly easy to port MCU of your choice.
Note about RAM Buffer Requirements
Receiving and decoding COBS is quite simple. You just need a RAM buffer big enough to store the decoded message (+CRC bytes).
Transmitting COBS is a little more tricky because you need to replace zero bytes with the distance to the next zero byte.
If the distance is more than 254 bytes, insert 0xFF, meaning the next COBS control byte is 255 bytes ahead.
I suppose there are three ways to handle this in RAM;
1/ Simplest way - have a buffer large enough to store the encoded message. Populate it and send with DMA or interrupt. For larger messages 4kB,8kB... maybe this gets too RAM hungry.
2/ Use a ringbuffer of at least 256 bytes. Populate the buffer with a bit of the message, send it, then continue encoding next bit of message etc. until whole message has been sent.
3/ Minimal RAM method would use more CPU time. Scan forward in the message to find the first zero, thats tells you the first COBS byte and then send the data up to that first zero. Then scan forward for next zero etc.
Edit:
2/ To save RAM, the message could be COBS encoded in-place, in it's own buffer. If the message started, say, 20 bytes into the buffer, the encoded frame could be built starting at the beginning of the buffer, then overwriting the message as you go.
Might be an interesting exercise to implement a minimal RAM COBS transmitter, hmm.