カランのブログ

Kalan 頭像照片,在淡水拍攝,淺藍背景

四零二曜日電子報上線啦!訂閱訂起來

ソフトウェアエンジニア / 台湾人 / 福岡生活
このブログはRSS Feed をサポートしています。RSSリンクをクリックして設定してください。技術に関する記事はコードがあるのでブログで閲覧することをお勧めします。

今のモード ライト

我會把一些不成文的筆記或是最近的生活雜感放在短筆記,如果有興趣的話可以來看看唷!

記事のタイトルや概要は自動翻訳であるため(中身は翻訳されてない場合が多い)、変な言葉が出たり、意味伝わらない場合がございます。空いてる時間で翻訳します。

avr-libc 中的 ATOMIC_BLOCK

avr-libcには、<util/atomic.h>というものがあります。最初の反応は、AVRは単一コアなのになぜatomicが必要なのかということですので、説明を見てみました。

このヘッダーファイルのマクロは、アトミックまたは非アトミックに実行されることが保証されたコードブロックに対応しています。この文脈での「アトミック」という用語は、対応するコードが割り込みを受けることができないことを指します。

マイクロコントローラでも、さまざまな割り込みを使用することができるため、プログラムの実行は途中で中断される可能性があります。atomicを使用することで、その中に含まれるコードセグメントが割り込みに影響を受けないように保証することができます(一時的に割り込みを停止します)。

ATOMIC_BLOCK(ATOMIC_FORCEON) {
  // 重要な処理を行う
}

直感的には、cli()sei()の組み合わせに似ていますが、ドキュメントの説明によると、さらに多くのことが行われているようです。内部の実装は次のようになっています:

#define ATOMIC_BLOCK(type) for ( type, __ToDo = __iCliRetVal(); \
                           __ToDo ; __ToDo = 0 )

typeを引数として受け取ることができ、ATOMIC_RESTORESTATEATOMIC_FORCEONの2つの引数を渡すことができます。

#define ATOMIC_RESTORESTATE uint8_t sreg_save \
    __attribute__((__cleanup__(__iRestore))) = SREG

これはseiの効果に似ていますが、より興味深いのは__attribute__の使用です。GCCでは、変数や関数がどのように保存されるべきかを決定するために__attribute__を使用することができます。これはlibcの実装で定義されている動作であり、AVRの場合は次のように書くことができます:

#include <avr/pgmspace.h>
const int my_var[2] PROGMEM = { 1, 2 };

ここでのPROGMEMは実際には__attribute__です:

#ifndef __ATTR_PROGMEM__
#define __ATTR_PROGMEM__ __attribute__((__progmem__))
#endif

通常、変数はメモリに格納されますが、マイクロコントローラではメモリが非常に制限されています。ただし、一般的なコンピュータとは異なり、通常、マイクロコントローラのコードは事前に書かれ、コンパイル後にプログラムメモリ(フラッシュメモリ)に直接書き込まれます。プログラムコードが少ない場合、フラッシュメモリに余分なスペースが残ることがあり、その場合はPROGMEMを使用して変数をフラッシュメモリに格納し、メモリ使用量を減らすことができます。読み取り時には、pgm_read_wordを使用して変数を読み取ることができます。

ATOMIC_BLOCKに戻ると、展開すると次のようなコードになります:

for (uint8_t sreg_save __attribute__((__cleanup__(__iRestore))) = 0;  __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0) {
   // 重要な処理を行う
}

このようにして、割り込みの影響を受けずにコードの実行が保証されます。forループを使用するこのテクニックは、驚くべきものであり、このように応用することは全く考えていませんでした。

次の記事

node.js ファイルの読み込みの詳細

前の記事

リミックスのフォームとデータ読み取りメカニズムの探討

この文章が役に立つと思うなら、下のリンクで応援してくれると大変嬉しいです✨

Buy me a coffee