Part Number:TMS320C6748Other Parts Discussed in Thread:SYSBIOS
example4-4 来自 bios user guide (SPRUEX3U) 4.1.1
代码:
/*.cfg*/ 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('&writer'); writer0.priority = 3; writer0.arg0 = 0; var writer1 = Task.create('&writer'); writer1.priority = 3; writer1.arg0 = 1; var writer2 = Task.create('&writer'); writer2.priority = 3; writer2.arg0 = 2; /* uses Queue module and create two instances statically */ var Queue = xdc.useModule('ti.sysbios.knl.Queue'); Program.global.msgQueue = Queue.create(); Program.global.freeQueue = Queue.create(); /* ======== semtest.c ======== */ #include <xdc/std.h> #include <xdc/runtime/Memory.h> #include <xdc/runtime/System.h> #include <xdc/runtime/Error.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Queue.h> #define NUMMSGS 3 /* number of messages */ #define NUMWRITERS 3 /* number of writer tasks created with */ /* Config Tool */ typedef struct MsgObj { Queue_Elem elem; /* first field for Queue */ Int id; /* writer task id */ Char val; /* message value */ } MsgObj, *Msg; Void reader(); Void writer(); /* The following objects are created statically. */ extern Semaphore_Handle sem; extern Queue_Handle msgQueue; extern Queue_Handle freeQueue; /* ======== main ======== */ Int main(Int argc, Char* argv[]) { Int i; MsgObj *msg; Error_Block eb; Error_init(&eb);msg = (MsgObj *) Memory_alloc(NULL, NUMMSGS * sizeof(MsgObj), 0, &eb); if (msg == NULL) { System_abort("Memory allocation failed"); }/* Put all messages on freeQueue */ for (i = 0; i < NUMMSGS; msg++, i++) { Queue_put(freeQueue, (Queue_Elem *) msg); } BIOS_start(); return(0); } /* ======== reader ======== */ Void reader() { Msg msg; Int i; for (i = 0; i < NUMMSGS * NUMWRITERS; i++) { /* Wait for semaphore to be posted by writer(). */ Semaphore_pend(sem, BIOS_WAIT_FOREVER); /* get message */ msg = Queue_get(msgQueue); /* print value */ System_printf("read '%c' from (%d).\n", msg->val, msg->id); /* free msg */ Queue_put(freeQueue, (Queue_Elem *) msg); } System_printf("reader done.\n"); } /* ======== writer ======== */ Void writer(Int id) { Msg msg; Int i;for (i = 0; i < NUMMSGS; i++) { /* Get msg from the free list. Since reader is higher * priority and only blocks on sem, list is never * empty. */ msg = Queue_get(freeQueue);/* fill in value */ msg->id = id; msg->val = (i & 0xf) + 'a'; System_printf("(%d) writing '%c' ...\n", id, msg->val); /* put message */ Queue_put(msgQueue, (Queue_Elem *) msg); /* post semaphore */ Semaphore_post(sem); }System_printf("writer (%d) done.\n", id); } /*result*/ (0) writing 'a' ... read 'a' from (0). (0) writing 'b' ... read 'b' from (0). (0) writing 'c' ... read 'c' from (0). writer (0) done. (1) writing 'a' ... read 'a' from (1). (1) writing 'b' ... read 'b' from (1). (1) writing 'c' ... read 'c' from (1). writer (1) done. (2) writing 'a' ... read 'a' from (2). (2) writing 'b' ... read 'b' from (2). (2) writing 'c' ... read 'c' from (2). reader done. writer (2) done.
#1 配置文件中,Program.global.sem = Semaphore.create(0); 说明信号量初始化为0?
#2 创建了三个writer,这三个task是按照顺序123执行的吗?还是说os没有“刻意”排序?
#3 信号量只是用来限制task的行为?
#4 如果用emaphore_pend(sem, BIOS_NO_WAIT);替换Semaphore_pend(sem, BIOS_WAIT_FOREVER);是不是就没有了限制效果?BIOS_NO_WAIT只是判断了一次信号量是否大于0?
#5 不是counting priority semaphore才会考虑task的优先级?这个信号量没有设置模式,默认的模式是simple counting。
Shine:
#1 是的。您可以看一下Semaphore.create函数的说明。https://www.ti2k.com/wp-content/uploads/ti2k/DeyiSupport_DSP_Semaphore.html 是的,这三个writer是同一个Priority的,所以会顺序执行。#3 信号量是一个同步机制,避免访问同一资源。#4 是的。上面的链接里有说明。
A timeout value of BIOS_WAIT_FOREVER causes the task to wait indefinitely for its semaphore to be posted.
A timeout value of BIOS_NO_WAIT causes Semaphore_pend to return immediately.#5 是的。
,
Owen Bao:
#5 从所给的结果来看,每次执行一次write,会紧跟着一个read,而没有继续下一次write,能否说明read插入了信号量的list?这个list我不是很理解,是在write的注释中提到的,这条注释也提到了reader的优先级更高,所以我猜测counting priority semaphore的优先级不是指task的优先级?/* Get msg from the free list. Since reader is higher and only blocks on sem, list is never empty. */。在guide里,提到了waiting list,我又有一个猜测是,对于本例子,list里只有reader,没有writer,所以reader才会紧跟writer执行?
,
Shine:
因为read的priority比writer priority高,所以当第一个writer写完数据后post一个semphore,reader收到这个semphore后打印信息,接着等待信号量。这是wait list里的第二个writer开始写数据后,接着post一个semphore,reader再去读。
,
Owen Bao:
var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');Program.global.sem = Semaphore.create(0);
cfg里面设置信号量只有这两句,所以信号量模式默认是Semaphore_Mode_COUNTING,它也会考虑task优先级?那和Semaphore_Mode_COUNTING_PRIORITY的区别在哪?
,
Shine:
请看下面对Semaphore_Mode_COUNTING_PRIORITY参数的说明。For PRIORITY semaphores, the pending task will be inserted in the waiting list before the first task that has lower priority. This ensures that tasks of equal priority will pend in FIFO order.software-dl.ti.com/…/Semaphore.html