Discussion Forum

Interrupt Service Routine (ISR) and os_mut_wait()

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Kris Zawada
Posted
6-Jul-2010 19:57 GMT
Toolset
ARM
New! Interrupt Service Routine (ISR) and os_mut_wait()

When ISR calls os_mut_wait() the processor generates an exception.

Is os_mut_wait() prohibited from being called from an ISR?

Read-Only
Author
Hans-Bernhard Broeker
Posted
6-Jul-2010 20:20 GMT
Toolset
ARM
New! RE: Interrupt Service Routine (ISR) and os_mut_wait()

Is os_mut_wait() prohibited from being called from an ISR?

It shouldn't be necessary to prohibit that. It's self-evident that it's a Very Bad Idea, Indeed(TM), to sit inside an ISR waiting for some other part of the system that can never be reached from this situation to release a Mutex.

Read-Only
Author
Kris Zawada
Posted
6-Jul-2010 20:33 GMT
Toolset
ARM
New! RE: Interrupt Service Routine (ISR) and os_mut_wait()

Then, what is a good way to share memory between the ISR and and lets say a get funtion?

There are two approaches that would work great. The first is a mutex mechanism. The second is turning off the interrupt source. In this case disabling the interrupt source would be the best because I don't know how os_mut_wait() is written. Is it written to disable interrupts?

The first example:

///< Global Counter
I32U Counter = 0;
///< Mutex used between ISR and Get function
OS_MUT mutex;


/**************************
* Initializes Values
**************************/
void Init(void)
{
        os_mut_init(mutex);
}

/**************************
* Returns Counter Value
**************************/
I32U GetCounter(void)
{
        I32U value;

        // Lock the mutex
        os_mut_wait(mutex);
        // Now, Get the value
        value = Counter;
        // Release the mutex
        os_mut_release();

        return value;
}

/**************************
* Returns Counter Value
**************************/
void TimerISR(void)
{
        // Lock the mutex
        os_mut_wait(mutex);

        // Now, change the value
        ++Counter;

        // Release the mutex
        os_mut_release();
}

The second example

///< Global Counter
I32U Counter = 0;

/**************************
* Returns Counter Value
**************************/
I32U GetCounter(void)
{
        I32U value;

        // Disable the timer
         TIMER = DISABLE;

        // Now, Get the value
        value = Counter;

        // Enable the timer again
        TIMER = ENABLE;

        return value;
}

/**************************
* Returns Counter Value
**************************/
void TimerISR(void)
{
        // Now, change the value
        ++Counter;
}
Read-Only
Author
Per Westermark
Posted
6-Jul-2010 22:31 GMT
Toolset
ARM
New! RE: Interrupt Service Routine (ISR) and os_mut_wait()

The "good" way is to use a ring buffer, where the ISR (producer) owns the write pointer and the main program (consumer) owns the read pointer.

Suddenly, you don't need any locking mechanisms unless your processor isn't able to perform atomic writes of the pointers.

You may decide to degenerate the ring buffer into a double-buffered approach too if you want.

But the ISR may never wait. It must always be able to go ahead - or must be delayed a clock cycle or two from entering - or must fail.

Read-Only
Author
IB Shy
Posted
7-Jul-2010 06:32 GMT
Toolset
ARM
New! RE: Interrupt Service Routine (ISR) and os_mut_wait()

"Is os_mut_wait() prohibited from being called from an ISR?"

Yes, it most definitely is.

Quote: "Functions that begin with os_ can be called from a task but not from an interrupt service routine."

http://www.keil.com/support/man/docs/rlarm/rlarm_ar_using_hints.htm

Next Thread | Thread List | Previous Thread Start a Thread | Settings