コンテンツにスキップ

critical-section — Crate 詳細

critical-section

Mature no_std

環境ごとに差し替え可能なクリティカルセクション API crate。no_std ライブラリが、Cortex-M の割り込み禁止、RP2040 のマルチコア対応ロック、RTOS のカーネルロック、std の Mutex などの実装差を意識せず、critical_section::with() や Mutex を使って共有データを保護できるようにします。

A pluggable, cross-platform critical-section API for Rust. It lets portable libraries use critical_section::with(), acquire/release, and a critical-section-based Mutex while the final target-support crate supplies the concrete implementation.

概要

critical-section は、組み込み Rust で共有データを保護するための 共通 API を提供する crate です。ライブラリは critical_section::with()critical_section::Mutex を使ってクリティカルセクション内の処理を書き、最終バイナリ側が Cortex-M、RISC-V、RP2040、RTOS、std など実行環境に合った実装を 1 つだけ供給します。

使い分けの考え方

  • ライブラリ crate: critical-section に依存するだけにし、stdcritical-section-* feature は有効化しない。実装選択は最終ユーザーのバイナリに任せる。
  • no_std バイナリ: cortex-mriscvrp2040-halembassy-rpnrf-softdevice など、ターゲットに合った実装提供 crate の feature を 1 つだけ有効化する。
  • std バイナリ / host test: critical-sectionstd feature を有効化すると、std::sync::Mutex ベースの実装を使える。no_std ライブラリのテストでは dev-dependencies 側だけで有効化するのが安全。

注意点

critical_section::with() を使うのに実装が 1 つもリンクされていない場合は _critical_section_1_0_acquire / _critical_section_1_0_release の undefined reference が発生します。逆に複数の crate が実装を提供すると duplicate symbol になります。依存ツリー全体で実装は ちょうど 1 つ になるように feature を整理してください。

バージョン
1.2.0
ライセンス
MIT OR Apache-2.0
メンテナンス
受動的メンテナンス

コード例

PC 上のサンプルや no_std ライブラリの host test では std feature を dev-dependencies 側だけで有効化すると扱いやすいです。

std feature で critical_section::Mutex を使う
use core::cell::Cell;
use critical_section::Mutex;
// Cargo.toml:
// critical-section = { version = "1.2", features = ["std"] }
//
// std feature を有効化すると、critical-section crate 自身が
// std::sync::Mutex ベースの実装を提供します。
static COUNTER: Mutex<Cell<u32>> = Mutex::new(Cell::new(0));
fn main() {
critical_section::with(|cs| {
let current = COUNTER.borrow(cs).get();
COUNTER.borrow(cs).set(current + 1);
});
critical_section::with(|cs| {
assert_eq!(COUNTER.borrow(cs).get(), 1);
});
}

単一コア Cortex-M では cortex-m crate の critical-section-single-core feature を使う構成例です。実プロジェクトではターゲット MCU/HAL/RTOS に合った実装を 1 つだけ有効化します。

単一コア Cortex-M バイナリで実装 crate を選ぶ
#![no_std]
#![no_main]
use core::cell::Cell;
use cortex_m_rt::entry;
use critical_section::Mutex;
use panic_halt as _;
// Cargo.toml の例:
// cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
// cortex-m-rt = "0.7"
// critical-section = "1.2"
// panic-halt = "0.2"
//
// ライブラリ側は critical-section のみを使い、
// 実際の実装は最終バイナリ側で 1 つだけ選択します。
static VALUE: Mutex<Cell<u32>> = Mutex::new(Cell::new(0));
#[entry]
fn main() -> ! {
critical_section::with(|cs| {
VALUE.borrow(cs).set(42);
});
loop {
cortex_m::asm::wfi();
}
}

関連 Crates