TI-RTOS Kernel User‘s Guide:4 Synchronization Modules

本章介绍同步访问共享资源的模块

4.1Semaphores

SYS/BIOS为基于信号量的任务间同步和通信提供了一组基本功能。信号量通常用于在一组相互竞争的任务之间协调对共享资源的访问。Semaphore模块提供Semaphore_Handle类型句柄访问的信号量对象的函数。信号量对象可以声明为计数或二进制信号量,也可以声明为简单(FIFO)或优先级感知信号量。信号量可用于任务同步和互斥。默认情况下信号量为简单的计数信号量。计数信号量保留了可用资源数量的内部计数,当count大于0时,任务在获取信号量时不会阻塞;信号量的计数值仅受16位计数器大小的限制。如果禁用断言,如果计数从最大16位值增加,则计数滚动而不通知。

semParams.mode = Semaphore_Mode_COUNTING;

二进制信号量最多协调两个任务对共享资源的访问,二进制信号量提供比计数信号量更好的性能。

semParams.mode = Semaphore_Mode_BINARY;

任务按照FIFO顺序等待简单计数和二进制信号量,而不考虑任务的优先级。创建“优先级”信号量,是在具有较低优先级的第一个任务之前将挂起的任务插入等待列表中。因此,同等优先级的任务按FIFO顺序等待,但高优先级的任务在低优先级的任务之前准备好。

semParams.mode = Semaphore_Mode_COUNTING_PRIORITY;
semParams.mode = Semaphore_Mode_BINARY_PRIORITY;

请注意,使用优先级信号量可能会增加系统中的中断延迟,因为在扫描等待信号量的任务列表以寻找适当的插入点时,中断将被禁用。一般来说,每个等待任务大约有12条指令。例如,如果有10个更高优先级的任务在等待,那么在新任务进入列表之前,所有10个任务都将被检查,并禁用中断。

函数Semaphore_create()和Semaphore_delete()分别用于创建和删除信号量对象,

Semaphore_Handle Semaphore_create( Int count, 
    Semaphore_Params *attrs,
    Error_Block *eb );
Void Semaphore_delete(Semaphore_Handle *sem);

信号量计数在创建时初始化为count。通常count设置为信号量正在同步的资源数量。Semaphore_pend()等待一个信号量。如果信号量计数大于0,Semaphore_pend()只是减少计数并返回,计数不大于0,,Semaphore_pend()将等待Semaphore_post()发送信号量。Semaphore_pend()的timeout参数,允许任务等待到超时,无限期等待(BIOS_WAIT_FOREVER),或者根本不等待(BIOS_NO_WAIT)。Semaphore_pend()的返回值用于指示信号量是否成功获取。

Bool Semaphore_pend( Semaphore_Handle sem, UInt timeout);

Semaphore_post()用于给信号量发信号。如果任务正在等待信号量,Semaphore_post()将从信号量队列中删除第一个任务,并将其放入就绪队列。如果没有任务在等待,Semaphore_post()只是增加信号量计数并返回。

Void Semaphore_post(Semaphore_Handle sem);

调用Semaphore_post()可能会导致在特定情况下重新启用硬件中断。

4.1.1Semaphore例子

例4-4提供了三个writer任务的示例代码,它们创建唯一的消息,并将它们放在一个reader任务的列表中。写入器任务调用Semaphore_post()来指示另一条消息已被放入列表中。reader任务调用Semaphore_pend()来等待消息。Semaphore_pend()仅当消息在列表中可用时返回。阅读器任务使用System_printf()函数打印消息。在这个示例程序中,三个写器任务、一个读器任务、一个信号量和一个队列是按如下方式静态创建的:

var Defaults = xdc.useModule('xdc.runtime.Defaults');
var Diags    = xdc.useModule('xdc.runtime.Diags');
var Error    = xdc.useModule('xdc.runtime.Error');
var Log      = xdc.useModule('xdc.runtime.Log');
var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
var Main   = xdc.useModule('xdc.runtime.Main');
var Memory = xdc.useModule('xdc.runtime.Memory')
var SysMin = xdc.useModule('xdc.runtime.SysMin');
var System = xdc.useModule('xdc.runtime.System');
var Text   = xdc.useModule('xdc.runtime.Text');

var BIOS  = xdc.useModule('ti.sysbios.BIOS');
var Clock = xdc.useModule('ti.sysbios.knl.Clock');
var Task  = xdc.useModule('ti.sysbios.knl.Task');
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
var Hwi   = xdc.useModule('ti.sysbios.hal.Hwi');
var HeapMem   = xdc.useModule('ti.sysbios.heaps.HeapMem');

/* set heap and stack sizes */
BIOS.heapSize = 0x2000;
Program.stack = 0x1000;
SysMin.bufSize = 0x400;

/* set library type */
BIOS.libType = BIOS.LibType_Custom;

/* Set logger for the whole system */
var loggerBufParams = new LoggerBuf.Params();
loggerBufParams.numEntries = 32;
var logger0 = LoggerBuf.create(loggerBufParams);
Defaults.common$.logger = logger0;
Main.common$.diags_INFO = Diags.ALWAYS_ON;

/* Use Semaphore, and Task modules and set global properties */
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
Program.global.sem = Semaphore.create(0);
var Task = xdc.useModule('ti.sysbios.knl.Task');
Task.idleTaskVitalTaskFlag = false;

/* Statically create reader and writer Tasks */
var reader = Task.create('&reader');
reader.priority = 5;
var writer0 = Task.create('
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值