How to make your embedded C code immune to requirement changes without adding too much overhead and complexity? - c

In many embedded applications there is a tradeoff between making the code very efficient or isolating the code from the specific system configuration to be immune to changing requirements.
What kinds of C constructs do you usually employ to achieve the best of both worlds (flexibility and reconfigurabilty without losing efficiency)?
If you have the time, please read on to see exactly what I am talking about.
When I was developing embedded SW for airbag controllers, we had the problem that we had to change some parts of the code every time the customer changed their mind regarding the specific requirements. For example, the combination of conditions and events that would trigger the airbag deployment changed every couple weeks during development. We hated to change that piece of code so often.
At that time, I attended the Embedded Systems Conference and heard a brilliant presentation by Stephen Mellor called "Coping with changing requirements". You can read the paper here (they make you sign-up but it's free).
The main idea of this was to implement the core behavior in your code but configure the specific details in the form of data. The data is something you can change easily and it can even be programmable in EEPROM or a different section of flash.
This idea sounded great to solve our problem. I shared this with my colleague and we immediately started reworking some of the SW modules.
When trying to use this idea in our coding, we encountered some difficulty in the actual implementation. Our code constructs got terribly heavy and complex for a constrained embedded system.
To illustrate this I will elaborate on the example I mentioned above. Instead of having a a bunch of if-statements to decide if the combination of inputs was in a state that required an airbag deployment, we changed to a big table of tables. Some of the conditions were not trivial, so we used a lot of function pointers to be able to call lots of little helper functions which somehow resolved some of the conditions. We had several levels of indirection and everything became hard to understand. To make a long story short, we ended up using a lot of memory, runtime and code complexity. Debugging the thing was not straightforward either. The boss made us change some things back because the modules were getting too heavy (and he was maybe right!).
PS: There is a similar question in SO but it looks like the focus is different. Adapting to meet changing business requirements?

As another point of view on changing requirements ... requirements go into building the code. So why not take a meta-approach to this:
Separate out parts of the program that are likely to change
Create a script that will glue parts of source together
This way you are maintaining compatible logic-building blocks in C ... and then sticking those compatible parts together at the end:
/* {conditions_for_airbag_placeholder} */
if( require_deployment)
trigger_gas_release()
Then maintain independent conditions:
/* VAG Condition */
if( poll_vag_collision_event() )
require_deployment=1
and another
/* Ford Conditions */
if( ford_interrupt( FRONT_NEARSIDE_COLLISION ))
require_deploymen=1
Your build script could look like:
BUILD airbag_deployment_logic.c WITH vag_events
TEST airbag_deployment_blob WITH vag_event_emitter
Thinking outloud really. This way you get a tight binary blob without reading in config.
This is sort of like using overlays http://en.wikipedia.org/wiki/Overlay_(programming) but doing it at compile-time.

Our system is subdivided into many components, with exposed configuration and test points. There is a configuration file that is read at start-up that actually helps us instantiate components, attach them to each other, and configure their behavior.
It's very OO-like, in C, with the occasional hack to implement something like inheritance.
In the defense/avionics world software upgrades are very strictly controlled, and you can't just upgrade SW to fix issues... however, for some bizarre reason you can update a configuration file without a major fight. So it's been darn useful for us to be able to specify a lot of our implementation in those configuration files.
There is no magic, just good separation of concerns when designing the system and a bit of foresight on the part of the developers.

What are you trying to save exactly? Effort of code re-work? The red tape of a software version release?
It's possible that changing the code is reasonably straight-forward, and quite possibly easier than changing data in tables. Moving your often-changing logic from code to data is only helpful if, for some reason, it's less effort to modify data rather than code. That might be true if the changes are better expressed in a data form (e.g. numeric parameters stored in EEPROM). Or it might be true if the customer's requests make it necessary to release a new version of software, and a new software version is a costly procedure to build (lots of paperwork, or perhaps OTP chips burned by the chip maker).
Modularity is very good principle for these sort of things. Sounds as though you're already doing it to some degree. It's good to aim to isolate the often-changing code to as small an area as possible, and try to keep the rest of the code ("helper" functions) separate (modular) and as stable as possible.

I don't make the code immune to requirements changes per se, but I always tag a section of code that implements a requirement by putting a unique string in a comment. With the requirements tags in place, I can easily search for that code when the requirement needs a change. This practice also satisfies a CMMI process.
For example, in the requirements document:
The following is a list of
requirements related to the RST:
[RST001] Juliet SHALL start the RST with 5 minute delay when the ignition
is turned OFF.
And in the code:
/* Delay for RST when ignition is turned off [RST001] */
#define IGN_OFF_RST_DELAY 5
...snip...
/* Start RST with designated delay [RST001] */
if (IS_ROMEO_ON())
{
rst_set_timer(IGN_OFF_RST_DELAY);
}

I suppose what you could do is to specify several valid behaviors based on a byte or word of data that you could fetch from EEPROM or an I/O port if necessary and then create generic code to handle all possible events described by those bytes.
For instance, if you had a byte that specified the requirements for releasing the airbag it could be something like:
Bit 0: Rear collision
Bit 1: Speed above 55mph (bonus points for generalizing the speed value!)
Bit 2: passenger in car
...
Etc
Then you pull in another byte that says what events happened and compare the two. If they're the same, execute your command, if not, don't.

For adapting to changing requirements I would concentrate on making the code modular and easy to change, e.g. by using macros or inline functions for parameters which are likely to change.
W.r.t. a configuration which can be changed independently from the code, I would hope that the parameters which are reconfigurable are specified in the requirements, too. Especially for safety-critical stuff like airbag controllers.

Hooking in a dynamic language can be a lifesaver, if you've got the memory and processor power for it.
Have the C talk to the hardware, and then pass up a known set of events to a language like Lua. Have the Lua script parse the event and callback to the appropriate C function(s).
Once you've got your C code running well, you won't have to touch it again unless the hardware changes. All of the business logic becomes part of the script, which in my opinion is a lot easier to create, modify and maintain.

Related

C design pattern performing a list of actions without blocking?

Embedded C. I have a list of things I want to do, procedurally, mostly READ and WRITE and MODIFY actions, acting on the results of the last statement. They can take up to 2 seconds each, I can’t block.
Each action can have states of COMPLETE and ERROR which has sub-states for reason the error occurred. Or on compete I’ll want to check or modify some data.
Each list of actions is a big switch and to re-enter I keep a list of which step I’m on, a success step++ and I come back in further down the list next time.
Pretty simple, but I’m finding that to not block I’m spending a ton of effort checking states and errors and edges constantly. Over and over.
I would say 80% of my code is just checks and moving the system along. There has to be a better way!
Are there any design patterns for async do thing and come back later for results in a way that efficiently handles some of the exception/edge/handling?
Edit: I know how to use callbacks but don’t really see that as “a solution” as I just need to get back to a different part of the same list for the next thing to do. Maybe it’s would be beneficial to know the backend to how async and await in other languages work?
Edit2: I do have an RTOS for other projects but this specific question, assume no threads/tasks, just bare metal superloop.
Your predicament is a perfect fit for state machines (really, probably UML statecharts). Each different request can each be handled in its own state machine, which handle events (such as COMPLETE or ERROR indications) in a non-blocking, run-to-completion manner. As the events come in, the request's state machine moves through its different states towards completion.
For embedded systems, I often use the QP event-driven framework for such cases. In fact, when I looked up this link, I noticed the very first paragraph uses the term "non-blocking". The framework provides much more than state machines with hierarchy (states within states), which is already very powerful.
The site also has some good information on approaches to your specific problem. I would suggest starting with the site's Key Concepts page.
To get you a taste of the content and its relevance to your predicament:
In spite of the fundamental event-driven nature, most embedded systems
are traditionally programmed in a sequential manner, where a program
hard-codes the expected sequence of events by waiting for the specific
events in various places in the execution path. This explicit waiting
for events is implemented either by busy-polling or blocking on a
time-delay, etc.
The sequential paradigm works well for sequential problems, where the
expected sequence of events can be hard-coded in the sequential code.
Trouble is that most real-life systems are not sequential, meaning
that the system must handle many equally valid event sequences. The
fundamental problem is that while a sequential program is waiting for
one kind of event (e.g., timeout event after a time delay) it is not
doing anything else and is not responsive to other events (e.g., a
button press).
For this and other reasons, experts in concurrent programming have
learned to be very careful with various blocking mechanisms of an
RTOS, because they often lead to programs that are unresponsive,
difficult to reason about, and unsafe. Instead, experts recommend [...] event-driven programming.
You can also do state machines yourself without using an event-driven framework like the QP, but you will end up re-inventing the wheel IMO.

Saving execution state -- something like protothreads but without using labels as values?

I'm trying to find a way to serialize execution/stack state, in such a way that the state can be archived and restored at a later time where execution can be made to pick up where it left off. Sort of like continuations, but with the feature that the stack state should be able to be serialized to disk and rehydrated on subsequent runs. I'm working in C (and/or Objective-C, if that helps.)
Protothreads looked somewhat close to what I'm looking for, but uses the GCC labels-as-values extension to resume from stored state. It seems to me that this is not likely to be robust for serialization/deserialization of the state across different compilations (and probably not even across runs of the same binary in the presence of ASLR.) In the abstract, there are going to be versioning challenges to be sure, but it doesn't seem like protothreads even gets that far.
I guess the canonical approach here would be to convert the code to a state machine, and then serialize/deserialize the state of the SM, but I find it a lot easier to think in terms of code, and struggle to envision how one would go about translating large swaths of non-trivial code into a state machine (even assuming that said code already has no global state or non-serializable heap structures, etc.)
It seems likely that any viable approach is going to require you to make allowances for it in your code. I imagine you'd have to store all your stack state in a "managed" stack structure that mirrored the stack, etc. I suspect it won't come "free", but I guess I'm hoping someone has already invented this wheel.
Anyone know of tools/libraries that address this problem, or alternately some method for converting arbitrary (but conforming) code into a serializable state machine? I found ragel, which goes the other way (SM specification -> code), but nothing generalize going this way.
I have subsequently discovered that C#'s compiler converts yield-based IEnumerator implementations into state machines in private/anonymous inner classes, so I guess it is possible to automate this for arbitrary code. Anyone know of a generalized method of doing this? (i.e. assuming you could structure the code like a yielding iterator.)

combining ms access vba codes

Me and my colleague are developing an ms access based application. We are designing and coding different pages/forms in order to divide work. We plan to merge our work later. How can we do that without any problems like spoiling the design and macros? We are using Ms access 2007 for front end and sqlserver 2005 as the datasource.
I found an idea somewhere on bytes.com. I can import forms, reports, queries,data and tables that I want.I'm going to try this. However, it's just an idea.So, need to study this approach by trial and error techniques.
The most important requirement is to complete the overall design before you start coding. For example:
All the forms must have the same style. Help and error information must be provided in the same way on each form. If a user can divide the forms into two sets, you have failed.
The database design must be finished with a complete, written description of each table, its relationships and its attributes.
The purpose and parameters for each major macro must be defined. If macro A1 exists only to service macro A then A1 is not a major macro and only A's author need know of its details until coding is complete.
Agreed a documentation style and detail level. If the application needs enhancement in six or twelve months' time, you should be able to work on the others macros and forms as easily as on your own.
If one of you thinks a change to the design is required after coding has started, this change must be documented, agreed with the other and the change specification added to the master specification.
Many years ago I lectured on (Electronic Data interchange (EDI). With EDI, the specification is divided into two with one set of organisations providing applications for message senders and another set providing applications for message receivers. I often used an example in my lectures to help my audience understand the importance of a complete, unambiguous specification.
I want two shapes, an E and a reverse-E, which I can fit together to create a 10 cm square. I do not care what they are made of providing they fit together perfectly.
If I give this task to a single organisation, this specification will be enough. One organisation might use cardboard, another metal, but I do not care. But suppose I ask one organisation to create the E and another the reverse-E. How detailed does my specification have to be if I am to get my 10 cm square? I would suggest: material, thickness and dimensions of the E. My audience would compete to suggest more and more obscure characteristics that had to match: density, colour, pattern, texture, etc, etc.
I was not always convinced my audience listened to the rest of my lecture because they were searching for a characteristic that would cap all the others. No matter, I had got across my major point which was why EDI specifications were no mind-blowingly detailed.
Your situation will not be so difficult since you and your colleague are probably in the same room and can talk whenever you want. But I hope this example helps you understand how easy is it for the interface between your two parts to be less than seamless if you do not agree the complete design at the beginning. It's the little assumptions - I though you knew I was doing it that way - that will kill your application.
New section
OK, probably most of my earlier advice was inappropriate in your situation.
So you are trying to modify code you did not write in a language you do not know. Good luck; you will need it.
I think scope is going to be your biggest problem. Most modern languages have namespaces allowing you to give a variable or a routine as much or as little scope as you require. VBA only has three levels.
A variable declared within a function or subroutine is automatically private to that function or subroutine.
A variable declared as Private within a module is invisible to functions and subroutines in other modules but is visible to any function or subroutine within the module.
A variable declared as Public within a module is visible to any function or subroutine within the project.
Anything declared within a form is private to that form. If a form wishes to pass a value to an outside function or subroutine, it can do so by writing to a public variable or by passing it in a parameter to a public function or subroutine.
Avoiding Naming Conflicts within VBA Help gives useful advice.
Form and module names will have to be unique across the merged project. You will not be able to avoid have constants, variables, functions and sub-routines which are visible to the other's functions and sub-routines. Avoiding Naming Conflicts offers one approach. An approach I have used successfully is to divide the application into sub-applications and, if necessary, sub-sub-applications and to assign a prefix to each. If every public constant, variable, function and sub-routine name has the appropriate prefix you can simulate namespace type control.

C, design: removing global objects

I'm creating a small Avida-style life simulation. I started out with a very basic, everything-is-global 600-line program in a single file to test some ideas, and now I want to create a real design.
Among other things, I had a global configuration object that every other function got something out of. Now, I must localize the object and pass pointers around. Thing is, mostly everyone needs this object. I've thought of three possible solutions:
a) Keep the configuration object
global (simplest, though not really a
solution)
b) Store pointers everywhere they are
needed (easy enough, though a waste
of memory, since some small
plain-old-data structures would need
it).
c) Create factories for the POD types
that need access to options, and have
the factory perform all operations on
them.
Of my ideas, only (c) sounds logical, but I don't want to needlessly complicate the structure. What would you guys do?
I'm fine with new ideas, and will provide whatever information about the program you want to know.
Thanks in advance!
I have to agree with #Carl Norum: there is nothing wrong with the global config setup you have now. You say that everybody "got something out of" it. As you know, the problem with globals comes when everybody writes into them. In your case, the config info truly is needed globally so deserves to be global.
If you want to make it be a little more decoupled and protected -- a little less global-ish -- then why not add some read/write access routines.
See, storing pointers everywhere isn't going to really solve the problem: it will only add a layer of indirection that will merely disguise or camouflage what are, in reality, the global accesses that are making you nervous. And that extra layer of indirection will add juuuuust enough room for juuuuust a teeny-weeny little bug to creep in.
So, bottom line: if stuff is naturally global then make it global and don't worry about the usual widespread received wisdom that's mostly correct but might not be the right thing in your application. To always be bound by the rules/propaganda that CS teachers put out there is, imo, the perfect example of a foolish consistency.
Global variables are awesome. Spend your time actually getting something done instead of refactoring for no reason. Every company I have worked at uses them heavily.
Ask yourself if you're actually gaining anything by moving it to an object you're just passing around everywhere. Might as well save yourself the extra complexity..
Go for B, unless profiling proves it to be a problem. On most machines, the memory required to store a pointer is very, very trivial.

