首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > VxWorks >

谋求:taskSpawn( )函数 和semBCreate()函数详解

2013-01-08 
寻求:taskSpawn( )函数 和semBCreate()函数详解帮帮忙,哪位能告诉我这两个函数的作用,和其中各个参数的含

寻求:taskSpawn( )函数 和semBCreate()函数详解
帮帮忙,哪位能告诉我这两个函数的作用,和其中各个参数的含义与作用。
  我看了好久都不是很懂,谢谢大家了
[解决办法]
int taskSpawn
    (
    char          *name,        /*任务名*/
    int           priority,     /*任务优先级,vxWorks好像共255个,而且调度采用优先级抢占式,同优先级轮换式的调度方式*/
    int           options,      /*任务的一些特性,例如VX_SUPERVISOR_MODE0x0001                              OBSOLETE: tasks always in sup mode*/
    int           stackSize,    /* 需要申请堆栈的大小*/
    FUNCPTR       entryPt,      /*任务处理函数*/
    int           arg1,         /*任务处理函数需要的参数*/
    int           arg2,
    int           arg3,
    int           arg4,
    int           arg5,
    int           arg6,
    int           arg7,
    int           arg8,
    int           arg9,
    int           arg10 
    )

[解决办法]
SEM_ID semBCreate
    (
    int         options,  /*信号量的特性,例如信号量的阻塞队列类型为优先级优先行还是FIFO*/
    SEM_B_STATE initialState /* 信号量的初始状态:empty or full,用来同步或者资源互斥*/
    )
返回的值就是改信号量的ID,实际上就是指向信号量的指针啦
[解决办法]
taskSpawn:创建并激活任务,有点类似于VC下的启动线程函数:
int taskSpawn
  (
  char *name, /*你要创建的任务名:比如说task1,在Shell下可以用命令:i 来查看当前系统中所有的任务*/
  int priority, /*任务优先级,*/
  int options, /*一般为0*/
  int stackSize, /* 需要申请堆栈的大小*/
  FUNCPTR entryPt, /*回调函数,*/
  int arg1,        /*传递给处理任务回调函数所需要的参数*/
  int arg2,
  int arg3,
  int arg4,
  int arg5,
  int arg6,
  int arg7,
  int arg8,
  int arg9,
  int arg10  
  )
用法:
taskSpawn("CANR1", 230, 0, 1024*32, (FUNCPTR)RecvProc,cardNo,1,0,0,0,0,0,0,0,0);


/************************************************************************/


/* CAN板卡接收数据任务                                                  */
/* 参数: cardNo - CAN板卡序号,0表示第一块板卡,1表示第二块板卡           */
/*       portNo - 端口号,0表示第一端口,1表示第二端口                    */
/************************************************************************/
void RecvProc(int cardNo, int portNo)
{
CANMSG rece_msg;
int    ret = 0;
int    i   = 0;

memset(&rece_msg, 0, sizeof(CANMSG));

printf("Recv CAN(%d) task ok.\n",cardNo);

/* 置CAN控制器为正常工作模式*/
if(cardNo==0)
{
canNormalRun(portNo);
}
else
{
canNormalRun2(portNo);
}

while(1)
{
/************************************************************************/
/* 接收数据                                                             */
/************************************************************************/
if(cardNo==0)
{
ret = canReceiveMsg(portNo,&rece_msg);
}
else
{
ret = canReceiveMsg2(portNo,&rece_msg);
}

if(ret==1)
{
/* success */
printf("Receive Data: ");
    for(i = 0; i < rece_msg.dlen; i++)
{
printf("%d, ", rece_msg.data[i]);
}
printf("\n");
taskDelay(100);
}
else
{
//printf("No data.\n");
taskDelay(2);
}
}
}


