logo
  • 現在做什麼
  • 關於我

Kalan

文章分類

  • 前端
  • 開發筆記
  • 雜談
  • 年度回顧

快速連結

  • 現在做什麼
  • 關於我
  • 聯絡我
  • 職涯思考🔗

關注我

在福岡生活的開發者,分享軟體開發與日本生活的點點滴滴。

© 2025 Kalan Made with ❤️. All rights reserved.

avr-libc 中的 ATOMIC_BLOCK

作成者:カランカラン2022年2月27日 14:14
ホーム/開発ノート
💡

質問やフィードバックがありましたら、フォームからお願いします

英語原文

目次

    本文は台湾華語で、ChatGPT で翻訳している記事なので、不確かな部分や間違いがあるかもしれません。ご了承ください

    avr-libc の中には <util/atomic.h> というファイルがあります。最初の印象は、avr は単核であるべきなのに、なぜ atomic が必要なのかということです。そのため、無意識に説明を見てみました。

    このヘッダーファイルのマクロは、原子性を持つか持たないかが保証されたコードブロックを扱います。この文脈での「Atomic」という用語は、該当するコードが中断されることができないことを指します。

    マイクロコントローラーでも、さまざまな割り込みが利用できるため、コードの実行が途中で中断される可能性があります。atomic を使用することで、内部にあるコード片が割り込みの影響を受けないこと(割り込みを一時的に中止する)を保証できます。

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

    体感としては cli() と sei() の組み合わせのように見えますが、ドキュメントの説明によると、さらなる処理が行われているようです。内部の実装は次のようになります。

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

    type をパラメータとして受け取ることができ、渡すことができるパラメータには ATOMIC_RESTORESTATE と ATOMIC_FORCEON があります。

    #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 loop を使用するこの方法は非常に興味深く、こんな使い方ができるとは思いもしませんでした。

    ← node.js ファイルの読み込みの詳細リミックスのフォームとデータ読み取りメカニズムの探討 →

    この記事が役に立ったと思ったら、下のリンクからコーヒーを奢ってくれると嬉しいです ☕ 私の普通の一日が輝かしいものになります ✨

    ☕Buy me a coffee