C++ Adventures
I would like to both do more development work at work, and also do some more embedded development, and the answer to both is to get good at C++. To that end, here's my progress today:
github.com/AlDanial/cloc v 1.90 T=0.01 s (712.3 files/s, 77556.5 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C++ 5 168 17 618
C/C++ Header 4 51 21 105
-------------------------------------------------------------------------------
SUM: 9 219 38 723
-------------------------------------------------------------------------------
I mostly spent the time working on a dictionary system (key/value store) [1], but I managed to get some work done on the kimodem [2] too. This dictionary has the constraint that it needs to be able to be file-backed (at least, it needs to be able to be written to a file and read from a file). The ESP platform that I'm using for the modem uses SPIFFS, which I need to spend more time reading up on. Also, because the goal is for it to go on embedded systems, I'd like to have a constrained or fixed size for it so I understand how much memory it'll use.
Anyways, there's three layers this is built on, from bottom to top.
- The arena, which is just a memory buffer with some basic management built in.
- A TLV library built on the arena. Records can store at most 254 bytes (allowing for a trailing NUL byte).
- A dictionary that uses pairs of TLV records to represent a key and value.
It has been a while since I wrote anything much, so I needed to dust off some of those systems programming skills. After a couple of segfaults and some brainos, I got it all working. Here's the dictionary test program running:
kyle@ono-sendai:~/code/klib$ ./dictionary_test
TESTPROG: ./dictionary_test
Arena @ 0x0x7ffeb8693a48
Store is 128 bytes at address 0x0x7ffeb8693a48
Type: mmap/file
test Set foo->quux
Set complete
Dictionary KV pairs
foo->quux
test Set baz->quux
Set complete
Dictionary KV pairs
foo->quux
baz->quux
test Set spam->xyzzx
Set complete
Dictionary KV pairs
foo->quux
baz->quux
spam->xyzzx
test overwriting key
test Set baz->corvid
Set complete
Dictionary KV pairs
foo->quux
spam->xyzzx
baz->corvid
lookup
compare records
add new key to dictionary
test Set quux->xyzzx
Set complete
Dictionary KV pairs
foo->quux
spam->xyzzx
baz->corvid
quux->xyzzx
OK
Dictionary KV pairs
(NONE)
It needed a few minor tweaks to get it running on my ESP32 board (a MicroMod board [3] and carrier [4] from Sparkfun). Right now, the WiFi system is crashing, so that needs some investigation tomorrow.
Here's a few of the things I learned or worked through:
- There's no guarantee that values will be set to 0. This was working on my Linux build, but completely broke on Windows. Mea culpa for using Windows, but it was a useful reminder.
- I messed up my pointer math a few times.
- The longest bug to debug (about 15 minutes) was an endless loop when deleting a record. Instead of tracking my progress in the arena, I kept trying to search from the beginning. I thought it was a memory corruption thing, but it turns out it was just changing a call from (eliding the error checking and whatnot):
cursor = FindTag(arena, NULL, record);
to
cursor = FindTag(arena, cursor, record);
The cursor variable controls how the library searches for things. If it's NULL, it searches from the beginning.
- I was spoiled by having gdb; on the ESP32, I don't. So now I have to debug this:
Rebooting...
!�␘!�L␘B␇1�!�!���!y␌�J�MODEM BOOT
MODEM: TRY AUTOCONNECT
MODEM: CHECK HomeSSID_Guest
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d293c PS : 0x00060130 A0 : 0x800d2978 A1 : 0x3ffca3f0
A2 : 0x3ffc36b0 A3 : 0x00000002 A4 : 0x3ffca45c A5 : 0x0000ff00
A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x00000000 A9 : 0x0000007f
A10 : 0x3ffca45c A11 : 0x00000001 A12 : 0x00000200 A13 : 0x0000ff00
A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000011 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000002 LBEG : 0x40089881 LEND : 0x40089891 LCOUNT : 0xffffffff
Backtrace: 0x400d2939:0x3ffca3f0 0x400d2975:0x3ffca410 0x400d28f2:0x3ffca430 0x400d29e2:
0x3ffca450 0x400d2af9:0x3ffca580 0x400d2b8b:0x3ffca5b0 0x400d669a:0x3ffca5e0
ELF file SHA256: b472167c77126ae4
Rebooting...
%S9#�!��n�s����9␌�␌�
��MODEM BOOT
The line noise is because the code is using a baud rate of 9600 while the ESP firmware is sending at 115200. Something I can fix (without some hardware tweaks).
Anyways, it's late and I have work in the morning. I don't like leaving the board in a constant state of reboot, but I'm going to have to.
- [1] https://git.wntrmute.dev/kyle/klib
- [2] https://git.wntrmute.dev/kyle/kimodem
- [3] https://www.sparkfun.com/products/16781
- [4] https://www.sparkfun.com/products/16400