EEVblog Electronics Community Forum

Electronics => Microcontrollers => Topic started by: yashrk on December 18, 2018, 04:43:21 pm

Title: Resources for better embedded programming
Post by: yashrk on December 18, 2018, 04:43:21 pm
Hey, guys, I needed help in finding resources to improve my embedded programming.

The last project I worked on needed me to write a C program for an existing product (this was my first professional project as a trainee engineer) which had its code written in Basic, and I ended up writing a "working code" with a program flow similar to the existing code. As you can imagine the code was nothing to be proud of.
But I do want to improve on that, most of the classes in university we end up learning how the language work and its basics but we never learn to structure code for an embedded system or how we should we approach to write code for a control system.
I have tried to find such resources which talk's about the process of writing good code and not just teach you to write "for loop" in that specific language. I certainly have found few good coding advise here and there but nothing extensive.
If you know of any such resources which can help me to be a better programmer please do share, irrespective of resource is specific for embedded or not.

Thanks,
Yash
Title: Re: Resources for better embedded programming
Post by: rstofer on December 18, 2018, 10:00:36 pm
A long while back there was the concept of "Top Down Design" and "Bottom Up Coding".

The idea was that you would start thinking about the top level and what it should do.  You might even sketch it out on a whiteboard or even a tablet.  What does the thing do?  How do people interact with it?  Is there a menuing system?  We keep thinking about lower and lower levels until we get down to the hardware.

Then we know the requirements of the hardware so we start coding back toward the top, testing each level as we go.  Eventually, we reach the top and the project is finished.

I don't know if this is in common use today.  There were a lot of books written on the topic back around '80 or so.

https://en.wikibooks.org/wiki/A-level_Computing/AQA/Problem_Solving,_Programming,_Data_Representation_and_Practical_Exercise/Problem_Solving/Top-down_design_and_Step-wise_refinement

https://stackoverflow.com/questions/881064/top-down-and-bottom-up-programming

With Top Down Design, you can code up dummy lower level procedures to test things like the user interface.

I don't know that it really matters but one thing that does matter is that the programmer needs to understand what the system is supposed to do.  Really understand it...
Title: Re: Resources for better embedded programming
Post by: nctnico on December 18, 2018, 10:48:23 pm
I think there are two main issues to tackle when writing a program: designing the logic and writing robust code. Designing the logic means work out flow charts and data flow first. UML is probably a good start. A good design has at least a data flow and an event/interaction flow which matches up. This should catch problems with the design in an early stage.

Writing robust code comes down to checking values and index ranges. Try to avoid using pointers because you can't do a range check on what a pointer is pointing to. And avoid casting one type into another. The latter usually means the design isn't right so back to the drawing board. Either way 99.9% of the C code out there is just bad.
Googling for 'writing robust C code' will lead to many interesting websites. If you feel like writing robust C code is cumbersome then you are starting to get somewhere.  ;)
Title: Re: Resources for better embedded programming
Post by: westfw on December 19, 2018, 02:07:26 am
Quote
we never learn to structure code for an embedded system or how we should we approach to write code for a control system.
Reading about, or taking a class, in the use of Real Time Operating Systems would probably be useful, even for cases where you don't end up using an RTOS.  Things  like Interrupts, context, and efficiency, and resource managment show up more there than they do is most other CS classes.
Title: Re: Resources for better embedded programming
Post by: nick_d on December 20, 2018, 10:12:20 am
Practice, practice, practice.

The first embedded controller I wrote was nothing to be proud of either, but it DID work. I remember struggling with issues like debouncing buttons... That would be like 2mins work now that I've seen all the different ways to do it and developed preferences for several of them (depending).

I agree RTOS is where it is at, although you might get a better grounding in the concepts by writing straight interrupt driven code with no RTOS initially. Well either way, jump in. Honestly the only way to get good is choose a project and then do it.

cheers, Nick
Title: Re: Resources for better embedded programming
Post by: tggzzz on December 20, 2018, 11:22:54 am
Understand the concepts of finite state machines, i.e. long-duration states and instantaneous events. Work out how they map onto the concepts in RTOSs and hardware, e.g. interrupts, messages, threads.

