日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

管道:介绍和基本服务

發布時間:2023/11/28 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 管道:介绍和基本服务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

管道:介紹和基本服務

Pipes introduction and basic services

與郵箱或隊列相比,它們提供了在任務之間傳遞簡單消息的更靈活的方式。

使用管道

在Nucleus SE中,管道是在構建時配置的。一個應用程序最多可以配置16個管道。如果未配置管道,則應用程序中不會包含與管道相關的數據結構或服務調用代碼。

管道僅僅是一組存儲位置,每個存儲位置都足夠大,足以容納一個用戶定義字節長度的數據項,對這些數據項的訪問是受控制的,以便可以由多個任務安全地使用它。任務可以重復寫入管道,直到所有位置都已滿。任務可以從管道中讀取,數據通常以先進先出(FIFO)的方式接收。嘗試發送到完整管道或從空管道讀取可能會導致錯誤或任務掛起,具體取決于在API調用和Nucleus SE配置中選擇的選項。

管道和隊列

Nucleus SE還支持隊列,管道和隊列之間的主要區別是消息大小。隊列攜帶由單個ADDR組成的消息,這些地址通常是指針。管道承載任意字節長的消息;應用程序中每個管道的大小是固定的,并在配置時設置。

配置管道

管道數量

與Nucleus SE的大多數方面一樣,管道的配置主要由nuse_config.h中的#define語句控制。鍵設置是NUSE_PIPE_NUMBER,它確定為應用程序配置了多少個管道。默認設置為0(即沒有管道正在使用),您可以將其設置為最大16的任何值。錯誤的值將導致編譯時錯誤,該錯誤由nuse_config_check.h中的測試生成(此錯誤包含在nuse_config.c中,因此使用此模塊進行編譯),從而導致編譯一個#錯誤語句。

選擇非零值是管道的“主啟用”。這將導致一些數據結構被相應地定義和調整大小,在下一篇文章中會有更多內容。它還激活API啟用設置。

API啟用

Nucleus SE中的每個API函數(服務調用)在nuse_config.h中都有一個啟用的#define符號。對于管道,包括:

NUSE_PIPE_SEND

NUSE_PIPE_RECEIVE

NUSE_PIPE_JAM

NUSE_PIPE_RESET

NUSE_PIPE_INFORMATION

NUSE_PIPE_COUNT

默認情況下,所有這些都設置為FALSE,從而禁用每個服務調用并禁止包含任何實現代碼。要為應用程序配置管道,需要選擇要使用的API調用,并將其啟用符號設置為TRUE。
下面是從默認nuse_config.h文件中提取的內容。

#define NUSE_PIPE_NUMBER 0 /* Number of pipes in the

system – 0-16 */

/* Service call enablers */

#define
NUSE_PIPE_SEND FALSE

#define
NUSE_PIPE_RECEIVE FALSE

#define
NUSE_PIPE_JAM FALSE

#define
NUSE_PIPE_RESET FALSE

#define
NUSE_PIPE_INFORMATION FALSE

#define
NUSE_PIPE_COUNT FALSE

如果啟用了管道API函數而未配置管道(除非始終允許使用NUSE_pipe_Count()),則會導致編譯時錯誤。如果您的代碼使用尚未啟用的API調用,則會導致鏈接時間錯誤,因為應用程序中不會包含任何實現代碼。

管道服務電話

Nucleus RTOS支持10個與管道相關的服務調用,它們提供以下功能:

向管道發送消息。由Nucleus SE中的NUSE_Pipe_Send()實現。

從管道接收消息。由Nucleus SE中的NUSE_Pipe_Receive()實現。

在管道前面發個信息。由Nucleus SE中的NUSE_Pipe_Jam()實現。

將管道恢復到未使用狀態,不暫停任何任務(重置)。由Nucleus SE中的NUSE_Pipe_Reset()實現。

提供有關指定管道的信息。由Nucleus SE中的NUSE_Pipe_Information()實現。

返回(當前)為應用程序配置的管道數的計數。由Nucleus SE中的NUSE_Pipe_Count()實現。

向應用程序添加新管道(創建)。未在Nucleus SE中實現。

從應用程序中刪除管道(刪除)。未在Nucleus SE中實現。

返回指向應用程序中所有管道(當前)的指針。未在Nucleus SE中實現。

向管道(廣播)上掛起的所有任務發送消息。未在Nucleus SE中實現。

將詳細檢查每個服務調用的實現。

管道讀寫服務

可以在管道上執行的基本操作是向管道寫入數據(有時稱為發送)和從中讀取數據(也稱為接收)。也可以將數據寫入管道前端,這也被稱為堵塞。Nucleus RTOS和Nucleus SE各自為這些操作提供了三個基本API調用,這里將對此進行討論。

寫在管道上

Nucleus RTOS API對管道的寫入調用非常靈活,允許您無限期地掛起,或者在操作無法立即完成的情況下暫停,也就是說,您嘗試寫入一個完整的管道。Nucleus SE提供相同的服務,除了task suspend是可選的并且不實現timeout。

Nucleus RTOS還提供了一個向管道廣播的功能,但Nucleus
SE不支持這種功能。

Nucleus RTOS API Call for Sending to a Pipe

Service call prototype:

STATUS NU_Send_To_Pipe(NU_PIPE *pipe, VOID *message,

UNSIGNED size, UNSIGNED suspend);

Parameters:

pipe – pointer to the user-supplied pipe control block

message – a pointer to the message to be sent

size – the number of bytes in the message. If the pipe supports variable-length messages, this parameter must be equal to or less than the message size supported by the pipe. If the pipe supports fixed-size messages, this parameter must be exactly the same as the message size supported by the pipe

suspend – specification for task suspend; may be NU_NO_SUSPEND or NU_SUSPEND or a timeout value

Returns:

NU_SUCCESS – the call was completed successfully

NU_INVALID_PIPE – the pipe pointer is invalid

NU_INVALID_POINTER – the message pointer is NULL

NU_INVALID_SIZE – the message size is incompatible with the message size supported by the pipe

NU_INVALID_SUSPEND – suspend was attempted from a non-task thread

NU_PIPEE_FULL – the pipe is full and suspend was not specified

NU_TIMEOUT – the pipe is still full even after suspending for the specified timeout value

NU_PIPE_DELETED – the pipe was deleted while the task was suspended

NU_PIPE_RESET – the pipe was reset while the task was suspended

Nucleus SE API Call for Sending to a Pipe

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

<="" font="" style=“box-sizing: inherit;”>

<="" font="" style=“box-sizing: inherit;”>

STATUS NUSE_Pipe_Send(NUSE_PIPE pipe, U8 *message,

U8 suspend);

Parameters:

pipe – the index (ID) of the pipe to be utilized

message – a pointer to the message to be sent, which is a sequence of bytes as long as the configured message size of the pipe

suspend – specification for task suspend; may be NUSE_NO_SUSPEND or NUSE_SUSPEND

Returns:

NUSE_SUCCESS – the call was completed successfully

NUSE_INVALID_PIPE – the pipe index is invalid

NUSE_INVALID_POINTER – the message pointer is NULL

NUSE_INVALID_SUSPEND – suspend was attempted from a non-task
thread or when blocking API calls were not enabled

NUSE_PIPE_FULL – the pipe is full and suspend was not specified

NUSE_PIPE_WAS_RESET – the pipe was reset while the task was
suspended

管道發送的核SE實現

NUSE_Pipe_Send()–檢查API函數是否已啟用suspend()的條件編譯(取決于u)的API是否已啟用。我們將在這里分別研究這兩種變體。

如果未啟用阻塞,則此API調用的代碼非常簡單:

if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full /{ return_value = NUSE_PIPE_FULL;}else / pipe element available */{ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Head[pipe]]; for (i=0; i<msgsize; i++) { *data++ = *message++; } NUSE_Pipe_Head[pipe] += msgsize; if (NUSE_Pipe_Head[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Head[pipe] = 0; } NUSE_Pipe_Items[pipe]++; return_value = NUSE_SUCCESS;}

該函數只檢查管道中是否有空間,并使用NUSE_pipe_Head[]索引將消息存儲在管道的數據區域中。

啟用阻塞后,代碼會變得更復雜:

