Home › Forums › Chat Forum › Any firmware engineers here?
- This topic has 25 replies, 11 voices, and was last updated 10 years ago by GrahamS.
-
Any firmware engineers here?
-
UrbanHikerFree Member
Just after a bit of a pointer really. I’ve been programming for decades, but never with an RTOS. Now I have one, I don’t really know how to use it!
I’m after some pointers, especially with regard to semaphore/mutex task synchronisation and mutual exclusion. I understand the concept of the mechanisms, and how they could help. But can’t for the life of me work out what “best practice” would be in the real world. Can’t find any real world examples on the net, only classroom simplifications.
Anyone care to help enlighten me…
Book/website recommendation would be a good start.
gofasterstripesFree Memberuuuhhhhh… nothing on Slashdot or Stackexchange?
This is beyond me, sorry.
FlaperonFull MemberI’m after some pointers
0x3A24633A
0x6875534C
0x64D3322CYou can have those for free.
jwrFull MemberI’m not a RTOS programmer, but I do write a lot of concurrent code. My starting point was “Principles of Concurrent and Distributed Programming” by M. Ben Ari. It’s a pretty dry academic text, but it covers the fundamentals and a number of use cases. From there I mostly taught myself by experimenting.
You might want to look into the latest fad of writing parallel code on graphics cards as it uses the same concepts.
gofasterstripesFree MemberI think there’s a lot of mileage in graphics card programming, myself. HUMA etc.
JamieFree Member0x3A24633A
0x6875534C
0x64D3322CI don’t think that is intergra to his question.
GrahamSFull MemberHello. Been doing firmwarey-type stuff for about ten years.
We typically work on small footprint devices and write our own OS, but I have worked with some RTOS too (e.g. LynxOS, QNX and WinCE)
I’m after some pointers, especially with regard to semaphore/mutex task synchronisation and mutual exclusion.
That sounds like you just need some guidance on general multi-threading and concurrency, rather than RTOS in particular. The basic principles are the same, though RTOS typically have stricter scheduling of threads/tasks etc to ensure they get serviced in a timely manner.
UrbanHikerFree MemberThanks all.
Yep, GrahamS, your bang on the money. It is an RTOS, but in reality its not the real time bits that I have a lack of understanding of. As you say, its multi-thread and concurrency.
Thanks, jwr. I’ll check it out.
To give an example of something I thought I knew but didn’t. My initial approach was to give every thread a unique priority, mostly so that I could reason about when something might run. Now I realise that is completely the wrong approach. I guess I’m looking for a 1st or 2nd year uni level mental download.
BurgerFull MemberNot a programmer myself, more hardware, but can I point you to Jack Ganssle http://www.ganssle.com. He has loads of book reviews and articles that might have the answers you are looking for.
Even if you don’t find what you want, I can recommend the articles under sailing [/url] for some way off topic reading.UrbanHikerFree MemberI’ve been on Jack Ganssle’s mailing list for years. Great stuff. Never thought of looking at his book review list. Good call.
GrahamSFull MemberTo give an example of something I thought I knew but didn’t. My initial approach was to give every thread a unique priority, mostly so that I could reason about when something might run.
That’s really down to the scheduling system used, which will depend which RTOS you are coding for.
Some background here:
http://en.wikipedia.org/wiki/Scheduling_(computing)UrbanHikerFree MemberThanks for all the input. I think even getting the correct phrasing for things has helped. Now looking into multi-threading…
mrmonkfingerFree MemberBeen doing RTOS for years. Some good pointers already mentioned.
If you can get your head around the ‘priority inversion’ problem, you’ll be ok with using semaphores & mutexes.
Also, if you’re generally hot on proper memory allocation (you know, always and I mean always freeing stuff you’ve allocated) you just need to apply a similar approach to working the mutexes/semaphores.
GrahamSFull Memberproper memory allocation
Get you with your fancy memory allocation. 😀
(we are typically not allowed to use the heap at all. Not one single byte.)
mrmonkfingerFree MemberI had to go with a metaphore that an app programmer would understand 😆
chambordFull MemberAlso, if you’re generally hot on proper memory allocation (you know, always and I mean always freeing stuff you’ve allocated) you just need to apply a similar approach to working the mutexes/semaphores.
Does all this kind of stuff get done in exclusively in C, or is C++ allowed? If so, C++ and RAII is your friend here. I’d also look in to C++11, with async calls and future types.
GrahamSFull MemberIf so, C++ and RAII is your friend here.
We do write stuff in Embedded C++ but as above, no heap allocation so you can forget using objects and RAII.
chambordFull MemberDestructors still get called when objects on the stack go out of scope so an RAII wrapper would still be nicer for maintaining mutexes.
Anyway it sounds like UrbanHiker has enough on his plate so that can wait a while 🙂
andytherocketeerFull Membernot done this for decades. but it does take me back to the days of Transputers and playing with Occam.
no heap for us either. wrote our own deterministic scheduler, so zero concurrency, no heap, no priority, careful splitting of activities meant no task deadlock. hardest bit was making sure that any application would never come to a natural end and would always be rescheduled by some means.
much more fun than writing desktop apps. specially when debugging unforeseen strange combinations of external stimuli that the guys writing the spec didn’t account for.
chambordFull Memberspecially when debugging unforeseen strange combinations of external stimuli that the guys writing the spec didn’t account for.
That sounds more like hell than fun to me 🙂
EDIT: Though I’ll add that desktop app development doesn’t set my heart on fire either 🙂
GrahamSFull Memberhardest bit was making sure that any application would never come to a natural end and would always be rescheduled by some means.
Yeah.. that can be tricky..
http://en.wikipedia.org/wiki/Halting_problem
😉
kcalFull Memberbeen decades since last programmed at anything other than medium level, 6800 was processor of choice during my studies 🙁 some 8086 assembler when I first started working, but course didn’t cover concurrent OS techniques though it did delve into processors quite a bit.
Kind of regret moving to higher levels of languages, it’s akin to really getting your hands dirty at fixing bikes I reckon!
UrbanHikerFree MemberAh, I wondered if the banter my heat up a little during work time!
So, yep agree with GS. Would never touch dynamic memory allocation, just asking for trouble and doesn’t really bring anything to the party.
Programming strictly in C here, and with MQX for those OS geeks out there.
Although all the info is interesting, and given me a whole wealth of internet browsing to do, I’m not sure I’m any further forward. So how about a little example…
Looking at switch debounce. High priority task task_debounce, runs every 25mS, looks at the inputs lines and sets up rising edge stores in an OS provided event construct. Simple so far. Now, low priority task task_user_interface, occasionally looks for a rising edge. When it sees one, it updates some display things, and then wants to reset the rising edge event, sit back and wait for the next one.
So the question is, what would best practice be to reset the rising edge event?
1.Being a hardcore firmware engineer, my first thought is to disable interrupts, read/clear/write the event store, enable ints. Obviously not the way to go with an OS.
2.Maybe grab a semaphore, to gain exclusive access to the rising edge store. Then I have to worry about task_debounce not having access.
3.Send a message to task_debounce? What then happens if another task reads the stores in the mean time.
4.expect there are an infinite number of other methods…
GrahamSFull MemberFrom your description my approach would be a bit of layered architecture and hardware abstraction there.
I’d have a “driver” for the switch which handled the debounce etc and could provide the appropriate signals to the other tasks (via events, semaphores or some other method).
That also means you can then swap in a fake switch stub/mock when you need to do some unit testing.
UrbanHikerFree MemberAh, OK. So your saying that the “driver” should push the information out to things. I think this is where my lack of experience bites me. Something like this…
task_user_interface generally just blocks, waiting for any rising edge. Then task_debounce unblocks it when the rising edge occurs?
GrahamSFull MemberDon’t know your system obviously, but typically I’d expect to write a button driver which handled the debounce for me. Normally that wouldn’t poll, instead it would have a interrupt service routine which would triggered on any edge change and would start/reset a timer.
If that timer expires before another edge change then we have a proper debounced event to be communicated to the outside world via whatever mechanism you are using (event queue, semaphore etc).
The topic ‘Any firmware engineers here?’ is closed to new replies.