1. Official Program Guide
Located in the installation directory: \docs\vxworks\guide\index.html
2. Common Libraries:
#include "taskLib.h"
#include "msgQLib.h"
#include "semLib.h"
#include "ioLib.h"
#include "wdLib.h"
#include "logLib.h"
#include "socket.h"
3. IO System: ioLib.h
1. The IO devices in the system, including keyboard, serial port, files, etc., are accessed through a unified interface. The first step is usually to obtain a file descriptor, then perform read/write or settings work, and finally close the descriptor.
create: create a file
open: obtain the descriptor of a file or device
read: read from a file or device
write: write to a file or device
ioctl: set parameters
close: close the file descriptor
remove: delete a file
2. Memory File
memDrv( ) – initialize a pseudo memory device
memDevCreate( ) – create a pseudo memory device
memDevCreateDir( ) – create a group of pseudo memory devices
memDevDelete( ) – delete a pseudo memory device
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. Implementing multiple IO monitoring through the Select function: selectLib.h
When waiting for multiple IO, we can use the Select function, where fd is the file descriptor:
int select(
    int width,
    fd_set * pReadFds,
    fd_set * pWriteFds,
    fd_set * pExceptFds,
    struct timeval * pTimeOut
)
Several macros:
FD_SET(fd, &fdset) sets the listening bit for fd
FD_CLR(fd, &fdset) clears the listening bit for fd
FD_ZERO(&fdset) clears all listening bits
FD_ISSET(fd, &fdset) checks if fd has data
Example, where MAX means taking the maximum value:
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<width; &readfds))="" (fd_isset(fds[i],="" ...="" ...;="" <="" code="" i++)="" if="" {="" }=""></width;>4. Programming in a Multi-task Environment:
1. Task Control: taskLib.h
taskSpawn( ) – create a task
taskInit( ) – initialize a task, user specifies stack and PCB address
taskActivate( ) – activate an initialized task
exit( ) – end in a task (ANSI)
taskDelete( ) – delete a task
taskDeleteForce( ) – force delete, even if protected
taskSuspend( ) – suspend a task
taskResume( ) – resume a suspended task
taskRestart( ) – restart a task
taskPrioritySet( ) – change task priority
taskPriorityGet( ) – read task priority
taskLock( ) – prohibit task scheduling
taskUnlock( ) – allow task scheduling
taskSafe( ) – protect task from deletion
taskUnsafe( ) – remove protection
taskDelay( ) – delay
taskIdSelf( ) – get the ID of the current task
taskIdVerify( ) – check if task ID exists
taskTcb( ) – get the address of the task control block (TCB)
taskOptionsSet( ) – change task options
taskOptionsGet( ) – get current task options
taskRegsGet( ) – get register information from the task TCB
taskRegsSet( ) – set register information in the task TCB
taskName( ) – get task name
taskNameToId( ) – get ID by name
taskIdDefault( ) – set default task ID
taskIsReady( ) – check if task is ready
taskIsSuspended( ) – check if task is suspended
taskIdListGet( ) – get the list of active tasks
2. Task Mutual Exclusion – Semaphore: semLib.h
semGive( ) – release a semaphore
semTake( ) – obtain a semaphore, will block
semFlush( ) – make all tasks blocked on this semaphore ready
semDelete( ) – delete a semaphore
1) Binary Semaphore: semBCreate
Can be used for task synchronization and mutual exclusion, but commonly used for task synchronization
2) Mutex Semaphore: semMCreate
Semaphore specifically for task mutual exclusion, protecting critical resources
3) Counting Semaphore: semCCreate
Access control for multi-instance resources
3. Task Synchronization
1) Message Queue: msgQLib.h
Message queue
msgQCreate( ) – create message queue
msgQDelete( ) – delete message queue
msgQSend( ) – send message
msgQReceive( ) – receive message, will block after calling
msgQNumMsgs( ) – get the number of messages in the message queue
Init() {
    if ((msgQID = msgQCreate(8, 1, MSG_Q_FIFO)) == NULL) {
        printf("Message queue create failed!\n");
    }
}
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) Pipe: ioLib.h, the system includes the pipe driver component by default
pipeDevCreate( ) – create pipe
pipeDevDelete( ) – delete pipe
Since pipes belong to IO, they can be monitored using Select, while message queues cannot.
Init() {
    if (pipeDevCreate("/pipe/mypipe", 8, 1) != OK) {
        printf("/pipe/mypipe create failed!\n");
    }
    if ((semMID = semMCreate(SEM_Q_FIFO)) == NULL) {
        printf("Mutex semaphore create failed!\n");
    }
}
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) Binary Semaphore
Init() {
    if ((semBID = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL) {
        printf("Binary semaphore create failed!\n");
    }
}
taskSend() {
    semGive(semBID);
}
taskReceive() {
    semTake(semBID, WAIT_FOREVER);
}
4) Events: eventLib
To send an event, specify the target task’s ID
eventReceive( ) – wait for an event
eventSend( ) – send an event
eventClear( ) – clear the current task’s event.
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!\n");
    } else {
        Ev &= 0x00000001;
        if (Ev) {
            printf("Event %d received!", Ev);
        }
    }
}
5. Watchdog: wdLib.h
The system provides a soft watchdog timer, which is also simple to use:
wdCreate( ) – create watchdog
wdDelete( ) – delete
wdStart( ) – start
wdCancel( ) – stop
Init() {
    if ((wdID = wdCreate()) == NULL) {
        printf("Watch dog create failed!\n");
    }
}
task() {
    if (OK != wdStart(wdID, sysClkRateGet()*5, proc_wd, 0)) {
        printf("Watch dog start failed!\n");
    }
}
int proc_wd(int param) {
    logMsg(... ...);
}
6. Network Programming: sockLib.h
Using standard BSD Socket, communicate using TCP or UDP protocol.
socket( ) – open socket
bind( ) – bind to port, address, etc.
listen( ) – listening mode
accept( ) – allow the other party’s connection
connect( ) – actively connect to the remote end
connectWithTimeout( ) – connect function with timeout feature
sendto( ) – send
send( ) – send
sendmsg( ) – send
recvfrom( ) – receive
recv( ) – receive
recvmsg( ) – receive
setsockopt( ) – set socket parameters
getsockopt( ) – get socket parameters
getsockname( ) – get socket name
getpeername( ) – get the name of the connected peer
shutdown( ) – close connection
7. Exception Handling
1. Error Numbers: errnoLib.h
32-bit signed integer, 1~500 is occupied by the system, others are available for programs. For example:
#define MEMORY_LEAK 0x20005
errnoGet( ) – get the current task’s error number
errnoOfTaskGet( ) – get the specified task’s error number
errnoSet( ) – set the current task’s error number
errnoOfTaskSet( ) – set the specified task’s error number
2. Signals: sigLib.h
signal( ) – specify the entry function for the signal
raise( ) – send a signal to the current task
kill( ) – send a signal to the specified task
task1() {
    signal(30, proc_sig);
}
task2() {
    kill(task1ID, 30);
}
void proc_sig(int param) {
    logMsg("Error message...");
}
8. Interrupts: iv.h
x86’s interrupts 0x0~0xf correspond to vxWorks’ interrupts 0x20~0x2f
Taking interrupt 9 as an example:
Initialize interrupt:
intConnect( INUM_TO_IVEC(9+0x20), Int9Handler, 0);
sysIntEnablePIC(9);
Interrupt function prototype:
void Int9Handler(int Param);
Explanation of takeSpawn and semCreate
int taskSpawn(
    char *name,        /* Task name */
    int priority,     /* Task priority, vxWorks seems to have a total of 255, and scheduling adopts priority preemption, with round-robin scheduling for the same priority */
    int options,      /* Some characteristics of the task, such as VX_SUPERVISOR_MODE  0x0001 OBSOLETE: tasks always in supervisor mode */
    int stackSize,    /* Size of stack to be allocated */
    FUNCPTR entryPt,  /* Task handling function */
    int arg1,         /* Parameters needed by the task handling function */
    int arg2,
    int arg3,
    int arg4,
    int arg5,
    int arg6,
    int arg7,
    int arg8,
    int arg9,
    int arg10
)
SEM_ID semBCreate(
    int options,  /* Characteristics of the semaphore, such as whether the blocking queue type of the semaphore is priority-based or FIFO */
    SEM_B_STATE initialState /* Initial state of the semaphore: empty or full, used for synchronization or resource mutual exclusion */
)
The returned value is the ID of the semaphore, which is actually a pointer to the semaphore.