Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


MCU - Threads changing global state


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 TheComet   Crossbones+   -  Reputation: 1640

Like
0Likes
Like

Posted 25 February 2014 - 11:14 AM

I'm programming a micro controller using C. There is a case when the voltage levels of the circuit become unstable and sink below a predefined threshold (for example when the device is unplugged). When this happens, an external interrupt is triggered to inform the micro controller about it, upon which all I/O modules need to immediately shut down.

 

I'd also like to have a function for polling if a power failure occurred.

 

What is the best way of doing this? Up until now I've always used a global variable to keep track of states, like in the following code:

// NOTE: bools are not supported
static volatile char power_failure = 1;

/*-------------------------------------------------------*/
void enable_sub_circuits( void )
{    /* configures modules and other things like that */
    if( successful )
        power_failure = 0;
}

/*-------------------------------------------------------*/
void disable_sub_circuits( void )
{
    power_failure = 1;
    /* shuts down all modules */
}

/*-------------------------------------------------------*/
char is_power_failure( void )
{
    return power_failure;
}

/*-------------------------------------------------------*/
void _ISR _INT0Interrupt( void )
{
    disable_sub_circuits();
}

_INT0Interrupt is triggered when the power failure occurs, and can be considered to be on a separate "thread", for those who aren't sure what an interrupt is.

 

Is this an acceptable way of doing this? The reason why I ask is, I've never really worked with threads before in my life, and since I've been learning about them recently, I've started to question my methods when handling interrupts on micro controllers.


YOUR_OPINION >/dev/null

Sponsor:

#2 ApochPiQ   Moderators   -  Reputation: 16382

Like
2Likes
Like

Posted 25 February 2014 - 11:55 AM

Interrupts and threading have a ... complex relationship, even on the most widely popular CPUs. On a microcontroller all bets are off, because the way the interrupt mechanism is implemented in silicon might have different semantics than you expect from, say, a thread running on an x86-compatible CPU. You also have to keep in mind that you have no OS between you to manage scheduling and transitions between execution contexts cleanly.

 

Your idea might work, depending on how the chip is built; but you have one critical flaw: if you're low on voltage, you can't guarantee that the MCU is even going to be able to tick over, let alone power anything beyond the watchdog interrupt. So you can write all kinds of code to poll on that variable and it has no promise that it will ever even get to run.



#3 blewisjr   Members   -  Reputation: 622

Like
0Likes
Like

Posted 25 February 2014 - 12:27 PM

Like Apoch said rather well you do have a major issue. In the mcu world you are interfacing with the transistors directly not a OS. If you hit power failure your code will not trigger. One of to things happens on power failure. If at really low power as in partial failure the chip is going to brownout. At total failure the chip is going to turn completely off so there is no longer a clock at all. In the case of brownout you need to trigger a interrupt to wake it up but if you are still in partial failure it will just brownout again. In the case of total failure once power is restored the chip is reset. In either case you will not be able to execute any instructions because you have no clock or a clock which only has enough omph to recognize the wake me up interrupt. There really is no way to oh shit save state unless it happen before the clock goes away.

You also have to note a interrupt is not a thread in any way shape or form. It is a full diversion. A micro can not multitask as it is a single core that processes liniarly. When a interrupt happens everything stops on the chip till it is processed. Minus the clock. So if in a interrupt and another interrupt happens you will miss the second one entirely it is not qeued up to happen next just skipped.

Edited by blewisjr, 25 February 2014 - 12:32 PM.


#4 TheComet   Crossbones+   -  Reputation: 1640

Like
0Likes
Like

Posted 25 February 2014 - 05:33 PM

The voltage source being monitored is a 12V source, and triggers the power failure when it goes below 11.2V. The micro controller is powered by 3.3V from a step-down converter, which gets its power from the 12V source.

 

I have a guaranteed ~50ms before the 12V source is low enough for the 3.3V source to begin failing, which is more than enough time to perform the necessary shutdowns. This has been measured and proven. There's really not much to do in the shutdown routine other than disable all ports and write a few bytes to an internal flash.

 

You also have to note a interrupt is not a thread in any way shape or form. It is a full diversion. A micro can not multitask as it is a single core that processes liniarly. When a interrupt happens everything stops on the chip till it is processed. Minus the clock. So if in a interrupt and another interrupt happens you will miss the second one entirely it is not qeued up to happen next just skipped. 

 

Correct, yes.

 

@all

I can confirm that the code does what it is intended to do, thanks for the input. I take it the code is acceptable?


YOUR_OPINION >/dev/null

#5 King Mir   Members   -  Reputation: 2050

Like
0Likes
Like

Posted 26 February 2014 - 04:26 AM

On a single core cpu, you know that there is nothing happening during execution, so you don't have all the pitfalls of multi-threading on a multi-core CPU. You can rely on sequential consistency. Interrupts are not in the language standard, so you're not in violation when you rely on their hardware specific properties like that. You do need volatile, because from the point of view of the rest of the program, your interrupt handler is an external event, but you don't need threading primitives.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS