Common Functions in VxWorks Programming

WeChat Official Account: North South North There is a path through the mountains, diligence is the way; the sea of learning is endless, skillful craft is the boat!

1. Official Program Guide

Located in the installation directory: \docs\vxworks\guide\index.html

2. Common Libraries:

#include "taskLib.h" /* Task */ 
#include "msgQLib.h" /* Message Queue */ 
#include "semLib.h" /* Semaphore */ 
#include "ioLib.h" /* IO */ 
#include "wdLib.h" /* Watchdog */ 
#include "logLib.h" /* Log Output */ 
#include "socket.h" /* Network Socket */

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 setting operations, and finally close the descriptor.

  • creat: Create a file

  • open: Obtain the descriptor for 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 Files

  • memDrv( ) – Initialize pseudo memory device

  • memDevCreate( ) – Create pseudo memory device

  • memDevCreateDir( ) – Create a group of pseudo memory devices

  • memDevDelete( ) – Delete 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 Listening with Select Function: selectLib.h

When waiting for multiple IOs, we can use the Select function, where fd is the file descriptor:

int select( 
    int width, /* Maximum fd, or directly FD_SETSIZE (2048) */ 
    fd_set * pReadFds, /* Set of read fds */ 
    fd_set * pWriteFds, /* Set of write fds */ 
    fd_set * pExceptFds, /* Not supported by vxWorks, NULL */ 
    struct timeval * pTimeOut /* Wait time, NULL = forever */ 
) 

Several macros:

  • FD_SET(fd, &fdset) Set the listening bit for fd

  • FD_CLR(fd, &fdset) Clear the listening bit for fd

  • FD_ZERO(&fdset) Clear all listening bits

  • FD_ISSET(fd, &fdset) Check 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(..); /* Open IO */ 
width = MAX(fds[0], … … , fds[3])+1; /* Max fd +1 */ 
/* FOREVER {*/ 
FD_ZERO(&readFds); /* Set fd_set structure */ 
FD_SET(fds[0], & readFds);… …; FD_SET(fds[3], & readFds); 
if (select(width, &readFds, NULL, NULL, NULL) == ERROR) { /* Listen */ 
close(fds[0]); … …; close(fds[3]); 
return; 
} 
for(i=0; i<width; i++) 
if (FD_ISSET(fds[i], &readFds)) { 
… …; /* Perform read/write operations */ 
} 
} 
/* } */ 
}

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 already initialized task

  • exit( ) – End in a task (ANSI)

  • taskDelete( ) – Delete a task

  • taskDeleteForce( ) – Force deletion, 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( ) – Disable task scheduling

  • taskUnlock( ) – Enable task scheduling

  • taskSafe( ) – Protect task from deletion

  • taskUnsafe( ) – Remove protection

  • taskDelay( ) – Delay

  • taskIdSelf( ) – Get current task ID

  • taskIdVerify( ) – Verify 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 task TCB

  • taskRegsSet( ) – Set register information in task TCB

  • taskName( ) – Get task name

  • taskNameToId( ) – Get ID from name

  • taskIdDefault( ) – Set default task ID

  • taskIsReady( ) – Check if task is ready

  • taskIsSuspended( ) – Check if task is suspended

  • taskIdListGet( ) – Get list of active tasks

2. Task Mutual Exclusion – Semaphore: semLib.h

  • semGive( ) – Release a semaphore

  • semTake( ) – Acquire 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 is often used for task synchronization.

2) Mutex Semaphore: semMCreate is specifically used for mutual exclusion of tasks, protecting critical resources.

3) Counting Semaphore: semCCreate is for access control of multi-instance resources.

3. Task Synchronization

1) Message Queue: msgQLib.h Message Queue

  • msgQCreate( ) – Create a message queue

  • msgQDelete( ) – Delete a message queue

  • msgQSend( ) – Send a message

  • msgQReceive( ) – Receive a message, blocks after calling

  • msgQNumMsgs( ) – Get the number of messages in the queue

