[英]Global union for different modules
我有帶有一組不同驅動程序的 MCU 代碼(用於 AVR)。 使用中的驅動程序是在啟動時選擇的(在初始化代碼中),並且一次只會使用一個驅動程序。 因此,我可以將所有 RAM 段別名為同一個位置。 這是必需的,因為 RAM 非常有限,並且所有驅動程序都需要 2-3 KB 的緩沖區等存儲空間。
目前我在所有 header 文件中都有typedef
結構:
typedef struct {
// Driver-specific variables for internal use.
// None of those and accessed from outside C-file
int internal_variable1_for_driver1;
int internal_variable2_for_driver1;
...
} st_driver1_t;
其他驅動程序也有類似的結構
#include "driver1.h"
#include "driver2.h"
#include "driver3.h"
...
union {
st_driver1_t DRV1;
st_driver2_t DRV2;
st_driver3_t DRV3;
...
} DRV;
免責聲明:我知道除了選定的模塊之外,所有來自模塊的 RAM 訪問都應該被禁用,因為它會改變整個聯合體。 我的投資組合中有很多 ASM 代碼,這對我來說是顯而易見的。
現在我有一些沖突,因為我必須包含 all_drivers.h,因此所有 driverN.h 文件都包含在每個驅動程序中。 我想對所有其他驅動程序隱藏所有這些標頭。
是否可以在 C 文件中使用__attribute__((common))
定義所有特定於驅動程序的結構,從而從標頭中隱藏所有結構。 據我了解,linker 會將所有這些結構合並到重疊段中並創建一些聯合模擬。
struct __attribute__((common)) {
int var1;
int var2;
...
} DRV;
struct __attribute__((common)) {
long OtherVar1;
int ExtraOne;
...
} DRV;
另外,我是否應該將這些結構定義為static
? 這個解決方案會穩定還是沒有記錄的黑客攻擊?
是否可以使用
__attribute__((common))
定義所有特定於驅動程序的結構
使用 GCC 和兼容的編譯器,您可以將__attribute__((__common__))
用於公共變量(如果某些變量不應該是公共的,則可以使用 __attribute__((__no_common__) __attribute__((__no_common__))
,但公共是默認值)。
GCC 已將其默認行為從-fcommon
切換為-fno-common
前一段時間(2020 年使用v10 ),因此您還可以使用-fcommon
編譯所有需要此功能的編譯單元。
我應該將這些結構定義為
static
[...]?
不可以。對象必須滿足一些條件才能合並為 common:
這些對象是全局的(因此也在 static 存儲中)。
這些對象沒有初始化器。
這些對象具有相同的(程序集)名稱。
必須建議編譯器將對象放在公共對象中,如上文所討論的那樣。
有時,最好不要讓對象在 C/C++ 級別上具有相同的名稱,例如,driver1 的 object 被命名為driver1
等。如果對象在程序集級別上具有相同的名稱,這很好,這可以通過使用來實現所有此類對象的程序集名稱相同。 這是 GCC 提供的功能。以下示例將程序集名稱設置為asm_name
,因此在程序集代碼中將使用名稱asm_name
,但在 C 代碼中使用driver1
:
typedef struct { ... } driver1_t;
__attribute__((__common__))
driver1_t driver1 __asm ("asm_name");
如果 ABI 需要前導下划線,您應該使用適合該 ABI 的名稱並使用以_
開頭的程序集名稱,如_asm_name
。
在某些用例中,common 比將所有對象放入一個 union 中要清晰和方便得多,所以不要因這些注釋而氣餒。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.