do{ if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full / { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_PIPE_FULL; } else { / block task / NUSE_Pipe_Blocking_Count[pipe]++; NUSE_Suspend_Task(NUSE_Task_Active, (pipe << 4) | NUSE_PIPE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else / pipe element available */ { data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Head[pipe]]; for (i=0; i<msgsize; i++) { *data++ = message++; } NUSE_Pipe_Head[pipe] += msgsize; if (NUSE_Pipe_Head[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Head[pipe] = 0; } NUSE_Pipe_Items[pipe]++; if (NUSE_Pipe_Blocking_Count[pipe] != 0) { U8 index; / check whether a task is blocked on this pipe */ NUSE_Pipe_Blocking_Count[pipe]–; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == pipe)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; }} while (suspend == NUSE_SUSPEND);

對代碼的一些解釋可能有用:

代碼包含在do…while循環中,當參數suspend的值為NUSE_suspend時,循環將繼續。

如果管道已滿,并且suspend設置為NUSE_NO_suspend,則API調用將以NUSE_pipe_full退出。如果suspend設置為NUSE_suspend,則任務將被掛起。返回時(即,當任務被喚醒時),如果返回值為NUSE_SUCCESS,表示任務被喚醒是因為消息已被讀取(而不是重置管道),則代碼循環返回頂部。

如果管道未滿,則使用NUSE_pipe_Head[]索引存儲提供的消息,以將消息存儲在管道的數據區域中。檢查管道上是否有任何任務掛起(等待接收)。如果有任務等待,第一個任務被喚醒。suspend變量被設置為NUSE_NO_suspend,API調用將退出并返回NUSE_SUCCESS。

從管子里讀東西

從管道讀取的Nucleus RTOS API調用非常靈活,使您能夠無限期地掛起,或者在操作無法立即完成的情況下暫停,也就是說,您嘗試從空管道中讀取。Nucleus SE提供相同的服務,除了task suspend是可選的并且不實現timeout。

ucleus RTOS API Call for Receiving from a Pipe

Service call prototype:

STATUS NU_Receive_From_Pipe(NU_PIPE *pipe, VOID *message, UNSIGNED size, UNSIGNED *actual_size, UNSIGNED suspend);

Parameters:

pipe – pointer to user-supplied pipe control block

message – pointer to storage for the message to be received

size –
the number of bytes in the message. This number must correspond to the message size defined when the pipe was created

suspend – specification for task suspend; may be NU_NO_SUSPEND or NU_SUSPEND or a timeout value

Returns:

NU_SUCCESS – the call was completed successfully

NU_INVALID_PIPE – the pipe pointer is invalid

NU_INVALID_POINTER – the message pointer is NULL

NU_INVALID_SUSPEND – suspend was attempted from a non-task

NU_PIPE_EMPTY – the pipe is empty and suspend was not specified

NU_TIMEOUT – indicates that the pipe is still empty even after suspending for the specified timeout value

NU_PIPE_DELETED –
the pipe was deleted while the task was suspended

NU_PIPE_RESET – the pipe was reset while the task was suspended

Nucleus SE API Call for Receiving from a Pipe

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

STATUS NUSE_Pipe_Receive(NUSE_PIPE pipe, U8 *message,

U8 suspend);

Parameters:

pipe – the index (ID) of the pipe to be utilized

message – a pointer to storage for the message to be received, which is a sequence of bytes as long as the configured message size of the pipe

suspend – specification for task suspend; may be NUSE_NO_SUSPEND or NUSE_SUSPEND

Returns:

NUSE_SUCCESS – the call was completed successfully

NUSE_INVALID_PIPE – the pipe index is invalid

NUSE_INVALID_POINTER – the message pointer is NULL

NUSE_INVALID_SUSPEND – suspend was attempted from a non-task thread or when blocking API calls were not enabled

NUSE_PIPE_EMPTY – the pipe is empty and suspend was not specified

NUSE_PIPE_WAS_RESET – the pipe was reset while the task was suspended

Nucleus SE Implementation of Pipe Receive

管道接收的核SE實現

NUSE_Pipe_Receive()API函數的大部分代碼(在參數檢查之后)是通過條件編譯選擇的,這取決于是否啟用了對阻塞(任務掛起)API調用的支持。我們將在這里分別研究這兩種變體。

如果未啟用阻塞,則此API調用的代碼非常簡單:

if (NUSE_Pipe_Items[pipe] == 0) /* pipe empty /{ return_value = NUSE_PIPE_EMPTY;}else{ / message available */ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *message++ = *data++; } NUSE_Pipe_Tail[pipe] += msgsize; if (NUSE_Pipe_Tail[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Tail[pipe] = 0; } NUSE_Pipe_Items[pipe]–; *actual_size = msgsize; return_value = NUSE_SUCCESS;}

只需使用管道中的指針NUSE_Pipe_Tail[]從數據管道中返回數據,并通過管道返回數據。 啟用阻塞后,代碼會變得更復雜:

do{ if (NUSE_Pipe_Items[pipe] == 0) /* pipe empty / { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_PIPE_EMPTY; } else { / block task / NUSE_Pipe_Blocking_Count[pipe]++; NUSE_Suspend_Task(NUSE_Task_Active, (pipe << 4) | NUSE_PIPE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } else { / message available */ data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *message++ = data++; } NUSE_Pipe_Tail[pipe] += msgsize; if (NUSE_Pipe_Tail[pipe] == (NUSE_Pipe_Size[pipe] * msgsize)) { NUSE_Pipe_Tail[pipe] = 0; } NUSE_Pipe_Items[pipe]–; if (NUSE_Pipe_Blocking_Count[pipe] != 0) { U8 index; / check whether a task is blocked / / on this pipe */ NUSE_Pipe_Blocking_Count[pipe]–; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_PIPE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == pipe)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } *actual_size = msgsize; return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; }} while (suspend == NUSE_SUSPEND);

對代碼的一些解釋可能有用:

代碼包含在do…while循環中,當參數suspend的值為NUSE_suspend時,循環將繼續。

如果管道為空,并且suspend設置為NUSE_NO_suspend,則API調用將以NUSE_pipe_empty退出。如果suspend設置為NUSE_suspend,則任務將被掛起。返回時(即,當任務被喚醒時),如果返回值為NUSE_SUCCESS,表示任務因已發送消息而被喚醒(而不是重置管道),則代碼循環返回頂部。

如果管道包含任何消息,則使用NUSE_pipe_Tail[]索引返回存儲的消息,以從管道的數據區域獲取消息。檢查管道上是否有任何任務被掛起(等待發送)。如果有任務等待,第一個任務被喚醒。suspend變量被設置為NUSE_NO_suspend,API調用將退出并返回NUSE_SUCCESS。

寫在管道前面

Nucleus RTOS-API調用寫入管道的前端非常靈活,允許您無限期地掛起,或者在操作無法立即完成的情況下暫停超時;也就是說,您嘗試寫入一個完整的管道。Nucleus SE提供相同的服務,除了task suspend是可選的并且不實現timeout。

Nucleus RTOS API Call for Jamming to a Pipe

Service call prototype:

STATUS NU_Send_To_Front_Of_Pipe(NU_PIPE *pipe, VOID *message,

UNSIGNED size, UNSIGNED suspend);

Parameters:

pipe – pointer to a user-supplied pipe control block

message – a pointer to the message to be sent

size – the number of bytes in the message. If the pipe supports variable-length messages, this parameter must be equal to or less than the message size supported by the pipe. If the pipe supports fixed-size messages, this parameter must be exactly the same as the message size supported by the pipe.

suspend – specification for task suspend; may be NU_NO_SUSPEND or NU_SUSPEND or a timeout value

Returns:

NU_SUCCESS – the call was completed successfully

NU_INVALID_PIPE – the pipe pointer is invalid

NU_INVALID_POINTER – the message pointer is NULL

NU_INVALID_SIZE – the message size is incompatible with the message size supported by the pipe

NU_INVALID_SUSPEND – suspend was attempted from a non-task thread

NU_PIPE_FULL – the pipe is full and suspend was not specified

NU_TIMEOUT – the pipe is still full even after suspending for the specified timeout value

NU_PIPE_DELETED – the pipe was deleted while the task was suspended

NU_PIPE_RESET – the pipe was reset while the task was suspended

Nucleus SE API Call for Jamming to a Pipe

This API call supports the key functionality of the Nucleus RTOS API.

Service call prototype:

STATUS NUSE_Pipe_Jam(NUSE_PIPE pipe, ADDR *message,

U8 suspend);

Parameters:

pipe – the index (ID) of the pipe to be utilized

message – a pointer to the message to be sent, which is a sequence of bytes as long as the configured message size of the pipe

suspend – specification for task suspend; may be NUSE_NO_SUSPEND or NUSE_SUSPEND

Returns:

NUSE_SUCCESS – the call was completed successfully

NUSE_INVALID_PIPE – the pipe index is invalid

NUSE_INVALID_POINTER – the message pointer is NULL

NUSE_INVALID_SUSPEND – suspend was attempted from a non-task thread or when blocking API calls were not enabled

NUSE_PIPE_FULL – the pipe is full and suspend was not specified

NUSE_PIPE_WAS_RESET – the pipe was reset while the task was suspended

Nucleus SE Implementation of Jamming to a Pipe

The bulk of the code of the NUSE_Pipe_Jam() API function is very similar to that of NUSE_Pipe_Send() , except that the data is stored using the NUSE_Pipe_Tail[] index,
thus:

if (NUSE_Pipe_Items[pipe] == NUSE_Pipe_Size[pipe]) /* pipe full /{ return_value = NUSE_PIPE_FULL;}else / pipe element available */{ if (NUSE_Pipe_Tail[pipe] == 0) { NUSE_Pipe_Tail[pipe] = (NUSE_Pipe_Size[pipe] - 1) * msgsize; } else { NUSE_Pipe_Tail[pipe] -= msgsize; } data = &NUSE_Pipe_Data[pipe][NUSE_Pipe_Tail[pipe]]; for (i=0; i<msgsize; i++) { *data++ = *message++; } NUSE_Pipe_Items[pipe]++; return_value = NUSE_SUCCESS;}

總結

以上是生活随笔為你收集整理的管道:介绍和基本服务的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。