I had a chance to work for three years in a firm that was engaged in embedded systems, namely, automation that drives trains. Hard real time, serious testing and microsecond gnawing wherever possible. I will try to give a couple of tips to those who are interested in embedded systems (and from the posts on Habré, I realized that there are a lot of these ;-)
Our piece of iron was not weak at all - C167, 16 MHz clock, external bus with 4 chip selections, a lot of peripherals on a stone ... Yes, and there were problems that barely had enough pieces of iron - a survey of almost 2000 discrete inputs, and even with a clever cyclogram, data packing into special structures and the exchange of this information over CAN networks ... And all this within 1 millisecond!
And now - tips :-) Not always true and applicable to your stone, but suddenly they will help.
Consider that all your systems are real-time systems. That is, a system where the response to external influence must be no later than the nth amount of time. It is also desirable minimum ;-)
The main () function must end in an infinite loop. Without any return at all. For the devil knows where control will be transferred after leaving it!
Consider the state of the system in which it will bring minimal harm! The so-called protective failure. If suddenly the robot falls off the position sensor of the executive body - it should STOP, and not try to move to a safe position (where it goes with the severed sensor - also knows the devil). It would be nice if the user knew that the device is in such a state. For example, changing the clock to 88:88 is better than leaving the display unchanged. It is very useful to check the equipment connected to the microcontroller, at least during initialization. Not everything can be checked, but what is possible is a must!
About real time. The program for the microcontroller is multi-threaded in most cases, and main () should be a thread with a minimum priority. Higher priority threads are interrupt handlers. Interrupts must not be disconnected unless absolutely necessary (for example, switching to the protective failure state). The interrupt handler should not run longer than the minimum period between interrupts, otherwise the system will not have time for lower priority tasks. How to estimate time is so easy. One foot of the microcontroller output should not be very important for the operation of the device. Ideally, connect the LED to it and signal them with everything that you can :-) In general, switching the state of this leg will help with the help of an oscillum to measure the execution time of anything, anything :-)
Properly prioritize interrupts! In the watch priority is for the control buttons. If there is an emergency stop button, it should have the highest priority: what little will happen in the device and where it will get stuck, but it must be possible to stop it. The highest priority is for alarms, then - on the importance of the functions of the device.
It is very important to consider the execution time of the handler and the frequency of interruptions for communication tasks. Suddenly it turns out that interrupts on the COM port occur every 10 μs and the handler hangs in it 9 μs. As already mentioned above, programs are multi-threaded, so use synchronization when accessing the same object from different threads. Especially to the reception and transmission queues. One small bug in the queues, combined with high priority of communication interrupts - it creates terrible things! :-)
Know and love the equipment! Problems on the bus can result in long hours of debugging and irreproducible glitches. Using assembler is not always justified: a gain in percentages of time can lead to poor readability of the code, especially considering good compilers for some stones :-)
That, like, and remembered most of the underwater rakes, which attacked. Maybe you are doing frivolous devices for fun, and real hard time is not necessary at all, but why not make devices with a serious approach? Suddenly it is with these "toys" that your road to serious systems will begin? Good luck to everyone in design, programming and debugging :)
')
Ps. If the public says that there is a collective blog for this, I will postpone it right there.
Pps. Thanks to the commentators - they pushed one more piece of advice: interruptions are good, but polling in a loop where interruptions can be used is evil! Although interruptions seem scary and terrible :-)