原文
SCOM:Synchronized COMmunication module
使用的时候要包含:#include <scom.h>
使用的类型和常数
typedef struct SCOM_Attrs { /* SCOM object creation attributes */
Char dummy; /* no attributes at present */
} SCOM_Attrs;
typedef struct SCOM_Obj SCOM_Obj, *SCOM_Handle; /* SCOM object handle */
extern SCOM_Attrs SCOM_ATTRS; /* default SCOM creation attributes */
描述:这个模块在任务之间传送消息。它允许用户创建任意个异步的队列,并把消息发到这些队列中而且可以
从这些队列中读取消息。这些消息是任意大小的缓存区。
SCOM模块管理SCOM队列对象。每一个SCOM队列内部使用一个队列对象(QUE)和一个旗语对象(SEM)。在SCOM队列的
结构在SCOM模块中是私有的。应用程序不应该涉及到SCOM队列的对象。
一个队列可以拥有任意个消息,但是消息的第一个域必须是QUE_elem。如:
typedef struct ScomBufChannels {
QUE_Elem elem;
Sample *bufChannel[ NUMCHANNELS ];
} ScomBufChannels;
Let us look at a general case where some tasks A and B want to exchange messages. Tasks A
and B agree that A sends data of type MyMsg to B via SCOM queues named "scomA" for task
A, and "scomB" for task B. The following steps would occur:
SCOM 用到的函数:
? SCOM_init(). Initializes the module.
? SCOM_exit(). Ends use of the module.
? SCOM_create(). Creates a new SCOM queue object.
? SCOM_open(). Gets a reference to an existing SCOM queue object by name.
? SCOM_delete(). Deallocates and deletes an SCOM queue object.
? SCOM_putMsg(). Places SCOM message in an SCOM queue.
? SCOM_getMsg(). Receives SCOM message from an SCOM queue.
分析:
SCOM_create()得到SCOM队列的句柄。
Syntax scomQueue = SCOM_create(queueName, *attrs);
Parameters String queueName; /* Name of SCOM queue to create */
SCOM_Attrs *attrs; /* SCOM object attributes; only NULL supported */
Return Value SCOM_Handle /* handle of new SCOM queue */
上面的表描述了两个任务之间的通信。一旦一个线程建立了一个队列,那么我们就可以在另一个线程里通过SCOM_open()来通信。
例子:
定义:
SCOM_Handle objSCOMINToDIS[NUM_SCOM_OBJS_IN][2];
Ptr msgSCOMInToProc[NUM_SCOM_OBJS_IN];
在main()函数中
/*-------------------------------------------------------*/
/* create all SCOM and message objects */
/*-------------------------------------------------------*/
objSCOMINToDIS[0][0] = SCOM_create("IN1TODIS", NULL);
objSCOMINToDIS[0][1] = SCOM_create("DISTOIN1", NULL);
objSCOMINToDIS[1][0] = SCOM_create("IN2ATODIS", NULL);
objSCOMINToDIS[1][1] = SCOM_create("DISTOIN2A", NULL);
objSCOMINToDIS[2][0] = SCOM_create("IN2BTODIS", NULL);
objSCOMINToDIS[2][1] = SCOM_create("DISTOIN2B", NULL);
在采集线程1中:
FVID_Frame *capFrameBuf;
SCOM_Handle fromInput1toDIS,fromDIStoInput1;
/*打开SCOM模块*/
fromInput1toDIS = SCOM_open("IN1TODIS");
fromDIStoInput1 = SCOM_open("DISTOIN1");
/*申请一个空间*/
FVID_alloc(capChanCh1, &capFrameBuf);
while(1)
{
/*-----------------------------------------------------------*/
/* Send message to process task with pointers to captured frame*/
/*-----------------------------------------------------------*/
SCOM_putMsg(fromInput1toDIS, (FVID_Frame *)capFrameBuf);
/*-----------------------------------------------------------*/
/* Wait for the message from the process task */
/*-----------------------------------------------------------*/
SCOM_getMsg(fromDIStoInput1, SYS_FOREVER);
/*-----------------------------------------------------------*/
/* Capture a new frame. */
/*-----------------------------------------------------------*/
FVID_exchange(capChanCh1, &capFrameBuf);
}
采集线程2中:
FVID_Frame *capFrameBuf;
SCOM_Handle fromInput2atoDIS,fromDIStoInput2a;
/*打开SCOM模块*/
fromInput2atoDIS = SCOM_open("IN2ATODIS");
fromDIStoInput2a = SCOM_open("DISTOIN2A");
/*申请一个空间*/
FVID_alloc(capChanCh2a, &capFrameBuf);
while(1)
{
/*-----------------------------------------------------------*/
/* Send message to process task with pointers to captured frame*/
/*-----------------------------------------------------------*/
SCOM_putMsg(fromInput2atoDIS, (FVID_Frame *)capFrameBuf);
/*-----------------------------------------------------------*/
/* Wait for the message from the process task */
/*-----------------------------------------------------------*/
SCOM_getMsg(fromDIStoInput2a, SYS_FOREVER);
/*-----------------------------------------------------------*/
/* Capture a new frame. */
/*-----------------------------------------------------------*/
FVID_exchange(capChanCh2a, &capFrameBuf);
}
显示线程3中:
void tskVideoLoopback()
{
Int i;
SCOM_Handle fromInput1toDIS,fromDIStoInput1;
SCOM_Handle fromInput2atoDIS,fromDIStoInput2a;
SCOM_Handle fromInput2btoDIS,fromDIStoInput2b;
FVID_Frame *capFrameBuf;
FVID_Frame *disFrameBuf;
/*设置显示的行数*/
Int numLinesDis = EVMDM642_vDisParamsChan.imgVSizeFld1;
/*设置采集的行数*/
Int numLinesCap = SEEDVPM642_vCapParamsChan.fldYStop1 -
SEEDVPM642_vCapParamsChan.fldYStrt1+1;
/*判断是显示区域大,还是采集区域大,取其小者*/
Int numLines = (numLinesDis > numLinesCap) ? numLinesCap : numLinesDis;
/*设置采集像素数*/
Int numPixels = (SEEDVPM642_vCapParamsChan.fldXStop1 -
SEEDVPM642_vCapParamsChan.fldXStrt1+1)/2;
/*设置采集行的增量*/
Int capLinePitch = (SEEDVPM642_vCapParamsChan.fldXStop1 -
SEEDVPM642_vCapParamsChan.fldXStrt1+1)/2;
/*设置显示行的增量*/
Int disLinePitch = EVMDM642_vDisParamsChan.imgHSizeFld1;
// numLines *= 2; /* both fields */
/*打开SCOM模块*/
fromInput1toDIS = SCOM_open("IN1TODIS");
fromDIStoInput1 = SCOM_open("DISTOIN1");
fromInput2atoDIS = SCOM_open("IN2ATODIS");
fromDIStoInput2a = SCOM_open("DISTOIN2A");
fromInput2btoDIS = SCOM_open("IN2BTODIS");
fromDIStoInput2b = SCOM_open("DISTOIN2B");
/*申请一个空间*/
FVID_alloc(disChan, &disFrameBuf);
while(1)
{
/*-----------------------------------------------------------*/
/* Wait for the message from the process task to recieve new */
/* frame to be displayed. */
/*-----------------------------------------------------------*/
capFrameBuf = (FVID_Frame *)SCOM_getMsg(fromInput1toDIS, SYS_FOREVER);
/*将数据放入相应的显示缓冲区*/
for(i = 0; i < numLines; i ++)
{
DAT_copy(capFrameBuf->frame.iFrm.y1 + i * capLinePitch,
disFrameBuf->frame.iFrm.y1 + i * disLinePitch+352,
numPixels);
DAT_copy(capFrameBuf->frame.iFrm.cb1 + i * (capLinePitch >> 1),
disFrameBuf->frame.iFrm.cb1 + i * (disLinePitch >> 1)+172,
numPixels>>1);
DAT_copy(capFrameBuf->frame.iFrm.cr1 + i * (capLinePitch >> 1),
disFrameBuf->frame.iFrm.cr1 + i * (disLinePitch >> 1)+172,
numPixels>>1);
}
// DAT_wait(DAT_XFRID_WAITALL);
/*-----------------------------------------------------------*/
/* Wait for the message from the process task to recieve new */
/* frame to be displayed. */
/*-----------------------------------------------------------*/
capFrameBuf = (FVID_Frame *)SCOM_getMsg(fromInput2atoDIS, SYS_FOREVER);
/*将数据放入相应的显示缓冲区*/
for(i = 0; i < numLines; i ++)
{
DAT_copy(capFrameBuf->frame.iFrm.y1 + i * capLinePitch,
disFrameBuf->frame.iFrm.y1 + i * disLinePitch+720*287,
numPixels);
DAT_copy(capFrameBuf->frame.iFrm.cb1 + i * (capLinePitch >> 1),
disFrameBuf->frame.iFrm.cb1 + i * (disLinePitch >> 1)+360*287,
numPixels>>1);
DAT_copy(capFrameBuf->frame.iFrm.cr1 + i * (capLinePitch >> 1),
disFrameBuf->frame.iFrm.cr1 + i * (disLinePitch >> 1)+360*287,
numPixels>>1);
}
// DAT_wait(DAT_XFRID_WAITALL);
/*-----------------------------------------------------------*/
/* Wait for the message from the process task to recieve new */
/* frame to be displayed. */
/*-----------------------------------------------------------*/
capFrameBuf = (FVID_Frame *)SCOM_getMsg(fromInput2btoDIS, SYS_FOREVER);
/*将数据放入相应的显示缓冲区*/
for(i = 0; i < numLines; i ++)
{
DAT_copy(capFrameBuf->frame.iFrm.y1 + i * capLinePitch,
disFrameBuf->frame.iFrm.y1 + i * disLinePitch+720*287+352,
numPixels);
DAT_copy(capFrameBuf->frame.iFrm.cb1 + i * (capLinePitch >> 1),
disFrameBuf->frame.iFrm.cb1 + i * (disLinePitch >> 1)+360*287+172,
numPixels>>1);
DAT_copy(capFrameBuf->frame.iFrm.cr1 + i * (capLinePitch >> 1),
disFrameBuf->frame.iFrm.cr1 + i * (disLinePitch >> 1)+360*287+172,
numPixels>>1);
}
DAT_wait(DAT_XFRID_WAITALL);
CACHE_clean(CACHE_L2ALL,NULL,NULL);
/*-----------------------------------------------------------*/
/* Display the decoded frame. */
/*-----------------------------------------------------------*/
FVID_exchange(disChan, &disFrameBuf);
/*-----------------------------------------------------------*/
/* Send message to process task to continue */
/*-----------------------------------------------------------*/
SCOM_putMsg(fromDIStoInput1, NULL);/* loop forever */
/*-----------------------------------------------------------*/
/* Send message to process task to continue */
/*-----------------------------------------------------------*/
SCOM_putMsg(fromDIStoInput2a, NULL);/* loop forever */
/*-----------------------------------------------------------*/
/* Send message to process task to continue */
/*-----------------------------------------------------------*/
SCOM_putMsg(fromDIStoInput2b, NULL);/* loop forever */
}
}