SCOM:Synchronized COMmunication module 同步通讯机制

来源:互联网 发布:js 获取点击对象的id 编辑:程序博客网 时间:2024/05/22 04:39

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同步通讯机制 - zua3 - ぁ梦想★天空的博客

SCOM同步通讯机制 - zua3 - ぁ梦想★天空的博客

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同步通讯机制 - zua3 - ぁ梦想★天空的博客

例子:

定义:

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 */

}

}