M0AGX / LB9MG

Amateur radio and embedded systems

  • Abusing reserved interrupt vectors on Cortex-M for metadata

    Bootloaders in embedded systems need a way to tell if there is a valid application available in memory. Executables on devices with an operating system use elaborate file formats like elf and exe but small bare-metal bootloaders need something simpler to keep both the bootloader size and the application size small. In this post I present the simplest possible scheme - a single CRC32 checksum appended to a raw binary file and how to do it.

    Read more...

  • Wiznet W7500 flash programming

    W7500 is a nice little MCU from Wiznet with a built-in hardware TCP/IP stack and Ethernet MAC. You can get quite far with your IoT application on a Cortex-M0 running at 48 MHz when the networking is offloaded in hardware. The device begins to show its age in 2023 (it was released around 2016). There is no crypto acceleration whatsoever, no AES. Only an RNG is available. I think that modern TLS is practically impossible but some lighter cryptography should be possible. Nevertheless, if you can put the device on an isolated VLAN the chip can still be useful today.

    Read more...

  • Listing stuck Python threads

    More than once I have been in the situation where a multithreaded Python application (eventually 😁) runs fine, all the threads cooperate nicely, but do not shut down cleanly. This for example happens after closing GUI windows where the GUI goes away but some worker threads do not. A Ctrl+C might help to shut down the stuck application only if the main thread is stuck. Still, every application should shut down cleanly so that it can be correctly monitored and restarted by init / systemd / wrapper script etc.

    Read more...

  • Recovering a bricked Wiznet W7500 using the bootloader

    I "bricked" a Wiznet W7500 MCU during development. After flashing yet another build of the firmware the J-Link disconnected suddenly and I was not able to connect to the chip again (even under reset). What's funny is that the LEDs blinked as usual and I was able to ping my application so the chip was far from being dead. I quickly found the suspected piece of code: pin muxing. When changing PORTA muxing options I must have un-muxed the SWD pins. 🙁

    Read more...

  • I have been copied on Aliexpress!

    Imitation is the sincerest form of flattery. A while ago I published a design of a basic coax switch for HF antennas. To my surprise, a fellow ham messaged me that I am "famous" on Aliexpress. 🙂

    Read more...

  • Today I learned: How to read address zero on RISC-V

    I have been working on a "yet another" flashloader with standard flash operations like readback and blank checks. The chip has flash mapped starting from address 0x0 so I wrote the code with obvious pointers like uint32_t *p = 0x0;. I built the code with gcc like countless times before but I did not get the behaviour I expected. The only thing "special" this time was that the CPU was a RISC-V.

    Read more...

  • Story from the trenches - uninitialized RAM is not random (enough)

    This is another story from the world of "it can't happen". A device was undergoing final testing that spanned many days in different simulated conditions. The testing included power cycling whenever the conditions were changed. Once in a very long while, on the order of maybe once per week, the device failed to communicate with the test equipment.

    Read more...

  • Things you should know about the stack on Cortex-M

    The stack is one of the "invisible" parts of almost every C implementation. It comes into view usually when something goes wrong. On a PC with an operating system in a "good" bad case the application will crash in an obvious way but issues with the stack can also lead to security vulnerabilities. On bare-metal embedded systems stack overflows can manifest themselves as "silent" data corruption (in the worst case) or obvious crashes/resets (in the "good" case). I will focus on the bare-metal Cortex-M use case.

    Understanding stack usage is also crucial to knowing how much "free" RAM is there left in an embedded system.

    Read more...

  • Bug of the day: missing entry point

    This is a tale of a strange bug I ran into when doing my first ever SAM E70 project. A new MCU. A new type of product. A custom PCB. What could possibly go wrong? 🙂

    Spoiler: Not strange. Not a bug.

    Read more...

  • Implementing a LIN slave on STM32L011

    LIN bus is a communication standard that originated in the automotive industry but is slowly gaining ground in other areas. It is less known than CAN, RS-485, I2C, SPI or USB but has some significant advantages when it comes to developing really cheap and simple devices that have to be …

    Read more...