Viewing 26 posts - 1 through 26 (of 26 total)
  • Any firmware engineers here?
  • UrbanHiker
    Free 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.

    gofasterstripes
    Free Member

    uuuhhhhh… nothing on Slashdot or Stackexchange?

    This is beyond me, sorry.

    Flaperon
    Full Member

    I’m after some pointers

    0x3A24633A
    0x6875534C
    0x64D3322C

    You can have those for free.

    Fresh Goods Friday 696: The Middling Edition

    Fresh Goods Friday 696: The Middlin...
    Latest Singletrack Videos
    jwr
    Full Member

    I’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.

    gofasterstripes
    Free Member

    I think there’s a lot of mileage in graphics card programming, myself. HUMA etc.

    Jamie
    Free Member

    0x3A24633A
    0x6875534C
    0x64D3322C

    I don’t think that is intergra to his question.

    GrahamS
    Full Member

    Hello. 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.

    UrbanHiker
    Free Member

    Thanks 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.

    Burger
    Full Member

    Not 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 for some way off topic reading.

    UrbanHiker
    Free Member

    I’ve been on Jack Ganssle’s mailing list for years. Great stuff. Never thought of looking at his book review list. Good call.

    GrahamS
    Full Member

    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.

    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)

    UrbanHiker
    Free Member

    Thanks for all the input. I think even getting the correct phrasing for things has helped. Now looking into multi-threading…

    mrmonkfinger
    Free Member

    Been 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.

    GrahamS
    Full Member

    proper memory allocation

    Get you with your fancy memory allocation. 😀

    (we are typically not allowed to use the heap at all. Not one single byte.)

    mrmonkfinger
    Free Member

    I had to go with a metaphore that an app programmer would understand 😆

    chambord
    Free Member

    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.

    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.

    GrahamS
    Full Member

    If 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.

    chambord
    Free Member

    Destructors 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 🙂

    andytherocketeer
    Full Member

    not 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.

    chambord
    Free Member

    specially 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 🙂

    GrahamS
    Full Member

    hardest 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

    😉

    kcal
    Full Member

    been 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!

    UrbanHiker
    Free Member

    Ah, 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…

    GrahamS
    Full Member

    From 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.

    UrbanHiker
    Free Member

    Ah, 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?

    GrahamS
    Full Member

    Don’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).

Viewing 26 posts - 1 through 26 (of 26 total)

The topic ‘Any firmware engineers here?’ is closed to new replies.