• 常用Vxworks编程API



    vxWorks编程API

     

    一、官方的Program Guide
    位于安装目录下:docsvxworksguideindex.html
    二、常用的库:
    #i nclude "taskLib.h"
    #i nclude "msgQLib.h"
    #i nclude "semLib.h"
    #i nclude "ioLib.h"
    #i nclude "wdLib.h"
    #i nclude "logLib.h"
    #i nclude "socket.h"

    三、IO系统:ioLib.h
    1、系统中的IO设备,包括键盘、串口、文件等,都用统一的接口访问。第一步通常先得到文件描述符,然后进行读写或者设置的工作,最后关闭该描述符。
    creat:建立文件
    open:得到文件或设备的描述符
    read:读文件或设备
    write:写文件或设备
    ioctl:设置参数
    close:关闭文件描述符
    remove:删除文件

    2、内存文件
    memDrv( ) - 初始化伪内存设备
    memDevCreate( ) - 建立伪内存设备
    memDevCreateDir( ) - 建立一组伪内存设备
    memDevDelete( ) - 删除伪内存设备

    Init() {
    uchar_t buffer[1024];
    int fd;
    memDrv( );
    memDevCreate("/mem/mem1", buffer, sizeof(buffer));
    if ((fd = open("/mem/mem1", O_RDWR, 0644)) != ERROR) {
    write(fd, &data, sizeof(data));
    ... ...
    close(fd);
    }
    memDevDelete("/mem/mem1");
    }

    3、通过Select函数实现多个IO监听:selectLib.h
    当等待多个IO时,我们可以使用Select函数,fd为文件描述符:
    int select(
    int width,
    fd_set * pReadFds,
    fd_set * pWriteFds,
    fd_set * pExceptFds,
    struct timeval * pTimeOut
    )
    还有几个宏:
    FD_SET(fd, &fdset) 设置fd的监听位
    FD_CLR(fd, &fdset) 清除fd的监听位
    FD_ZERO(&fdset) 清除所有监听位
    FD_ISSET(fd, &fdset) fd是否有数据
    例子,其中MAX意为取最大值:
    Init() {
    struct fd_set readFds;
    int fds[4];
    int width;

    fds[0] = open(..);... ...;fds[3] = open(..);
    width = MAX(fds[0], ... ... , fds[3])+1;

    FD_ZERO(&readFds);
    FD_SET(fds[0], & readFds);... ...; FD_SET(fds[3], & readFds);

    if (select(width, &readFds, NULL, NULL, NULL) == ERROR) {
    close(fds[0]); ... ...; close(fds[3]);
    return;
    }
    for(i=0; i
    if (FD_ISSET(fds[i], &readFds)) {
    ... ...;
    }
    }
    }

    四、多任务环境的编程:
    1、任务控制:taskLib.h
    taskSpawn( ) - 创建任务
    taskInit( ) -初始化任务,用户自己指定栈和PCB地址
    taskActivate( ) - 激活已经初始化的任务
    exit( ) - 在任务中结束 (ANSI)
    taskDelete( ) - 删除任务
    taskDeleteForce( ) - 强制删除,即使被保护
    taskSuspend( ) - 挂起任务
    taskResume( ) - 恢复挂起的任务
    taskRestart( ) - 重新启动任务
    taskPrioritySet( ) - 改变任务优先级
    taskPriorityGet( ) - 读取任务优先级
    taskLock( ) - 禁止任务调度
    taskUnlock( ) - 允许任务调度
    taskSafe( ) - 保护任务不被删除
    taskUnsafe( ) - 解除保护
    taskDelay( ) - 延时
    taskIdSelf( ) - 得到当前任务的ID
    taskIdVerify( ) - 任务ID是否存在
    taskTcb( ) - 得到任务控制块(TCB)的地址
    taskOptionsSet( ) - 改变任务选项
    taskOptionsGet( ) - 得到任务当前选项
    taskRegsGet( ) - 得到任务TCB中寄存器的信息
    taskRegsSet( ) - 设定任务TCB中寄存器的信息
    taskName( ) - 得到任务名称
    taskNameToId( ) - 由名称得到ID
    taskIdDefault( ) - 设置默认的任务ID
    taskIsReady( ) - 任务是否就绪
    taskIsSuspended( ) - 任务是否挂起
    taskIdListGet( ) - 得到活动的任务列表

    2、任务互斥 - 信号量:semLib.h
    semGive( ) – 释放一个信号量
    semTake( ) – 获取一个信号量,会阻塞
    semFlush( ) – 使所有阻塞在本信号量上的任务变为就绪状态
    semDelete( ) – 删除一个信号量
    1)二进制信号量:semBCreate
    可用于任务同步和互斥,但常用于任务同步
    2)互斥信号量:semMCreate
    专门用于任务互斥的信号量,保护临界资源
    3)计数信号量:semCCreate
    多实例资源的访问控制

    3、任务同步
    1)消息队列:msgQLib.h
    消息队列
    msgQCreate( ) - 创建消息队列
    msgQDelete( ) - 删除消息队列
    msgQSend( ) - 发送消息
    msgQReceive( ) - 接受消息,调用后阻塞
    msgQNumMsgs( ) - 得到消息队列中的消息数量

    Init() {
    if ((msgQID = msgQCreate(8, 1, MSG_Q_FIFO)) == NULL) {
    printf("Message queue create failed! ");
    }
    }

    taskSend() {
    if (OK != msgQSend(msgQID, "A", 1, NO_WAIT, MSG_PRI_NORMAL)) {
    printf("Message send failed!");
    }
    }

    taskReceive() {
    uchar_t ch;
    msgQReceive(msgQID, &ch, 1, WAIT_FOREVER);
    printf("Received from msgq: %c ", ch);
    }

    2)管道:ioLib.h,系统默认包含了pipe驱动组件
    pipeDevCreate( ) - 创建管道
    pipeDevDelete( ) - 删除管道
    由于管道属于IO,所以可以使用Select监听,消息队列不是IO,不能使用Select

    Init() {
    if (pipeDevCreate("/pipe/mypipe", 8, 1) != OK) {
    printf("/pipe/mypipe create fialed! ");
    }

    if ((semMID = semMCreate(SEM_Q_FIFO)) == NULL)
    {
    printf("Mutex semaphore create failed! ");
    }
    }

    taskSend() {
    int pd;
    if ((pd = open("/pipe/mypipe", O_WRONLY, 0644)) == ERROR) {
    printf("Open pipe failed!");
    }
    if (semTake(semMID, NO_WAIT) == ERROR) {
    printf("Pipe in use!");
    }
    write(pd, "a", 1);
    semGive(semMID);
    close(pd);
    }

    taskReceive() {
    int pd;
    uchar_t ch;
    if ((pd = open("/pipe/mypipe", O_RDONLY, 0644)) == ERROR) {
    printf("Open pipe failed!");
    }
    if (read(pd, &ch, 1)>0) {
    printf("Received from pipe: %c", ch);
    }
    }

    3)二进制信号量
    Init() {

    if ((semBID = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL) {
    printf("Binary semaphore create failed! ");
    }
    }

    taskSend() {
    semGive(semBID);
    }

    taskReceive() {
    semTake(semBID, WAIT_FOREVER);
    }

    4)事件:eventLib
    发送事件要指定目标任务的ID
    eventReceive( ) - 等待事件
    eventSend( ) - 发送事件
    eventClear( ) - 清除当前任务的事件.

    taskSend() {
    if (OK != eventSend(taskReceiveID, 0x00000001)) {
    printf("Event send failed!");
    }
    }
    taskReceive() {
    UINT32 Ev;
    if (OK!=eventReceive(0x00ffffff, EVENTS_WAIT_ANY, WAIT_FOREVER, &Ev)) {
    printf("eventReceive Error! ");
    }
    else {
    Ev &= 0x00000001;
    if (Ev) {
    printf("Event %d received!", Ev);
    }
    }
    }

    五、Watch dog :wdLib.h
    系统提供了软看门狗定时器,使用也简便:
    wdCreate( ) - 创建看门狗
    wdDelete( ) - 删除
    wdStart( ) - 启动
    wdCancel( ) - 停止


    Init() {
    if ((wdID = wdCreate()) == NULL) {
    printf("Watch dog create failed! ");
    }
    }
    task() {
    if (OK != wdStart(wdID, sysClkRateGet()*5, proc_wd, 0)) {
    printf("Watch dog start failed! ");
    }
    }
    int proc_wd(int param) {
    logMsg(... ...);
    }
    六、网络编程:sockLib.h
    使用标准的BSD Socket套接字,使用TCP或者UDP协议进行通讯。
    socket( ) - 打开套接字
    bind( ) - 与端口、地址等绑定
    listen( ) - 监听模式
    accept( ) - 允许对方的连接
    connect( ) - 主动与远端连接
    connectWithTimeout( ) - 超时功能的connect函数
    sendto( ) - 发送
    send( ) - 发送
    sendmsg( ) - 发送
    recvfrom( ) - 接收
    recv( ) - 接收
    recvmsg( ) -接收
    setsockopt( ) - 设定套接字参数
    getsockopt( ) - 得到套接字参数
    getsockname( ) - 得到套接字名称
    getpeername( ) -得到连接的对点的名称
    shutdown( ) - 关闭连接
    七、异常处理
    1、错误号:errnoLib.h
    32位有符号整数,1~500被系统占用,其他程序内可用。如
    #define MEMORY_LEAK 0x20005
    errnoGet( ) - 得到当前任务的错误号
    errnoOfTaskGet( ) - 得到指定任务的错误号
    errnoSet( ) - 设定当前任务的错误号
    errnoOfTaskSet( ) - 设定指定任务的错误号


    2、信号:sigLib.h
    signal( ) - 指定信号的入口函数
    raise( ) - 发送信号给当前任务
    kill( ) - 发送信号给指定任务


    task1() {
    signal(30, proc_sig);

    }


    task2() {
    kill(task1ID, 30);
    }
    void proc_sig(int param) {
    logMsg("Error message...");
    }


    八、中断:iv.h
    x86的0x0~0xf号中断对应vxWorks中0x20~0x2f号中断
    以9号中断为例:
    初始化中断:
    intConnect( INUM_TO_IVEC(9+0x20), Int9Handler, 0);
    sysIntEnablePIC(9);
    中断函数原型:
    void Int9Handler(int Param);





     takeSpawn与semCreate说明

    int taskSpawn
        (
        char          *name,        /*任务名*/
        int           priority,     /*任务优先级,vxWorks好像共255个,而且调度采用优先级抢占式,同优先级轮换式的调度方式*/
        int           options,      /*任务的一些特性,例如VX_SUPERVISOR_MODE	0x0001                               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,实际上就是指向信号量的指针啦


    部分函数详细说明

    1.taskSpawn 创建(产生并激活)新任务
    int taskSpawn
    (
    char *name,
    int priority,
    int options,
    int stackSize,
    FUNCPTR entryPt,
    int arg1,
    int arg2, int arg3,
    int arg4, int arg5,
    int arg6, int arg7,
    int arg8, int arg9,
    int arg10
    )
    函数运行成功返回任务ID号,否则为ERROR。
    任务可选项的几种模式如下表:
    名 称

    描 述
    VX_FP_TASK
    VX_NO_STACK_FILL
    VX_PRIVATE_ENV
    VX_UNBREAKABLE
    VX_SUPERVISOR_MODE
    0x8
    0x100
    0x80
    0x2
    运行带浮点的协处理器
    不使用0xee填充堆栈
    用私有环境运行任务
    断点失效
    用户任务常用值

    2.taskDelete 删除一个任务
    STATUS taskDelete
    (
    int tid
    )
    删除指定ID号的任务,并释放任务所占有的内存
    3.taskDelay 延迟任务
    STATUS taskDelay
    (
    int ticks
    )
    任务延迟为某一任务休眠一定时间提供了简单的处理方法,一般用于任务的周期性循环执行。当输入参数为NO_WAIT(其值为零)时,表示将所延迟的任务切换到同一优先级就绪队列的尾部。
    4.taskSuspend 任务悬置
    STATUS taskSuspend
    (
    int tid
    )
    5.taskResume 恢复任务
    STATUS taskResume
    (
    int tid
    )
    6.msgQCreate 创建并初始化消息队列
    #include <msgQLib.h>
    MSG_Q_ID msgQCreate
    (
    int maxMsgs,
    int maxMsgLength,
    int options
    )
    消息入列方式有两种:MSG_Q_FIFO 先进先出 ,按时间先后顺序考虑;MSG_Q_PRIORITY 按消息优先级考虑。
    7.msgQSend 向一消息队列发送消息包
    STATUS msgQSend
    (
    MSG_Q_ID msgQId,
    char * buffer,
    UINT nBytes,
    int timeout,
    int priority
    )
    该函数将长度为nBytes的缓冲区buffer消息包发向消息队列msgQId. 如果任务正在等待接收该消息队列的消息包,消息将立即被送到第一个等待的任务。如果没有任务等待此消息,消息包被保留在消息队列中。
    参数timeout指明:当消息队列已满时,等待消息队列有空间时所等待的时间。超过该时间还没空间可用的话,消息包被舍弃。它有两个特殊值:NO_WAIT(0)立即返回,不管消息包是否被发送;WAIT_FOREVER(-1)一直等待消息队列有空间可用。
    参数priority指明发送的消息的优先级,可能值有:MSG_PRI_NORMAL(0)正常优先级,将消息置于消息队列的尾部;MSG_PRI_URGENT(1)紧急消息,将消息置于消息队列的首部。
    8.msgQReceive 接收消息
    int msgQReceive
    (
    MSG_Q_ID msgQId,
    char * buffer,
    UINT maxNBytes,
    int timeout
    )
    该函数从消息队列msgQId接收消息,将其拷贝到最大长度为maxNBytes的缓冲区buffer。如果消息包长度超过maxNBytes,多余部分被舍弃。等待时间timeout有两个特殊值: NO_WAIT(0)立即返回;WAIT_FOREVER(-1)一直等待消息队列有消息可取。
    9.msgQDelete 删除一个消息队列
    STATUS msgQDelete
    (
    MSG_Q_ID msgQId
    )
    任何因发送或接收该消息队列的消息的任务都将解阻,并返回错误errno.
    10. wdCreate 创建看门狗定时器
    WDOG_ID wdCreate(void)
    11. wdStart 启动定时器
    STATUS wdStart

    WDOG_ID wdId,
    int delay,
    FUNCPTR pRoutine,
    int parameter

    12. wdCancel 取消一个当前工作的定时器
    STATUS wdCancel
    (
    WDOG_ID wdId
    )
    该函数只是让定时器的延迟值为零来取消其工作。
    13. wdDelete 删除定时器
    STATUS wdDelete
    (
    WDOG_ID wdId
    )
    14. semBCreate 创建并初始化二进制信号量
    SEM_ID semBCreate
    (
    int options,
    SEM_B_STATE initialState
    )
    信号量初始化状态值有两种:SEM_FULL(1)或SEM_EMPTY(0)。选项参数指明被阻塞任务的入列方式:基于优先级(SEM_Q_PRIORITY)和先进先出(SEM_Q_FIFO).
    15. semCCreate 创建并初始化计数信号量
    SEM_ID semCCreate
    (
    int options,
    int initialCount
    )
    选项参数指明被阻塞任务的入列方式:基于优先级(SEM_Q_PRIORITY)和先进先出(SEM_Q_FIFO).
    16. semGive 给出信号量
    STATUS semGive
    (
    SEM_ID semId
    )
    17. semTake 获得信号量
    STATUS semTake
    (
    SEM_ID semId
    int timeout
    )
    如果任务在规定时间内未得到信号量,函数semTake返回错误。等待时间值WAIT_FOREVER和NO_WAIT分别表示一直等待和不等待。
    18. semDelete 删除信号量
    STATUS semDelete
    (
    SEM_ID semId
    )
    该函数释放与此信号量相关的资源,所有等待此信号量的任务解阻。
    semMCreate( ) 分配并初始化一个互斥信号量


    semCCreate( ) 分配并初始化一个计数信号量


    semDelete( ) 终止一个自由的信号量


    semTake( ) 占有一个信号量


    semGive( ) 释放一个信号量


    semFlush( ) 解锁所有等待信号量的任务


    semBCreate( ), semMCreate( ), and semCCreate( )返回一个信号量ID作为其它后续任务使用该信号量的的句柄。当一个信号量被创建,它的队列(queue)类型就被确定。等待信号量的任务队列以优先级的高低排列(SEM_Q_PRIORITY),或者一先到先得的方式排列(SEM_Q_FIFO).


    ·         当一个Semaphore创建时,指定了任务队列的种类


    A.    semBCreat( SEM_Q_PRIORITY, SEM_FULL),   SEM_Q_PRIORITY 指明处于等待状态的任务在等待队列中以优先级的顺序排列


    B.    semBCreat(SEM_Q_FIFO,SEM_FULL),   SEM_Q_FIFO指明 处于等待状态的任务在等待队列中以先进先出的顺序排列


                            


    1.  二进制信号量(  binary) 


    Taking a Semaphore




     Giving a Semaphore







    互斥进程(Mutual Exclusion)


    互斥信号量有效的内锁对共享资源的进入,与屏蔽中断(disabling interrupts)和优先级锁定(preemptive locks)相比,二进制信号量将互斥的范围限制在仅与其有关的资源上。从技术上说,创建一个信号量来保护(guarding)资源。信号量初始化位可用的(FULL)。


    当一个Semaphore创建时,指定了这个semaphore是用在解决互斥还是用来同步任务


    A.    semBCreat( SEM_Q_FIFO, SEM_FULL) ,  SEM_FULL 指明用于任务间互斥.


    SEM_ID semMutex;


    semMutex = semBCreate (SEM_Q_PRIORITY, SEM_FULL);


        当一个任务要进入资源,首先要得到一个信号量(take that semaphore),只要有任务在使用这个信号量,其它的要进入资源的任务要停止执行(blocked from execution),当这个任务完成了对资源的使用,它会释放信号量,允许另一个任务来使用资源。


    semTake (semMutex, WAIT_FOREVER);


    . .  critical region, only accessible by a single task at a time .


    semGive (semMutex);





    同步协调进程(Synchronization)    


    B.    semBCreat(SEM_Q_FIFO,SEM_EMPTY),  SEM_EMPTY 指明用于任务间同步.


     


    #include "vxWorks.h"


    #include "semLib.h"


    SEM_ID syncSem;


     


    init ( int someIntNum )


    {


    intConnect (INUM_TO_IVEC (someIntNum), eventInterruptSvcRout, 0);


     


    syncSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY);


     


    taskSpawn ("sample", 100, 0, 20000, task1, 0,0,0,0,0,0,0,0,0,0);


    }


    task1 (void)


    { ...


    semTake (syncSem, WAIT_FOREVER);


     


    printf ("task 1 got the semaphore/n");


    ...


     


    }


    eventInterruptSvcRout (void)


    { ...


    semGive (syncSem);


     


    ...


    }


           semTake(semID,time out)--------有Semaphore空闲,就Take, 如果没有,由time out 定,超时则向下执行





    2.  互斥信号量


    互斥信号量是一个特殊的二进制信号量,设计用于优先级继承,安全删除和回归。


    互斥信号量的使用基本和二进制信号量是类似的。但有以下不同:


    ·         仅仅被用做互斥。


    ·         只能被使用它的任务释放.(It can be given only by the task that took it.)


    ·         ISR 不能释放它。


    ·         不能使用函数semFlush( )。


    优先级反转(Priority Inversion)


    优先级反转是指一个任务等待比它优先级低的任务释放资源而被阻塞,如果这时有中等优先级的就绪任务,阻塞会进一步恶化。优先级继承技术可用来解决优先级反转问题。







    Priority inversion arises when a higher-priority task is forced to wait an indefinite period of time for a lower-priority task to complete.


    优先级继承(Priority Inheritance)


    优先级继承可用来解决优先级反转问题。当优先级反转发生时,优先级较低的任务被暂时地提高它的优先级,使得该任务能尽快执行,释放出优先级较高的任务所需要的资源。


    Priority Inheritance







    The mutual-exclusion semaphore has the option SEM_INVERSION_SAFE, which enables a priority-inheritance algorithm. The priority-inheritance protocol assures that a task that owns a resource executes at the priority of the highest-priority task blocked on that resource. Once the task priority has been elevated, it remains at the higher level until all mutual-exclusion semaphores that the task owns are released; then the task returns to its normal, or standard, priority. Hence, the "inheriting" task is protected from preemption by any intermediate-priority tasks. This option must be used in conjunction with a priority queue (SEM_Q_PRIORITY).


    3.  计数信号量(Counting Semaphores)


    计数信号量是任务同步和互斥的另一种实现方式.计数信号量除了保留信号量被释放的次数以外和二进制信号量是一样的。每次信号量被释放(gaven)一次,计数增加;每次信号量被占用(taken)一次,计数减少;当计数减少为0时,要求得到信号量的任务被阻塞(blocked)。二进制信号量是如果一个信号量被释放,有一个任务阻塞等待,则这个任务就被unblock.而计数信号量如果一个信号量被释放,没有任务阻塞等待,则计数增加。这说明一个被释放两次的计数信号量可以被占用(taken)两次,没有阻塞。


    Counting semaphores are useful for guarding multiple copies of resources. For example, the use of five tape drives might be coordinated using a counting semaphore with an initial count of 5, or a ring buffer with 256 entries might be implemented using a counting semaphore with an initial count of 256. The initial count is specified as an argument to the semCCreate( ) routine.


    Counting Semaphore Example




    --------------------------------------------------------------------------------


     
     
    Semaphore Call
     Count after Call
     Resulting Behavior
     


    --------------------------------------------------------------------------------


     
     
    semCCreate( )  
     3
     Semaphore initialized with initial count of 3. 
     
    semTake( ) 
     2
     Semaphore taken. 
     
    semTake( ) 
     1
     Semaphore taken. 
     
    semTake( ) 
     0
     Semaphore taken. 
     
    semTake( ) 
     0
     Task blocks waiting for semaphore to be available. 
     
    semGive( ) 
     0
     Task waiting is given semaphore. 
     
    semGive( ) 
     1
     No task waiting for semaphore; count incremented. 
     


    --------------------------------------------------------------------------------


     
     
     
     








                消息队列(Message queues)


    现实的实时应用由一系列互相独立又协同工作的任务组成。信号量为任务间同步和联锁提供了高效机制。在VxWorks中,用于但一CPU任务之间通信主要(primary)的机制是消息队列。


    Full Duplex Communication Using Message Queues







    消息队列允许一定数量不同长度的消息进行排列。任何任务或中断服务程序(ISR)能够发送消息给消息队列。任何任务可以从消息队列接受消息。多任务可以从同意消息队列发送和接受消息。两个任务之间的全双工(Full-duplex)通信需要针对不同方向的两个消息队列。


    消息队列函数介绍   


    msgQCreate( )  创建斌初始化一个消息队列


    msgQDelete( ) 终止并释放一个消息队列


    msgQSend( )  发送一个消息到消息队列


    msgQReceive( ) 从消息队列接受一个消息


    消息队列是由函数msgQCreate (MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY)创建。它的参数MAX_MSGS指定了消息队列中可允许最多可以排列的消息数和每个消息允许的最大的字节数MAX_MSG_LEN。


    一个任务或中断服务程序(ISR)用函数msgQSend( )发送一个消息到消息队列。如果没有任务等待消息队列的消息,这个消息被添加消息缓存的队列里。如果某些任务已经在等待消息队列中的消息,消息立刻被传递给第一个等待的消息的任务。


    一个任务用函数msgQReceive( )从消息队列得到一个消息。如果消息队列缓存中有消息存在,第一个消息立刻出列并回到调用处(caller).如果没有消息存在,则任务(calling task)停止(blocks)并被添加到等待消息的任务队列中。这个等待的任务队列按照优先级或先进先出(FIFO)规则排列,这个规则有消息队列创建时所指定。


    等待时间限制(time out)


    msgQSend( ) 和 msgQReceive( )都有时间限制参数。当发送一个消息,如果消息队列缓存这时没有空间,这个参数指定允许等待的时间(ticks数),直到队列缓存有空间来接收消息。当接收消息时,如果消息队列没有消息,这个参数指定允许等待的时间(ticks数),直到消息队列有消息。







     




    #include "vxWorks.h"


    #include "msgQLib.h"


     




    #define MAX_MSGS (10)


    #define MAX_MSG_LEN (100)


     


    MSG_Q_ID myMsgQId;


     


    task2 (void)


        {


        char msgBuf[MAX_MSG_LEN];


     


       


        if (msgQReceive(myMsgQId, msgBuf, MAX_MSG_LEN, WAIT_FOREVER) == ERROR)


            return (ERROR);


     


       


        printf ("Message from task 1:/n%s/n", msgBuf);


        }


     


    #define MESSAGE "Greetings from Task 1"


    task1 (void)


        {


       


        if ((myMsgQId = msgQCreate (MAX_MSGS, MAX_MSG_LEN, MSG_Q_PRIORITY)) 


            == NULL)


            return (ERROR);


     


       


        if (msgQSend (myMsgQId, MESSAGE, sizeof (MESSAGE), WAIT_FOREVER,


                      MSG_PRI_NORMAL) == ERROR)


            return (ERROR);


        }





    管道(Pipes)


    管道对消息队列提供了一个可供选择的接口,VxWorks的I/O系统。管道是虚拟的I/O设备,由驱动pipeDrv管理。函数pipeDevCreate()创建一个管道设备,这个调用指定管道的名字,能被排列的最多的消息数,和每个消息允许的长度。


    status = pipeDevCreate ("/pipe/name", max_msgs, max_length);


    被创建的管道是一个通常命名(named)的I/O设备,任务能用标准的I/O函数打开,读,写管道,并能调用ioctl例程。当任务试图从一个空的管道中读取数据,或向一个满的管道中写入数据时,任务被阻塞。和消息队列一样,ISR可以向管道写入,但不能从管道读取。


    做为I/O设备,管道提供了消息队列所没有的重要特性,调用select()


     




  • 相关阅读:
    AX 2009 实现对display 方法过滤
    AX 2009实现数据验证方法
    AX 2009 实现outlook发送邮件并带多个附件
    AX 2009 销售订单导入导出
    Mixin技术与分布类编程
    关于python装饰器的总结
    作为软件工程师,你必须知道的20个常识
    Python装饰器基础语法总结
    如何成为一名黑客(转)
    python的对象和类
  • 原文地址:https://www.cnblogs.com/james1207/p/3290059.html
Copyright © 2020-2023  润新知