Avoid using priority as a means of getting something to work, except for interrupts and everything else.
Title: Re: Resources for better embedded programming
Post by: yashrk on December 20, 2018, 11:32:17 am
Thank you guys for your responses.

And I agree getting in to a project and figuring out problems, stumbling along the way and learning is the best way and that's what my process has been till date.

I haven't work on any type of real time system and that will be the next thing that I will like to tackle. Please do share any resources you happen to like.
Title: Re: Resources for better embedded programming
Post by: emece67 on December 20, 2018, 12:30:58 pm
Understand the concepts of finite state machines, i.e. long-duration states and instantaneous events. Work out how they map onto the concepts in RTOSs and hardware, e.g. interrupts, messages, threads.

Avoid using priority as a means of getting something to work, except for interrupts and everything else.

To achieve this goal, reading "Practical UML Statecharts in C/C++" can be helpful. Although this book presents a particular solution (author's one) to the problem, I think that the presentation he mades about FSM, extended FSM, hierarchical FSM and a way to implement then to build event driven systems is quite interesting.

Unfortunately the book is in someway outdated againts the C/C++ framework, tools and examples currently available at author's webpage.

Hope this helps, regards.
Title: Re: Resources for better embedded programming
Post by: tggzzz on December 20, 2018, 12:53:14 pm
Understand the concepts of finite state machines, i.e. long-duration states and instantaneous events. Work out how they map onto the concepts in RTOSs and hardware, e.g. interrupts, messages, threads.

Avoid using priority as a means of getting something to work, except for interrupts and everything else.

To achieve this goal, reading "Practical UML Statecharts in C/C++" can be helpful. Although this book presents a particular solution (author's one) to the problem, I think that the presentation he mades about FSM, extended FSM, hierarchical FSM and a way to implement then to build event driven systems is quite interesting.

Unfortunately the book is in someway outdated againts the C/C++ framework, tools and examples currently available at author's webpage.

Hope this helps, regards.

I don't know that particular book, but Harel's Statecharts are a reasonable foundation.

FSMs can be implemented in several ways. My preferences are for
Title: Re: Resources for better embedded programming
Post by: rstofer on December 20, 2018, 03:26:33 pm
Thank you guys for your responses.

And I agree getting in to a project and figuring out problems, stumbling along the way and learning is the best way and that's what my process has been till date.

I haven't work on any type of real time system and that will be the next thing that I will like to tackle. Please do share any resources you happen to like.

FreeRTOS has been ported to hundreds of boards.  Find a board that is supported and start with that.
FreeRTOS has been in use for many years and the documentation is excellent.  Many manufacturers include a ported version in their toolkit.  The Cypress PSOC 6 includes FreeRTOS in such a way that you just select an option button, decide on the stack size and the tools configure it for you.  All you have to do is add in the task code.

An RTOS lets you partition your code into separate tasks that communicate through structures.  The main loop doesn't need to know how the menuing system works, it only needs to become aware of the results.  More important than even the "real time" bit, partitioning makes the program easier to understand.  A bunch of tasks, doing their own thing, commuting communicating through structures (semaphores, mailboxes, queues, etc).  It let's you focus your efforts on the 'task' at hand while pretty much ignoring everything else.  Yes, the pun was intended.

I really like the way Cypress integrated FreeRTOS and you really owe it to yourself to play with a PSOC 4 or PSOC 6 (especially the PSOC 6 BLE Pioneer Kit).  Watch the video series and follow along!

http://www.cypress.com/training/psoc-101-video-tutorial-series-how-use-arm-cortex-m4-based-psoc-6 (http://www.cypress.com/training/psoc-101-video-tutorial-series-how-use-arm-cortex-m4-based-psoc-6)

Yes, the board costs more than many but education has never been free.

What about the 'superloop'?  Every embedded program has one:

while(1) {
// do everything
}

Inside the loop there will usually be some kind of FSM which is nothing more than a C 'switch' statement (on steroids).

Code: [Select]
int WinMain(void) { // ignore the WinMain vs main thing, it's a compiler issue...
// setup code goes here
int condition = 1;
int state = 1;
while (1) { // the superloop
switch (state) { // the FSM
case 1 : // do something in this first state
state = 2; // we're done with state 1
case 2 : // do something in this second state
if (condition) {
state = 1;
}
else {
state = 2; // loop here again
}
}

}
}

Clearly, a real project will be a lot more complex but, as a structure for a program, this works well in many cases.  As mentioned above, an array of function pointers also works well.  Sometimes the function calls are just coded into the switch() statement.  It depends entirely on the complexity of the function code whether to use an array of pointers to functions or just a simple switch statement.

By all means, start with the video series above.  It's quite a leap to go from Arduino to a project with FreeRTOS.  I recommended the PSOC 6 board but I would go along with any ARM board that already has a port.
Title: Re: Resources for better embedded programming
Post by: tggzzz on December 20, 2018, 03:41:09 pm
An RTOS lets you partition your code into separate tasks that communicate through structures.  The main loop doesn't need to know how the menuing system works, it only needs to become aware of the results.  More important than even the "real time" bit, partitioning makes the program easier to understand.  A bunch of tasks, doing their own thing, commuting through structures (semaphores, mailboxes, queues, etc).  It let's you focus your efforts on the 'task' at hand while pretty much ignoring everything else.  Yes, the pun was intended.

Precisely.

Quote
Inside the loop there will usually be some kind of FSM which is nothing more than a C 'switch' statement (on steroids).
Code: [Select]
int WinMain(void) { // ignore the WinMain vs main thing, it's a compiler issue...
// setup code goes here
int condition = 1;
int state = 1;
while (1) { // the superloop
switch (state) { // the FSM
case 1 : // do something in this first state
state = 2; // we're done with state 1
case 2 : // do something in this second state
if (condition) {
state = 1;
}
else {
state = 2; // loop here again
}
}

}
}
Clearly, a real project will be a lot more complex but, as a structure for a program, this works well in many cases.  As mentioned above, an array of function pointers also works well.  Sometimes the function calls are just coded into the switch() statement.  It depends entirely on the complexity of the function code whether to use an array of pointers to functions or just a simple switch statement.

The devil in the details is that too many projects start out with that, and then add another state, and then "just one little event", until it becomes an incomprehensible mess with nesting 10 deep. Yes, I've seen that in a commercial product, and getting a change out the door took 6 months. Ridiculous.

The key is to structure your thinking and hence the code such that when a change/enhancement is made, there is only one place that needs to be changed and it can be seen it doesn't affect unrelated operations.
Title: Re: Resources for better embedded programming
Post by: rstofer on December 20, 2018, 06:31:49 pm
The devil in the details is that too many projects start out with that, and then add another state, and then "just one little event", until it becomes an incomprehensible mess with nesting 10 deep. Yes, I've seen that in a commercial product, and getting a change out the door took 6 months. Ridiculous.

The key is to structure your thinking and hence the code such that when a change/enhancement is made, there is only one place that needs to be changed and it can be seen it doesn't affect unrelated operations.

I think that the increased complexity comes about from poor design from the start.  That's why I like the "Top Down" approach to design.  Get the big ideas out of the way and design down toward the hardware.  Then code your way back up!  But, no matter how you do it, sometimes it is better to drop the box of cards and start over (old Fortran truism).

As a newcomer, I would spend the time to implement some project with FreeRTOS and then use it as a template for grander undertakings.  At this point, it is probably the only rational way to undertake a large project.  Not just for 'real time' but for partitioning.
Title: Re: Resources for better embedded programming
Post by: emece67 on December 20, 2018, 07:04:52 pm
Understand the concepts of finite state machines, i.e. long-duration states and instantaneous events. Work out how they map onto the concepts in RTOSs and hardware, e.g. interrupts, messages, threads.

Avoid using priority as a means of getting something to work, except for interrupts and everything else.

To achieve this goal, reading "Practical UML Statecharts in C/C++" can be helpful. Although this book presents a particular solution (author's one) to the problem, I think that the presentation he mades about FSM, extended FSM, hierarchical FSM and a way to implement then to build event driven systems is quite interesting.

Unfortunately the book is in someway outdated againts the C/C++ framework, tools and examples currently available at author's webpage.

Hope this helps, regards.

I don't know that particular book, but Harel's Statecharts are a reasonable foundation.

FSMs can be implemented in several ways. My preferences are for
  • a 2D array of function pointers (state and event being the indices) since every combination has to be explicitly enumerated
  • a class=state and event=method in an OOP environment, where hierarchical states map naturally onto class hierarchies

The book presents Harel's statecharts, but it also shows you how to code them. The aproach took by the author is: FSM (or EFSM or HSM) = class; state handler = method; state = pointer to state handler; event = another class; FSMs interchange events.

Regards.
Title: Re: Resources for better embedded programming
Post by: tggzzz on December 20, 2018, 07:47:10 pm
The book presents Harel's statecharts, but it also shows you how to code them. The aproach took by the author is: FSM (or EFSM or HSM) = class; state handler = method; state = pointer to state handler; event = another class; FSMs interchange events.

That is one way of coding them in one language. If that is the only way presented, then it is unfortunate.

There is more than one way to skin a cat; which is best depends on the circumstances.
Title: Re: Resources for better embedded programming
Post by: rstofer on December 20, 2018, 10:16:21 pm

There is more than one way to skin a cat;

The cat won't like any of them!
Title: Re: Resources for better embedded programming
Post by: rstofer on December 20, 2018, 10:21:23 pm
The book presents Harel's statecharts, but it also shows you how to code them. The aproach took by the author is: FSM (or EFSM or HSM) = class; state handler = method; state = pointer to state handler; event = another class; FSMs interchange events.

That is one way of coding them in one language. If that is the only way presented, then it is unfortunate.

There is more than one way to skin a cat; which is best depends on the circumstances.

Apparently the latest version is oriented toward C instead of C++.  Page xix

https://www.state-machine.com/doc/PSiCC2_Excerpts.pdf (https://www.state-machine.com/doc/PSiCC2_Excerpts.pdf)
Title: Re: Resources for better embedded programming
Post by: emece67 on December 21, 2018, 02:46:30 am
That is one way of coding them in one language. If that is the only way presented, then it is unfortunate.

There is more than one way to skin a cat; which is best depends on the circumstances.

If my memory serves me well, the author discusses 3 ways to code FSM/HSMs, the nested switch, the 2D table and the OO method, being this last the one that he fully develops (in both C & C++) along the book. The framework supplied by the author is based on such approach. He also adds some more mechanisms to manage/dispatch events, etc.

The website gives some introductory material that can be consulted just to ascertain if the book is worth of a read.

Regards.
Title: Re: Resources for better embedded programming
Post by: westfw on December 21, 2018, 05:05:06 am
Quote
I agree RTOS is where it is at
That's not at all what I meant to say...


An RTOS (or any operating system, really, but RTOSes seem to have the books) teaches about many of the concurrency and parallelism issues that show up with microcontroller peripherals ALL THE TIME.  Interfacing slow peripherals to fast CPUs, or fast peripherals to ... anywhere, resource sharing and contention, response time to critical events, are problems that OS writers have been dealing with since mainframe, and a lot of the problems, and solutions, are very similar even on the tiniest microcontroller...

Title: Re: Resources for better embedded programming
Post by: Cicero on December 21, 2018, 01:10:19 pm
Think the overall message is just to dive in and learn whilst doing. 

FreeRTOS is an amazing resource, its a great starting point, but for smaller projects might just add unnecessary bloat.  Its a good idea to get involved in some small open source projects on github, you'll get exposed to lots of varying code structures and methods.

Try to avoid getting into a rut thinking one method is a one-size-fits-all solution, spend a decent time in a planning and review stage of specifications before writing any code. 

Title: Re: Resources for better embedded programming
Post by: yashrk on December 21, 2018, 01:13:23 pm
Good idea, thanx!