Init() { 
/* Create message queue */ 
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); /* Here the task will block */ 
printf("Received from msgq: %c ", ch); 
} 

2) Pipe: ioLib.h, the system defaults to include the pipe driver component

  • pipeDevCreate( ) – Create a pipe

  • pipeDevDelete( ) – Delete a pipe

Since the pipe belongs to IO, it can use Select for listening, while the message queue cannot use Select.

Init() { 
/* Create pipe */ 
if (pipeDevCreate("/pipe/mypipe", 8, 1) != OK) { 
printf("/pipe/mypipe create failed!\n"); 
} 
/* Create mutex semaphore */ 
if ((semMID = semMCreate(SEM_Q_FIFO)) == NULL) 
{ 
printf("Mutex semaphore create failed!\n"); 
} 
} 
taskSend() { 
int pd; /* Pipe descriptor */ 
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; /* Pipe descriptor */ 
uchar_t ch; 
if ((pd = open("/pipe/mypipe", O_RDONLY, 0644)) == ERROR) { 
printf("Open pipe failed!"); 
} 
if (read(pd, &ch, 1) > 0) { /* Here the task will block */ 
printf("Received from pipe: %c", ch); 
} 
} 

3) Binary Semaphore

Init() { 
/* Create binary semaphore */ 
if ((semBID = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL) { 
printf("Binary semaphore create failed!\n"); 
} 
} 
taskSend() { 
semGive(semBID); 
} 
taskReceive() { 
semTake(semBID, WAIT_FOREVER); /* Here the task will block */ 
} 

4) Events: eventLib Send events to specify the target task ID

  • eventReceive( ) – Wait for an event

  • eventSend( ) – Send an event

  • eventClear( ) – Clear the current task’s event.

taskSend() { 
if (OK != eventSend(taskReceiveID, 0×00000001)) { 
printf("Event send failed!"); 
} 
} 
taskReceive() { 
UINT32 Ev; 
if (OK != eventReceive(0×00ffffff, EVENTS_WAIT_ANY, WAIT_FOREVER, &Ev)) { 
printf("eventReceive Error!\n"); 
} 
else { 
Ev &= 0×00000001; 
if (Ev) { 
printf("Event %d received!", Ev); 
} 
} 
}

5. Watchdog: wdLib.h

The system provides a soft watchdog timer, which is also easy to use:

  • wdCreate( ) – Create a watchdog

  • wdDelete( ) – Delete

  • wdStart( ) – Start

  • wdCancel( ) – Stop

Init() { 
/* Create watchdog */ 
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 Use standard BSD sockets to communicate using TCP or UDP protocols.

  • socket( ) – Open a socket

  • bind( ) – Bind to port, address, etc.

  • listen( ) – Listening mode

  • accept( ) – Allow the other party’s connection

  • connect( ) – Actively connect to a remote

  • 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 Number: errnoLib.h

32-bit signed integer, 1~500 are reserved by the system, others are available for internal programs. For example:

#define MEMORY_LEAK 0×20005 
  • errnoGet( ) – Get current task’s error number

  • errnoOfTaskGet( ) – Get specified task’s error number

  • errnoSet( ) – Set current task’s error number

  • errnoOfTaskSet( ) – Set 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 a specified task

task1() { 
signal(30, proc_sig); /* Register signal number 30 */ 
/* raise(30); */ 
} 
task2() { 
kill(task1ID, 30); 
} 
void proc_sig(int param) { 
logMsg("Error message…"); 
}

8. Interrupts: iv.h

x86 interrupts 0×0~0xf correspond to vxWorks interrupts 0×20~0×2f. Taking interrupt number 9 as an example: initialize the interrupt:

intConnect( INUM_TO_IVEC(9+0×20), Int9Handler, 0); /* Bind interrupt function */ 
sysIntEnablePIC(9); /* Enable interrupt number 9 */ 

Interrupt function prototype:

void Int9Handler(int Param); /* Note do not call blocking functions in interrupt functions */ 

Click “Read the original text” to access more VxWorks resources

Common Functions in VxWorks Programming

Leave a Comment