Direct request is the simplest method used to request a semaphore. The request behaves as an atomic read and set operation. The result of a request is either to
grant the semaphore to the requesting core or deny the request because the semaphore has already been granted to another core.
A direct request is issued by reading the SEM_DIRECT register corresponding to the semaphore requested, there are 64 DIRECT registers, one corresponding to each
of the 64 semaphores. If the semaphore is free, the read returns “0x1”; if the request is rejected, the read returns the ID of the core that currently owns the semaphore.
No semaphore grant (SEMINTn) interrupts are generated when the direct request method is used. However, an error interrupt may be generated.
Direct Semaphore register:
There are 64 direct registers. Each one is associated with and used to manage the respective semaphore.
Direct Register (SEM_DIRECTn):
读与写该寄存器时,Free域的意义不同。
WaitHwSem :Waits until requested semaphore is free. Function is blocking, so it will wait until requested semaphore is free and calling EU is not suspended during
the wait time.
code:
#define HWSEM_DIRECT_REG_ADDRESS (volatile u32*)(0x02640100)
//0x02640100为
SEM_DIRECT0的地址,
SEM_DIRECTn的地址为
HWSEM_DIRECT_REG_ADDRESS
+n
u32
WaitHwSem(const u32 semId) //请求信号量
{
u32 retVal;
u32 semId;
volatile u32 reg;
retVal = NoError;
if( semId < 64) //64为硬件信号量
number
{
do
{
reg =*(HWSEM_DIRECT_REG_ADDRESS +semId); //读寄存器
} while ((reg &1) !=1);
}
else retVal = InvalidValue;
return retVal;
}
FreeHwSem :This function unlocks the semaphore. If there are other CPUs waiting the semaphore then thefirst
CPU(first-in-first-out)and EU waiting for the semaphore is allowed to return successfully from its call to WaitHwSem().
code:
volatile u32
DirectSEM[64]; //64个直接信号量
SEM_DIRECT0~63寄存器地址
u32 FreeHwSem(const u32 semId) //释放信号量
{
u32 retVal;
u32 semId;
retVal = NoError;
if(semId < 64) //64为硬件信号量
number
{
DirectSEM[semId] =
1; //写寄存器
}
else EHwSemRetVal_InvalidValue;
return retVal;
}
Direct semapore用法:
WaitHwSem(semId);
Access shared resource code;
//对于
Nyqusit来说,如果四个
CPU共享同一段内存,那么需要为该段内存
reserve一个硬
//件信号量semId
,当某个CPU访问这段内存的时候,需要采用类似的代码,用semId信号
//量进行保护共享内存,实现只允许同时只有一个
CPU在访问。
FreeHwSem(semId);