[解决办法]
下面是我收集整理的:
13.1 二进制信号量实现互斥和同步
13.1.1 互斥的实现:
使用二进制信号量可以很方便的实现互斥,互斥是指多任务在访问临界资源时具有排他性。为使多个任务互斥访问临界资源,只需要为该资源设置一个信号量,相当于一个令牌,哪个任务拿到这个令牌即有权使用该资源。把信号量设为可用,然后将需要资源的任务的临界代码置于semTake()和SemGive()之间即可。注明:
互斥中的信号量与任务优先级的关系:任务的调度还是按照任务优先级进行,但是在使用临界资源的时候只有一个任务获得信号量,也就是说还是按照任务优先级来获得信号量从而访问资源。只有当前使用资源的任务释放信号量SemGive(),其他任务按照优先级获得信号量。 
信号量属性中的参数为:SEM_Q_PRIORITY。而且在创建信号量的时候必须把信号量置为满的SEM_FULL。即信号量可用。 
注:信号量属性指定任务阻塞在信号量后的各任务排队的队列类型?? 
(sem_q_priority?? 按照优先级排队?? 或者sem_q_fifo?? 按照先来先服务的顺序排队)?? ,sem_delete_safe安全删除属性,允许任务优先级安全倒置sem_inversion_safe? 
基本实现互斥模型:
SEM_ID? semMutex;semMutex = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
task(void)?????? 
{
semTake(semMutex,WAIT_FOREVER);//得到信号量,即相当于得到使用资源的令牌//临界区,某一个时刻只能由一个任务访问;
semGive(semMutex);

13.1.2 同步的实现:
??? 同步即任务按照一定顺序先后执行,为了实现任务A和B的同步,只需要让任务A和B共享一个信号量,并设初始值为空,即不可用,将semGive()置于任务A之后,而在任务B之前插入semTake()即可.说明:
还是讨论和优先级的关系。由于信号量初始化为空,不可用,所以可能使得优先级反转,即高优先级任务B在等待低优先级任务A释放信号量。只有执行了信号量释放语句semGive()后任务B得到信号量才能执行。 
属性参数的设置为SEM_Q_FIFO,SEM_EMPTY; 
实现模式参考:
SEM_ID semSync;semSync = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
taskA(void)
{
……….
semGive(semSync);??
 //信号量释放,有效。
}
taskB(void)
{
semTake(semSync,WAIT_FOREVER);?
 //等待信号量。


……..
}
使用信号量注意事项:
用途不同,信号量属性和初始值不同; 
互斥访问资源使,semTake()和semGive()必须成对出现,且先后顺序不能颠倒; 
避免删除那些其他任务正在请求的信号量。 
应用:
1、? 确保任务优先级不反转:
SEM_ID? semFs;
SEM_ID? semFss;
SEM_ID? semFex;
semFs = semBCreate (SEM_Q_FIFO , SEM_EMPTY);
semFss = semBCreate (SEM_Q_FIFO , SEM_EMPTY);
semFex = semBCreate (SEM_Q_FIFO , SEM_EMPTY);?
 //创建三个信号量
void t_imaGet(void){??? printf("a?? ";?? semGive(semFs);???????????? //释放信号量}

void t_imaJud(void)
{?? 
semTake(semFs,WAIT_FOREVER);???? //确保优先级不反转。
? printf("jj ";? 
semGive(semFss);
}

void t_imaPro(void)
{??? 
semTake(semFss,WAIT_FOREVER);???
 printf("rr";??? 
semGive(semFex);???
 }

void t_imaExc(void)
{???? 
semTake(semFex,WAIT_FOREVER);?
??? printf("Y";? 
}
void start(void)
{? 
int tGetId,tJudId,tProId,tExcId;? 
tGetId = taskSpawn("tPget",200,0,1000,(FUNCPTR)t_imaGet,1,0,0,0,0,0,0,0,0,0);????? tJudId = taskSpawn("tPjud",201,0,1000,(FUNCPTR)t_imaJud,3,0,0,0,0,0,0,0,0,0);? tProId = taskSpawn("tPpro",202,0,1000,(FUNCPTR)t_imaPro,3,0,0,0,0,0,0,0,0,0);? tExcId = taskSpawn("tPexc",203,0,1000,(FUNCPTR)t_imaExc,3,0,0,0,0,0,0,0,0,0);}
以上例子虽然定了各个任务的优先级,但加上信号量可以实现同步,而且防止优先级反转出现。


热点排行