No author in sight.
The documentation is ancient history.
Yet, tomorrow, it must run.
For over 25 years, I have been keeping that software alive.
This is the story of who I am. Read it on Medium.
https://t.co/e0qTntiE9y
3/ I didn't rewrite everything.
Working low-level mechanisms stayed.
The goal was to make ownership explicit and change the system incrementally on real hardware.
I wrote the full case study here:
https://t.co/Yu9w74dN0b
#EmbeddedSystems#FreeRTOS#Firmware
1/ BLE sometimes failed after disconnect.
LED and buzzer effects conflicted.
Flash writes disturbed periodic processing.
Debug worked.
Release failed.
Adding another if or another flag would only make the system harder to understand.
2/ The real question became:
Who owns this state?
I separated:
• application state transitions
• hardware effects
• BLE events
• persistent storage
• time-critical processing
Queues and EventGroups replaced some of the informal Boolean signaling.
Too many flags. Not enough ownership.
I refactored legacy FreeRTOS firmware where BLE, ADC, Flash, LEDs and timers had gradually become tangled through shared state.
The bugs looked random.
They weren't. 🧵
A timeout inside the application is useful.
A timeout around the application is a reliability boundary.
Here is what I learned while recovering hung BlueZ state on a Raspberry Pi BLE collector:
https://t.co/H2wLP5i82o
#EmbeddedSystems#BlueZ
I removed Flash/KV Store writes from a 10 ms FreeRTOS timer callback.
The problem wasn’t Flash itself.
The problem was making real-time processing depend on unpredictable storage latency.
Small change. Much cleaner timing boundary.
Debug works. Release fails.
The bug was hidden inside an assert.
CY_ASSERT(initialize_storage() == SUCCESS);
In Release, the assert disappeared.
So did the initialization.
I wrote about how I found it and why this pattern is dangerous in embedded firmware.