當我需要將區域變數作為指標傳遞給另一個函式時,我需要一些關于在 FreeRTOS 中使用區域變數的解釋/說明。
例如,我有一些函式可以修改指標“資料”下的資料。
void modify_data(int * data){
*data = 10;
}
我可以這樣使用它嗎?
void some_function(void){
int d; // local variable
modify_data(&d);
}
或者也許我應該制作全域變數?
int d;
void some_function(void){
modify_data(&d);
}
還是靜態變數?
void some_function(void){
static int d;
modify_data(&d);
}
我的一般問題是:
如何在 FreeRTOS 中使用帶指標的函式使用(或替換)區域變數?
編輯:
此刻我對此的理解是:
如果我想將它們的指標傳遞給另一個函式(或對指向這些變數的指標做任何事情),函式中的區域變數沒有用處,因為任務切換會導致存盤區域變數的記憶體位置發生變化
如果我想用它們的指標做任何事情,我必須將變數宣告為靜態或全域
這有點煩人,因為我的大程式中的很多變數必須全域宣告,并且傳遞指向全域資料的指標沒有意義,除了代碼的可讀性
我正在使用 FreeRTOS 10.2.1、CMSIS 1.02,代碼在 STM32 微控制器上運行。
uj5u.com熱心網友回復:
對于初學者來說,這個宣告
*data = (*data) ;
呼叫未定義的行為。
至于您的問題,那么要更改函式中的變數,您需要通過參考將其傳遞給函式,該參考間接地通過指向它的指標。例如
void f( int *px )
{
*px = 10;
}
void g( void )
{
static int x;
f( &x );
}
uj5u.com熱心網友回復:
取決于你想做什么。如果您想d在該函式之外使用,則需要將其定義為全域,如果您只想在函式內部使用它,請將其宣告為本地。
uj5u.com熱心網友回復:
因此,經過一些評論討論和一些研究后,我找到了我的擔憂的答案。
區域變數可以以任何方式使用,除了在main 函式(和 main 呼叫的函式中)宣告的區域變數(在 FreeRTOS 調度程式啟動之前)。
我擔心的根源是我在一些教程中閱讀過,在“主要背景關系”中創建的本地函式可能會被搞砸或不存在。沒有清楚地解釋它適用于“主 c 函式”,我誤解了所有認為“主背景關系”是與主堆疊指標相關的背景關系,而不僅僅是“主函式”。
FreeRTOS 網站上的常見問題解答說:
在 FreeRTOS 調度程式啟動后,main() 的背景關系不存在,因為從那時起,只有 RTOS 任務和中斷具有背景關系。為了最大化 FreeRTOS 應用程式可用的 RAM 量,并且 C 標準允許 main() 的背景關系不再存在,一些 FreeRTOS 埠重新使用分配給 main 的堆疊作為系統或中斷堆疊。因此,切勿在 main() 使用的堆疊上分配 FreeRTOS 應用程式需要或以任何方式訪問的變數或緩沖區,因為它們很可能被覆寫。
所以這個簡化的例子就可以了:
int x;
int main(void)
{
x = 10;
createTasks();
vTaskStartScheduler();
}
但是這樣的事情在 FreeRTOS 中不起作用:
int * px; // this pointer will be not valid after vTaskStartScheduler()
int main(void)
{
int x = 10;
px = &x;
createTasks();
vTaskStartScheduler();
}
有人可能會問為什么我在 main 中使用了一個區域變數,并且想在應用程式的其余部分訪問它而不將其宣告為全域變數。我這樣做是因為我開發了將我的代碼附加到 CMSIS/STM32Cube 生成的代碼(這迫使程式員在“用戶代碼區域”中撰寫)的特定/奇怪的方式,這種方式在我開始使用 FreeRTOS 之前一直有效。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/462113.html
上一篇:為每個結構使用多個互斥鎖的最佳方法?(例如,由4個執行緒操作的2個結構)
下一篇:fwrite函式錯誤寫入資料
