Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
LOSTISLAND
PostPosted: Jul 12, 2012 - 04:14 AM
Hangaround


Joined: May 05, 2010
Posts: 199


Imagine there is a common bus to drive TFT LCD , Analog Switches , LEDs ,Relays and so on .
This bus is protected by a mutex .
Now I think there are 4 ways to make use of this mutex . As an instance on TFT :
1- Use it in application layer
Code:
__GetBus
GLCD_DisplayString(0,0,Str);
__ReleaseBus

2- Use it in top functions
Code:
void GLCD_DisplayString (unsigned int ln, unsigned int col, char *s)
{
    __GetBus
    GLCD_WindowMax();
    while (*s)
    {
        GLCD_DisplayChar(ln, col++, *s++);
    }
    __ReleaseBus
}

3- Use it in medium functions
Code:
static __inline void wr_reg (unsigned char reg, unsigned short val)
{
    __GetBus
    LCD_CS(0)
    wr_cmd(reg);
    wr_dat(val);
    LCD_CS(1)
    __ReleaseBus
}

4- Use it in bottom functions
Code:
static __inline unsigned char lcd_send (unsigned short byte)
{
    __GetBus
    BUS_Direction(Output);
    LCD_DIR(1)
    LCD_EN(0)
    BUS_Write(byte);
    LCD_LE(1)                         
    LCD_LE(0)
    BUS_Write(byte >> 8);
    __ReleaseBus
    return(1);
}

Which of them is true ?
Thanks in advanced


Last edited by LOSTISLAND on Jul 12, 2012 - 04:30 AM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
LOSTISLAND
PostPosted: Jul 12, 2012 - 04:17 AM
Hangaround


Joined: May 05, 2010
Posts: 199


By the way how can I widen the page on my posts ?
Are there any other consideration on this issue ?
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Jul 12, 2012 - 05:26 AM
Raving lunatic


Joined: Dec 18, 2001
Posts: 4716


MUTEX only needed if you have a preemptive multitasking scheduler like FreeRTOS or a DIY scheduler.

For mutual exclusion with an interrupt service routine (ISR) and a program (non-ISR), without a preemptive RTOS, it's usually simpler to just disable interrupts for a few instructions.
 
 View user's profile Send private message  
Reply with quote Back to top
westfw
PostPosted: Jul 12, 2012 - 06:44 AM
Resident


Joined: Jun 19, 2002
Posts: 956
Location: SF Bay area

The idea is that you should hold the Mutex for 'short' periods of time. Unless GLCD_DisplayChar is very slow, I'd probably do it at that level rather than anything lower.
You also need to be sure that you wouldn't leave mid-level functions unprotected. For instance, I think doing the mutex in GLCD_DisplayString() would be a bad idea since there is a reasonable changce that GLCD_DisplayChar is used by users as well.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 12, 2012 - 10:14 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62304
Location: (using avr-gcc in) Finchingfield, Essex, England

To make the decision I'd want to understand more about the CPU overhead of mutex acquire/release. If it's microseconds do it at the lowest level just for the actually bus access. If it's milliseconds do it at the highest level as you don't want to do it 100 or 1,000 times during the printing of one string.

As for widening a thread so code samples don't wrap. Watch this (and apologies if it makes the thread TOO wide!):
Code:
===============================================================================

(the point being that in code blocks the forum software will not break adjacent '=' characters in order to word wrap).

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
LOSTISLAND
PostPosted: Jul 12, 2012 - 04:33 PM
Hangaround


Joined: May 05, 2010
Posts: 199


Cliff ,
Got a question ,
Imagine somewhere the Lowest level function is repeatedly invoked , for 1000 times as an instance , Now when 500 times the Mutex is got and then released , suddenly another task sees the mutex released and gets the mutex . That interrupt which may take a considerable time might cause problems . For that I'm worried of using a mutex in the lowest level functions even if the overhead is low .
Isn't that true ?
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jul 12, 2012 - 04:56 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62304
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Isn't that true ?

That depends on the device involved. If it's the case that once a long access operation has started it must complete and there cannot be long periods of inactivity or it might timeout then you are right - wrap the mutex at the highest level. The downside of doing it at the highest level is, of course, the opposite, this one operation now hogs the entire bus until it completes. So again the relative merits of each have to be weighed and things like timing/indivisibility and so on have to be weighed up. That's why there is no "right answer" for your original question. There are too many variables and you have to weigh the importance of each up to make a decision.

(this is a bit like thread priorities - if you have just 3 or 5 tasks it's often easy to weigh up the relative importance of the tasks and how high a priority each thing should have but I remember being involved in a project that had more than 100 tasks and 99 priority levels which gave an astronomical number of possible thread priority options and it actually became more of an art than a science with someone employed almost full time "tuning" the system for the best performance by trying to balance the priorities!)

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
LOSTISLAND
PostPosted: Jul 13, 2012 - 07:43 AM
Hangaround


Joined: May 05, 2010
Posts: 199


Thanks a lot
 
 View user's profile Send private message  
Reply with quote Back to top
lfmorrison
PostPosted: Jul 16, 2012 - 08:15 PM
Raving lunatic


Joined: Dec 08, 2004
Posts: 4719
Location: Nova Scotia, Canada

If preemption is a possibility, then think about what would happen if you got preempted in each situation. Specifically, consider your third case, if you failed to include the mutex protection at that level:
Code:
static __inline void wr_reg (unsigned char reg, unsigned short val)
{
    LCD_CS(0)
    wr_cmd(reg);
    wr_dat(val);
    LCD_CS(1)
}


If you managed to assert the LCD chip select, but you were preempted before you managed to send all the relevant data, then is there a possibility that some other task may step in, assert a different chip select to access a different peripheral on the same bus, and both devices might end up receiving scrambled data?

The MINIMUM level for your mutex must be chosen to ensure that you are effectively protected from preemption causing the transmission to be broken up in a way that leads to data corruption. If you choose any level lower than that, then your mutex won't be doing its job.

You are, of course, free to place the mutex at a HIGHER position if you so choose, keeping in mind the trade-off that higher levels will lead to longer waits for any of your other, higher-priority peripherals.
 
 View user's profile Send private message  
Reply with quote Back to top
stevech
PostPosted: Jul 17, 2012 - 04:16 AM
Raving lunatic


Joined: Dec 18, 2001
Posts: 4716


MUTEXES with preemption in task scheduling is subject to timing/race conditions that are rare and almost impossible to cure by debugging. Read about "priority inversion". They have to be avoided by DESIGN. Or better, avoid using them at all costs:

For mutual exclusion with an interrupt service routine (ISR) and a program (non-ISR), without a preemptive RTOS, it's usually simpler to just disable interrupts for a few instructions.
 
 View user's profile Send private message  
Reply with quote Back to top
jayjay1974
PostPosted: Jul 17, 2012 - 11:14 AM
Raving lunatic


Joined: Oct 30, 2002
Posts: 5720
Location: The Netherlands

Even better...

* Store current interrupt enable status
* Disable interrupts
* Do work
* Restore from previously stored status

This way you never unintentionally reenable interrupts, if you happen to nest calls.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits