I am tring to develop/port a device driver for a motor controller in linux.
I need help implementing a semaphore type of operation within the device driver.
My driver needs to communication with the board by passing characters strings
to the board & reading replys (if any). This operation needs to be
atomic on the process level. For example, if two process (A&B) are requesting
information, process A need to send , wait, read as a single operation
before process B is allowed to talk to the board.
So I need some sort of semephore facility in my device driver. Here is a
first cut at some code. If anyone has already done this, could you please
post/send me your code. I am just starting developing in linux and could
use some help! Thanks,
To use it, I would:
1. Initialize structure in the init() function:
struct sem_t sem;
sem->cnt = 1; /* only one resource available */
sem->wait_queue = NULL;
2. Whenever I need to 'talk' to my device:
sem_ret( &sem ); /* block until device is free */
. . . /* my code */
sem_ret( &sem ) /* free device for others */
3. Some source code is posted below.
I don't think it is perfect. In sem_get(), if multiple task
are waiting on a single queue, a call to sem_ret() will
wake them all up and the next one to get the 'resource' will
depend on the scheduler. (no guarantee FIFO). Other than this
is should work, I'll try to test it soon. Please comment.
Tony
Here the code:
struct sem_t {
int cnt; /* num of resources available */
struct wait_queue *wait_queue; /* wait queue when blocked */
/*************************************************************************Quote:};
** Semaphore-type blocking function
**
** sem_get( struct sem_t *sw) - will block until it is able to get
** a free resource.
** sem_ret( struct sem_t *sw) - return the resoruce & waits up any task
** blocked in sem_get().
**************************************************************************/
void sem_get( struct sem_t * sw )
{
int got_it; /* flag (T or F) to indicate when we grabbed the resoure */
/* loop until we are able to grab a resource */
got_it = 0;
do {
cli();
if( sw->cnt > 0 ) /* if resource available */
{
got_it = 1; /* set to true, to exit */
sw->cnt--; /* decrement to indicate we grabbed one */
}
sti();
/* didn't get one, lets sleep until someone free a resource */
if( !got_it )
interruptible_sleep_on( &sw->wait_queue );
} while ( !got_it );
void sem_ret( struct sem_t * sw )Quote:}
{
cli();
sw->cnt++; /* increment counter to 'return' resource */
sti();
/* wake up other waiting on resource */
wake_up_interruptible( &sw->wait_queue );
--Quote:}
Institute for Astronomy Phone: (808) 956-8101
2680 Woodlawn Drive,Honolulu, HI Fax: (808) 988-3893