- 论坛徽章:
- 0
|
本帖最后由 machunleilei 于 2011-06-21 17:56 编辑
今天看到关于实现一些互斥的机制。以下是自己的一些拙见。
参考的是富士通样例上的程序实例,程序代码如下:
首先定义一个结构体
typedef struct {
int32_t Mode; /* Mode (0xff = unused) */
// volatile uint32_t CritSec; /* Critical Section */
uint32_t CritSec; /* Critical Section */
void (*IrqHandler)(uint32_t Ch); /* Driver Irq Handler */
} Mfs_INFO;
其中int32定义:typedef int int32_t;
typedef unsigned int uint32_t;
上面的结构体就是提供了互斥的基础数据结构,当然光有结构当然不行,还需要定义在这个数据结构上面的操作,写到这里不禁让我想到了管程这个概念。管程跟这个定义很像。
当然这里并不是用管程来管理互斥,而是采用strex和ldrex指令来实现对结构体操作的互斥。
首先定义了一系列操作:
关于是锁定了:
int32_t Mfs_Lock(uint32_t Ch);
这个函数的主要作用就是根据我们提供的整型变量当做一个索引在
static Mfs_INFO MfsInfo[] = {
/*{Mode,CritSec,IrqHandler}*/
/*0*/{0xff, 0, NULL},
/*1*/{0xff, 0, NULL},
/*2*/{0xff, 0, NULL},
/*3*/{0xff, 0, NULL},
/*4*/{0xff, 0, NULL},
/*5*/{0xff, 0, NULL},
/*6*/{0xff, 0, NULL},
/*7*/{0xff, 0, NULL},
};
这个结构体数组中找到相应的结构体,首先要判断这个结构体是否正在被互斥访问,如果是,就对其解锁,并再次对其加锁,如果加锁失败,则返回错误,否则成功返回。
接着就是函数:
void Mfs_UnLock(uint32_t Ch)
{
Mfs_INFO *p_info;
uint32_t dummy;
int32_t exc;
p_info = &MfsInfo[Ch];
do {
dummy = __LDREXW(&(p_info->CritSec));
if (dummy == 0) { /* Compiler warning */
/* Do nothing */
}
exc = __STREXW(0, &(p_info->CritSec));
} while (exc != 0);
}
首先要提的就是上面的两个用红色表示的函数其实就是strexw和ldrexw这两个指令的封装。
这个函数主要就是解锁,因为我们一旦对一个上面定义的结构体Mfs_INFO变量进行了加锁,那么这个变量中的CritSec变量就变成了1,而不是初始化的0.所以我们在这个函数实现中就可以看出将0赋给了CritSec变量,这不过这个赋值过程是原子操作,是不允许被打断的操作。
上面两个函数只是一个简单的将访问结构体变成了互斥访问了,具体到对这个结构体中的其他的成员的赋值当然要建立在互斥访问的基础上了。 |
|