How to imitate a player in an online game

I'd like to write an application, which would imitate a player in an online game.
About the game: it is a strategy, where you can:
train your army (you have to have enough resources, then click on a unit, click train)
build buildings (mines, armories, houses,...)
attack enemies (select a unit, select an enemy, click attack)
transport resources between buildings
make researches (economics, military, technologic,...)
This is a simplified list and is just an example. Main thing is, that you have to do a lot of clicking, if you want to advance...
I allready have the 'navigational' part of the application (I used Watin library - http://watin.sourceforge.net/). That means, that I can use high level objects and manipulate them, for example:
Soldiers soldiers = Navigator.GetAllSoldiers();
soldiers.Move(someLocation);
Now I'd like to take the next step - write a kind of AI, which would simulate my gaming style. For this I have two ideas (and I don't like either of them):
login to the game and then follow a bunch of if statements in a loop (check if someone is attacking me, check if I can build something, check if I can attack somebody, loop)
design a kind of scripting language and write a compiler for it. This way I could write simple scripts and run them (Login(); CheckForAnAttack(); BuildSomething(); ...)
Any other ideas?
PS: some might take this as cheating and it probably is, but I look on this as a learning project and it will never be published or reselled.
A bunch of if statements is the best option if the strategy is not too complicated. However, this solution does not scale very well.
Making a scripting language (or, domain specific language as one would call that nowadays) does not buy you much. You are not going to have other people create AI agents are you? You can better use your programming language for that.
If the strategy gets more involved, you may want to look at Bayesian Belief Networks or Decision Graphs. These are good at looking for the best action in an uncertain environment in a structured and explicit way. If you google on these terms you'll find plenty of information and libraries to use.
Sounds like you want a finite state machine. I've used them to various degrees of success in coding bots. Depending on the game you're botting you could be better off coding an AI that learns, but it sounds like yours is simple enough not to need that complexity.
Don't make a new language, just make a library of functions you can call from your state machine.
Most strategy game AIs use a "hierarchical" approach, much in the same way you've already described: define relatively separate domains of action (i.e. deciding what to research is mostly independent from pathfinding), and then create an AI layer to handle just that domain. Then have a "top-level" AI layer that directs the intermediate layers to perform tasks.
How each of those intermediate layers work (and how your "general" layer works) can each determined separately. You might come up with something rather rigid and straightforward for the "What To Research" layer (based on your preferences), but you may need a more complicated approach for the "General" layer (which is likely directing and responding to inputs of the other layers).
Do you have the sourcecode behind the game? If not, it's going to be kind of hard tracing the positions of each CPU you're (your computer in your case) is battling against. You'll have to develop some sort of plugin that can do it because from the sound of it, you're dealing with some sort of RTS of some sort; That requires the evaluation of a lot of different position scenarios between a lot of different CPUs.
If you want to simulate your movements, you could trace your mouse using some WinAPI quite easily. You can also record your screen as you play (which probably won't help much, but might be of assistance if you're determined enough.).
To be brutally honest, what you're trying to do is damn near impossible for the type of game you're playing with. You didn't seem to think this through yet. Programming is a useful skill, but it's not magic.
Check out some stuff (if you can find any) on MIT Battlecode. It might be up your alley in terms of programming for this sort of thing.
First of all I must point out that this project(which only serves educational purposes), is too large for a single person to complete within a reasonable amount of time. But if you want the AI to imitate your personal playing style, another alternative that comes to mind are neural networks: You play the game a lot(really a lot) and record all moves you make and feed that data to such a network, and if all goes well, the AI should play roughly the same as you do. But I'm afraid this is just a third idea you won't like, because it would take a tremendeous amount of time to get it perfect.

Resources