問題
ローレベルベアメタル埋め込みコンテキスト、私はそのようなアクセスメモリ位置にユーザを禁止するために、C ++構造内の任意の名前なしで、メモリ内の余白を作成したいです。
現在、私はuint32_t :96;
3ワードの代わりになる醜いビットフィールドを配置することでそれを達成しましたが、GCC(ビットフィールドが大きすぎてuint32_tに収まらない)から警告が出されます。これはかなり合法です。
正常に動作しますが、数百の警告が含まれるライブラリを配布する場合は、それほどクリーンではありません...
どうすれば適切に実行できますか?
そもそもなぜ問題があるのですか?
私が取り組んでいるプロジェクトは、マイクロコントローラーライン全体(STMicroelectronics STM32)のさまざまな周辺機器のメモリ構造を定義することです。そうするために、結果は、対象となるマイクロコントローラーに応じて、すべてのレジスターを定義するいくつかの構造体の結合を含むクラスです。
非常に単純なペリフェラルの簡単な例は次のとおりです。汎用入出力(GPIO)
union
{
struct
{
GPIO_MAP0_MODER;
GPIO_MAP0_OTYPER;
GPIO_MAP0_OSPEEDR;
GPIO_MAP0_PUPDR;
GPIO_MAP0_IDR;
GPIO_MAP0_ODR;
GPIO_MAP0_BSRR;
GPIO_MAP0_LCKR;
GPIO_MAP0_AFR;
GPIO_MAP0_BRR;
GPIO_MAP0_ASCR;
};
struct
{
GPIO_MAP1_CRL;
GPIO_MAP1_CRH;
GPIO_MAP1_IDR;
GPIO_MAP1_ODR;
GPIO_MAP1_BSRR;
GPIO_MAP1_BRR;
GPIO_MAP1_LCKR;
uint32_t :32;
GPIO_MAP1_AFRL;
GPIO_MAP1_AFRH;
uint32_t :64;
};
struct
{
uint32_t :192;
GPIO_MAP2_BSRRL;
GPIO_MAP2_BSRRH;
uint32_t :160;
};
};
all GPIO_MAPx_YYY
がマクロである場合、uint32_t :32
またはレジスタタイプ(専用構造)として定義されます。
ここでは、uint32_t :192;
どれがうまく機能するかがわかりますが、警告が表示されます。
これまでに検討したこと:
私はそれをいくつかuint32_t :32;
(ここでは6つ)に置き換えた可能性がありますが、uint32_t :1344;
(42)(特に)ある極端なケースがあります。そのため、構造の生成がスクリプト化されている場合でも、8kの上に約100行追加するのはやめたいと思います。
正確な警告メッセージは次のようなものです
width of 'sool::ll::GPIO::<anonymous union>::<anonymous struct>::<anonymous>' exceeds its type
(私はそれがどれほど怪しいかが好きです)
警告を削除するだけでは解決できませんが、
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-WTheRightFlag"
/* My code */
#pragma GCC diagnostic pop
解決策かもしれません...私が見つけTheRightFlag
た場合。ただし、このスレッドで指摘されているようにgcc/cp/class.c
、この悲しいコード部分では:
warning_at (DECL_SOURCE_LOCATION (field), 0,
"width of %qD exceeds its type", field);
これは-Wxxx
、この警告を削除するフラグがないことを示しています...
uint32_t :192;
。
:42*32
代わりに書くことができます:1344
char unused[12];
ましたか?