VxWorks編程指南

來源:互聯網
上載者:User
vxWorks編程指南
linearg 發表於 2006-6-10 11:34:00

一、官方的Program Guide
位於安裝目錄下:/docs/vxworks/guide/index.html

二、常用的庫:
#i nclude "taskLib.h" /* 任務 */
#i nclude "msgQLib.h" /* 訊息佇列 */
#i nclude "semLib.h" /* 訊號量 */
#i nclude "ioLib.h" /* IO */
#i nclude "wdLib.h" /* Watch dog */
#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,或直接FD_SETSIZE (2048) */
fd_set * pReadFds, /* 讀的fd集合 */
fd_set * pWriteFds, /* 寫的fd集合 */
fd_set * pExceptFds, /* vxWorks不支援,NULL */
struct timeval * pTimeOut /* 等待時間, NULL = forever */
)
還有幾個宏:
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(..); /* 開啟IO */
width = MAX(fds[0], ... ... , fds[3])+1; /* fd的最大值+1 */
/* FOREVER {*/
FD_ZERO(&readFds); /* 設定fd_set結構 */
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!/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)管道:ioLib.h,系統預設包含了pipe驅動組件
pipeDevCreate( ) - 建立管道
pipeDevDelete( ) - 刪除管道
由於管道屬於IO,所以可以使用Select監聽,訊息佇列不是IO,不能使用Select

Init() {
/* 建立管道 */
if (pipeDevCreate("/pipe/mypipe", 8, 1) != OK) {
printf("/pipe/mypipe create fialed!/n");
}
/* 建立互斥訊號量 */
if ((semMID = semMCreate(SEM_Q_FIFO)) == NULL)
{
printf("Mutex semaphore create failed!/n");
}
}

taskSend() {
int pd; /* pipe的描述符 */
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的描述符 */
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!/n");
}
}

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!/n");
}
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!/n");
}
}

task() {
if (OK != wdStart(wdID, sysClkRateGet()*5, proc_wd, 0)) {
printf("Watch dog start failed!/n");
}
}

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); /* 註冊30號的訊號 */
/* raise(30); */
}

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); /* 使能9號中斷 */

中斷函數原型:
void Int9Handler(int Param); /* 注意中斷函數中不要調用阻塞函數 */

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.