0
\$\begingroup\$

I am programming the code for a LM4F120 Stellaris Launchpad, and I need a method to activate a software interrupt when the value of a particular variable exceeds a predefined threshold value. When the value gets lower than the threshold value, the interrupt should be disabled.

For example, the variable name is flag and the threshold value is 200. Whenever flag gets above 200, the interrupt should be activated. Whenever flag gets below 200 again, the interrupt should be disabled.

How can I implement such a thing?

\$\endgroup\$
  • \$\begingroup\$ Thank you all... Thanks for your guidance. I'll implement all suggestions specially the suggestion of Scott Seidman. Actually in code I want to make a very quick responsive method for the stability of the device using IMU (Inertial Measurement Unit) and my task is not to waste even a 1 micro second while gaining that stability... I need to create a strict lines for the variables which are irregular with respect to time... I think Class or Structures can be the option (using the public and private section properly)... Or if any other option which can make the device quick will be better to foll \$\endgroup\$ – Jigar4Electronics Apr 2 '13 at 17:03
  • \$\begingroup\$ You should either Edit your question or Post as comment! \$\endgroup\$ – Swanand Apr 2 '13 at 18:59
  • \$\begingroup\$ Sounds like a plan. The only other advice I can offer is to really read the docs for your IMU extremely carefully. Some of these guys are very sophisticated, and you might be able to get the IMU itself to output a signal that you can interrupt on. For example, I'm using and accelerometer that fills a buffer and then throws a line low when the buffer is full that I use to trigger an interrupt. \$\endgroup\$ – Scott Seidman Apr 2 '13 at 19:44
3
\$\begingroup\$

Two ways I can think of.

The first may not work. Send a copy of your variable in to a timer register, and fake things to make it look like the timer register rolls over when it reaches the value in question, and that might throw a timer interrupt.

The second would work, but may not meet all your needs. Use the test value of your variable to output a digital bit, and loop that back to a pin that can trigger an interrupt on change.

Both methods require some handling when the variable values change.

Frankly, by your description, it doesn't sound to me like you need an interrupt, but maybe a case structure in your program. Interrupts aren't "active" or "inactive". They happen, then they're done. If you mean you'd like to enable an interrupt based on some decision, that's real easy on every platform I've seen, and just involves setting the right bits in the right register at the right time.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ +1 for the creative use of a counter module. As far as I can see this is the only solution offered that does not require extra software or external hardware. (Why was it downvoted??) \$\endgroup\$ – Wouter van Ooijen Apr 2 '13 at 16:58
5
\$\begingroup\$

If you want assignments to variables to have additional behaviors besides just overwriting th value, you have to add a little bit of abstraction. Wrap accesses to the variable with a functional interface.

E.g.

static th;

void set_th(int new_th)
{
   int old_th = th;
   th = new_th;
   if (old_th <= 200 && new_th > 200)
   { /* enable interrupt */ }
   else if (old_th > 200 && new_th <= 200)
   { /* disable interrupt */ }
}

int get_th(void)
{
   return th;
}

In some languages like C++, you can achieve the syntactic sugar so that actual assignment syntax to a variable triggers a function call. You write th = 42, where th is an object of class type, and the compiler actually generates th.set(42) (or that is the concept, anyway). Of course the set member function is user-defined, just like the plain C function set_th above.

You may also be able to program the machine itself to respond to the update of a memory location. That is to say, you can make the machine trigger an interrupt when a variable is updated. That can be done with a hardware watchpoint (normally used for debugging). Using a hardware watchpoint for this kind of thing is a huge hack, and could only be justified by the need to reduce the cycles to absolute minimum. I.e. you don't want to call a function to update the variable because of the overhead.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This is the approach I'd take too. If your CPU supports it, you could force the interrupt manually in set_th(). \$\endgroup\$ – John U Apr 2 '13 at 8:46
  • \$\begingroup\$ Can't we trigger the interrupt without checking the variable values??? my question was whenever the value goes higher than threshold it should be trigger the interrupt. I don't want to check it all the time... \$\endgroup\$ – Jigar4Electronics Apr 2 '13 at 9:49
  • \$\begingroup\$ @Jigar You wouldn't be checking it all the time, just when you update it. Is there a reason for avoiding the comparison in software? It may actually have a faster reaction time than generating an interrupt. \$\endgroup\$ – apalopohapa Apr 2 '13 at 11:40
  • \$\begingroup\$ Also, note that you don't necessarily need get_th. It exists for completeness so the variable is completely abstracted. If get_th really just returns the value of the variable, it can be inlined, so it has no overhead compared to an expression that accesses the variable directly. \$\endgroup\$ – Kaz Apr 2 '13 at 17:15
2
\$\begingroup\$

I've never used the Stellaris ARM series specifically but one approach would be to leave the timer running all the time and simply enable and disable the interrupt, for example something like the following:

if (Th > 200)
    ROM_IntEnable(INT_TIMER0A);
else
    ROM_IntDisable(INT_TIMER0A);

Leaving the timer running will have some effect on power consumption but I'd only worry about that if your application is power critical running off small batteries for example.

If that's the case you can just do just pretty much the opposite of how you enable the timer by replacing ROM_SysCtlPeripheralEnable with ROM_SysCtlPeripheralDisable etc to shut everything back down, and re-initialize when the level goes back up above the value.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Can't we trigger the interrupt without checking the variable values??? my question was whenever the value goes higher than threshold it should be trigger the interrupt. I don't want to check it all the time... \$\endgroup\$ – Jigar4Electronics Apr 2 '13 at 9:50
  • \$\begingroup\$ @Jigar4Electronics, that part wasn't clear in your question, but the usual way would be just to put an if statement in your ISR so it just returns and does nothing. If you really need to disable for them for maximum performance maybe Kaz's idea of using hardware watchpoints would be good, but that will be very device dependent and I'm not sure how you would do it with a Stellaris (assuming you can). \$\endgroup\$ – PeterJ Apr 2 '13 at 9:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.