30 March 2016

Development for embedded systems

Disclaimer: In this case my meaning for the "embedded systems" is a bit different from what one might think. Nowadays, Internet of Things (IoT) is a rapidly growing market and developers often refer to modules like esp8226 and other --duino boards.
Today I'll talk more about the GNSS receivers SoCs, which also have very low power requirements, relatively weak CPUs (ARM or PowerPC), but often come with DSP, which comes in handy in the situation of very limited computational resourses.

In the perfect world the only difference one should see between the development for the PC and GNSS SoCs is the performance. But we're not there yet. You have to download the external toolchain, new IDE, buy the JTAG probe (God, they're expensive) and so on. And there's more: because you've changed the compiler, you have to revise the code very carefully. No more C++11 (goodbye templates, auto, nullptr), I haven't yet worked with SoC with implemented STL (no more std::vector, only static arrays). I really love the idea of Microsoft with their Windows 10, that there's one OS and the development tools for every device: laptop, smartphone, tablet and PC. But again, we're not in the perfect world. So don't trust the compiler toolkit. Check the obj file, double check if you have some strange bug or you're not sure. The more specialized compiler is the more unknown bugs and undefined behaviour it contains. Morale: don't trust the compiler!

To run bare-metal application, you should place it to the zero-offset memory. Then the first non-maskable interrupt will start the application. Sounds easy, eh?

Today I learned, that it's not. This method assumes that the first instruction is located exactly at the 0x0. But once again: don't trust the compiler. It may rearrange the code, data and the others sections by his own means. And the worst thing that it won't even tell you this. So today I had to use some duct tape code: assemly function that is placed at zero-offset memory. That function (pre_start) just calls the start. Start consists of some initializations, that are created by the compiler. After the start the main() is called and we can proceed with our bare-metal debug.

The ARM application is now only used to control two LEDs, and to turn them ON I have to write 0 to the GPIO pin... But that's another story about our circuit design department.

No comments:

Post a Comment