はじめに:なぜ今Zephyrなのか
STM32のRTOSといえば長らく「STM32CubeMXでFreeRTOSを有効化」が定番でした。弊社でも多くの案件でこの構成を採用しており、その基本は STM32 + FreeRTOS 入門 で解説したとおりです。しかしここ数年、新規案件のRTOS選定でZephyr RTOSが対抗馬として挙がる機会が急激に増えています。
背景には3つの流れがあります。
- プロジェクトの成熟:ZephyrはLinux Foundation傘下で2016年に発足し、2026年で10周年を迎えました。2026年3月のembedded world(ニュルンベルク)では10周年が大きく取り上げられ、参画企業も拡大を続けています。サポートボードは1000種類超、STM32はNucleo/Discoveryを中心にほぼ全シリーズが公式対応です
- EUサイバーレジリエンス法(CRA):2024年12月に発効したCRAは、2026年9月11日から脆弱性報告義務、2027年12月11日から本格適用が始まります。Zephyrは2017年からCVE採番機関(CNA)として活動し、SBOM自動生成(
west spdx)や脆弱性アラート登録制度を整備しており、「CRA時代のRTOS」として注目されています - 「カーネルだけ」では足りない製品要件:BLE・Wi-Fi・USB・ファイルシステム・OTA更新が当たり前になり、カーネル単体のFreeRTOSでは周辺ライブラリの寄せ集めとバージョン管理が負担になってきました
本記事では、実際にNucleo-F446REを使ってwest環境構築 → Lチカ → スレッド → デバイスツリーと手を動かしながらZephyrの世界観を掴み、最後にFreeRTOSとの使い分け基準を整理します。なお執筆時点(2026年7月)のZephyr最新安定版はv4.4.0(2026年4月14日リリース)、長期サポート版(LTS)はv3.7です。
本記事は STM32 + FreeRTOS 入門 の姉妹編です。FreeRTOS側の記事で解説したタスク・キュー・セマフォの概念はZephyrでもそのまま通用するので、RTOSそのものが初めての方は先にFreeRTOS編を読むことをお勧めします。本記事は「FreeRTOSは使ったことがあるが、Zephyrはこれから」という方を主読者に想定しています。
ZephyrはFreeRTOSと何が違うのか
最初に押さえるべき本質的な違いは、提供範囲です。
- FreeRTOSは「カーネル」:スケジューラ・タスク・キュー・セマフォを提供するC言語ソース一式(十数ファイル)です。GPIOやUARTのドライバはST社のHAL、BLEやTCP/IPは別ライブラリを自分で組み合わせます。プロジェクト構成の主導権はSTM32CubeMX/CubeIDEにあります
- Zephyrは「OSディストリビューション」:カーネルに加えて、デバイスドライバ(GPIO/UART/I2C/SPI/ADC/CAN…)、Bluetooth LEスタック、ネットワークスタック、ファイルシステム、ロギング、シェル、テストフレームワークまでを単一のソースツリーとビルドシステムで提供します。ST社のHALも
hal_stm32モジュールとしてZephyrのドライバ内部に取り込まれています
この違いが開発フローに直結します。FreeRTOSでは「CubeMXでポチポチ設定してコード生成」でしたが、Zephyrではwest(メタツール)でソースを取得し、デバイスツリーでハードウェアを記述し、Kconfigで機能を選択してビルドします。GUIのコード生成ツールは基本的に使いません。Linuxカーネル開発の作法をマイコンに持ち込んだ、と考えると理解が早いです。
つまりZephyrの学習コストの大半は、RTOSカーネルのAPIではなくビルドシステムと設定機構(west・デバイスツリー・Kconfig)にあります。逆に言えば、そこさえ越えればカーネルAPIはFreeRTOS経験者ならすぐ読めます。
west環境構築:実コマンドで一気に
Ubuntu(WSL2含む)での手順です。Zephyrの公式Getting Startedに準拠しています。事前にaptで cmake(3.20.5以上)、ninja-build、device-tree-compiler(1.4.6以上)、python3-venv 等を入れておきます。Pythonは3.12が強く推奨されています(新しすぎるPythonでpipパッケージのビルドに失敗する事例があるため)。
# 1. Python仮想環境を作成してwestをインストール
python3 -m venv ~/zephyrproject/.venv
source ~/zephyrproject/.venv/bin/activate
pip install west
# 2. Zephyr本体と依存モジュール(hal_stm32等)を取得
west init -m https://github.com/zephyrproject-rtos/zephyr ~/zephyrproject
cd ~/zephyrproject
west update # 数GB。初回は時間がかかる
# 3. CMakeパッケージ登録とPython依存のインストール
west zephyr-export
west packages pip --install
# 4. Zephyr SDK(クロスコンパイラ一式)をインストール
cd ~/zephyrproject/zephyr
west sdk install
ポイントを補足します。
west updateが取ってくるのはZephyr本体だけではない:modules/hal/stm32(ST公式HAL/LL)など数十のモジュールリポジトリをwest.yml(マニフェスト)に従って一括チェックアウトします。FreeRTOSで「HALのバージョンとミドルウェアのバージョンの組み合わせ」に悩んだ経験があるなら、このマニフェストによるバージョン一括固定はZephyrの大きな魅力です- SDKはARM GCCを含むツールチェーン集:
west sdk install一発で入ります。STM32CubeIDE同梱のGCCとは独立しているので既存環境を汚しません - 仮想環境の有効化を忘れない:シェルを開き直したら毎回
source ~/zephyrproject/.venv/bin/activateが必要です。「昨日は動いたのにwest: command not found」の原因はほぼこれです
Nucleoボードへの west flash はデフォルトで STM32CubeProgrammer をランナーとして使います(OpenOCD・J-Linkも選択可)。ST公式サイトからCLI版を含むSTM32CubeProgrammerをインストールし、PATHを通しておいてください。ここを飛ばすと、ビルドは通るのに書き込みの段階で STM32_Programmer_CLI が見つからないエラーで止まります。
Nucleo-F446REでLチカ(blinky)
まずは公式サンプルの samples/basic/blinky を焼いてみます。Nucleo-F446REはZephyrに nucleo_f446re というボード名で登録されており、オンボードLED(LD2 / PA5)とユーザーボタン(PC13)、コンソール用UART(USART2、115200bps 8N1、ST-LINKの仮想COM経由)まで定義済みです。
cd ~/zephyrproject/zephyr
# -p always: ビルドディレクトリを毎回クリーン(ボード切替時の事故防止)
west build -p always -b nucleo_f446re samples/basic/blinky
# ST-LINK経由で書き込み(STM32CubeProgrammerランナー)
west flash
LD2が1秒周期で点滅すれば成功です。blinkyの main.c は本質的に次の内容です。
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#define SLEEP_TIME_MS 1000
/* デバイスツリーの led0 エイリアスからピン情報を取得(ビルド時に解決) */
#define LED0_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
int main(void)
{
if (!gpio_is_ready_dt(&led)) {
return 0;
}
gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
while (1) {
gpio_pin_toggle_dt(&led);
k_msleep(SLEEP_TIME_MS);
}
return 0;
}
FreeRTOS + HALの感覚で見ると、コードのどこにも「GPIOA」「ピン5」が出てこないことに気づくはずです。DT_ALIAS(led0) は「このボードで led0 と名付けられたLED」をデバイスツリーから引いてくるマクロで、実体(PA5)はボード定義ファイルに書かれています。だからこのmain.cは一切書き換えずに west build -b nucleo_h743zi でH7ボードでも動きます。これがZephyr流の移植性です。
スレッドを作る:FreeRTOSとの対応表つき
ZephyrではFreeRTOSの「タスク」に相当するものを「スレッド」と呼びます。もっとも簡単な作り方は K_THREAD_DEFINE マクロによる静的定義です。
#include <zephyr/kernel.h>
#define STACK_SIZE 1024
/* センサー読み取りスレッド(高優先) */
void sensor_thread(void *p1, void *p2, void *p3)
{
while (1) {
/* ここでI2Cセンサー読み取りなど */
k_msleep(100);
}
}
/* ログ出力スレッド(低優先) */
void logger_thread(void *p1, void *p2, void *p3)
{
while (1) {
printk("uptime=%lld ms\n", k_uptime_get());
k_msleep(500);
}
}
/* K_THREAD_DEFINE(名前, スタック, エントリ, 引数x3, 優先度, オプション, 開始遅延ms)
注意: Zephyrは数値が小さいほど高優先度(FreeRTOSと逆!) */
K_THREAD_DEFINE(sensor_tid, STACK_SIZE, sensor_thread, NULL, NULL, NULL, 5, 0, 0);
K_THREAD_DEFINE(logger_tid, STACK_SIZE, logger_thread, NULL, NULL, NULL, 7, 0, 0);
スケジューラの起動コード(FreeRTOSの osKernelStart() 相当)がどこにも無い点に注目してください。Zephyrではカーネルが main() より先に初期化され、main() 自体が1つのスレッドとして走ります。K_THREAD_DEFINE したスレッドは起動時に自動で走り出します。動的生成したい場合は k_thread_create()(スタック領域は K_THREAD_STACK_DEFINE で確保)を使います。
最重要の注意:優先度の向きがFreeRTOSと逆
Zephyrの公式ドキュメントには「数値が小さい優先度が、数値が大きい優先度に優先する」と明記されています。つまり優先度5のスレッドは優先度7のスレッドより偉い。FreeRTOS(数値が大きいほど高優先)の頭のままコピペ移植すると、優先度設計が丸ごと反転する事故になります。さらにZephyrでは負の優先度は協調(cooperative)スレッドという特別な意味を持ち、自分からブロックするまでプリエンプトされません。
FreeRTOS API → Zephyr API 対応表
| やりたいこと | FreeRTOS / CMSIS-OS v2 | Zephyr |
|---|---|---|
| タスク/スレッド生成 | xTaskCreate / osThreadNew | K_THREAD_DEFINE / k_thread_create |
| 待機(ms) | vTaskDelay / osDelay | k_msleep / k_sleep |
| メッセージキュー | xQueueSend/Receive / osMessageQueue* | K_MSGQ_DEFINE + k_msgq_put/get |
| セマフォ | xSemaphoreGive/Take / osSemaphore* | k_sem_give / k_sem_take |
| ミューテックス | xSemaphoreCreateMutex / osMutex* | k_mutex_lock/unlock(優先度継承あり) |
| ISRからの通知 | xxxFromISR 系API | セマフォ・キュー等のisr-ok APIはそのまま使える(K_NO_WAIT 指定) |
| ソフトウェアタイマー | xTimerCreate / osTimer* | K_TIMER_DEFINE / k_timer_start |
ISR まわりはZephyrの方がシンプルで、セマフォやメッセージキューはFreeRTOSのように「FromISR版を呼び分ける」ことなくそのまま使えます(ISR内ではブロック禁止=K_NO_WAITを指定)。ただしすべてのAPIがISR対応(isr-ok)ではなく、たとえばミューテックスはISRから一切使えない点には注意してください。FreeRTOSでのISR連携の勘所は FreeRTOS編の記事 で解説しています。
デバイスツリー:FreeRTOS経験者が最初に躓く壁
Zephyr導入でつまずくポイントの筆頭がここです。逆にここを理解すればZephyrは一気に楽になるので、考え方を丁寧に説明します。
考え方:ハード構成をCコードから追い出す
CubeMX + HALの世界では「PA5を出力に設定」というハードウェアの事実が、生成コードやマクロ定義としてCソースの中に散らばります。Zephyrではこれをデバイスツリー(Devicetree)という宣言的なテキスト(.dts / .dtsi / .overlay)に分離します。階層は次のとおりです。
- SoC定義(.dtsi):
stm32f446.dtsiなど。USART2は0x40004400にある、といったチップの事実。Zephyr本体に同梱 - ボード定義(.dts):
nucleo_f446re.dts。LD2はPA5、コンソールはUSART2、といったボードの事実。これも同梱 - アプリのオーバーレイ(.overlay):自分の基板・配線の事実。アプリ側で「上書き・追記」する差分ファイル
アプリのディレクトリに boards/nucleo_f446re.overlay(または全ボード共通なら app.overlay)を置くと、ビルド時に自動で合成されます。たとえばI2C1に温度センサーを追加する場合はこう書きます。
/* boards/nucleo_f446re.overlay */
&i2c1 {
status = "okay"; /* Nucleo-F446REの板定義では既にokayだが、SoC定義でdisabledのボードでは必須 */
clock-frequency = <I2C_BITRATE_FAST>; /* 400kHz */
temp_sensor: lm75@48 { /* I2Cアドレス0x48のセンサーを登録 */
compatible = "lm75";
reg = <0x48>;
};
};
ここで重要なのが2点。
status = "okay"の概念:SoC定義には全ペリフェラルが書かれていますが、大半はdisabled状態です。使うものだけをボード定義かオーバーレイでokayにします。「CubeMXでペリフェラルにチェックを入れる」操作のテキスト版だと思えば良いですcompatibleがドライバとの結び付け:compatible = "lm75"と書くと、Zephyrに同梱されたLM75ドライバがこのノードに紐付き、アプリからはsensor_sample_fetch()等の統一センサーAPIで読めます。デバイスドライバを自分で書かずに済むのがZephyrの生産性の源泉です
「Linuxのデバイスツリー=起動時にパースする」イメージがありますが、Zephyrのデバイスツリーはビルド時にCマクロへ完全展開されます(build/zephyr/zephyr.dts と devicetree_generated.h に成果物が出ます)。実行時のパース処理もRAM消費もありません。デバイスツリー起因のビルドエラーを調べるときは、まず合成結果の build/zephyr/zephyr.dts を見るのが定石です。
Kconfig(prj.conf)の基本
デバイスツリーが「ハードに何があるか」なら、Kconfigは「ソフトの機能を何を組み込むか」です。アプリ直下の prj.conf に CONFIG_* を列挙します。
# prj.conf の例
CONFIG_GPIO=y # GPIOドライバ
CONFIG_I2C=y # I2Cドライバ
CONFIG_SENSOR=y # センサーサブシステム(lm75等のドライバ含む)
CONFIG_LOG=y # ロギングサブシステム
CONFIG_SHELL=y # UARTコンソールで対話シェルが使える
CONFIG_MAIN_STACK_SIZE=2048
使わない機能はリンクすらされないため、フットプリントを絞れます。設定項目は膨大ですが、west build -t menuconfig でLinuxカーネルと同じ対話UIから検索・変更できます(確定したら prj.conf に書き戻すのが流儀です)。
FreeRTOS経験者向けに対応づけると、FreeRTOSConfig.h(configTOTAL_HEAP_SIZE 等)+「CubeMXのMiddlewareチェックボックス」を合わせたものが prj.conf です。ここで最頻出のハマりが「デバイスツリーで有効化したのにKconfigを忘れる」パターン。I2Cノードを okay にしても CONFIG_I2C=y が無ければドライバが組み込まれず、device_is_ready() が偽を返します。デバイスツリーとKconfigは両輪、と覚えてください。
FreeRTOSとの比較表と使い分け基準
| 観点 | FreeRTOS | Zephyr |
|---|---|---|
| 提供範囲 | カーネルのみ(ドライバはHAL、通信は別ライブラリ) | カーネル+ドライバ+BLE/ネットワーク/FS/シェルまで一体 |
| 学習コスト | 低い。CubeMXで即開始、APIも少ない | カーネルAPIは平易だが、west・デバイスツリー・Kconfigの習得が必要 |
| 開発フロー | STM32CubeMX/CubeIDE中心(GUI) | CLI中心(west build/flash)。VS Code+各種拡張が主流 |
| ライセンス | MIT(2017年よりAWSが開発主導) | Apache-2.0(Linux Foundation傘下の中立運営) |
| 移植性・マルチベンダー | 移植レイヤは薄いが、ドライバ層は各ベンダーHAL依存 | 1000超のボードでアプリコードがほぼ無修正で動く |
| 長期保守 | FreeRTOS LTS(AWS提供、更新2年。有償の延長保守EMPで最長+10年)+ST同梱版 | LTS(現行v3.7)+安定版を定期リリース(最新v4.4.0) |
| CRA・セキュリティ対応 | 脆弱性対応はAWS/各ライブラリ個別。SBOMは自前で整備 | CNA登録(2017年〜)、PSIRT運用、west spdx でSBOM自動生成 |
| フットプリント | 非常に小さい(数KB〜)。小容量MCU向き | 最小構成は小さいが、実用構成ではFreeRTOS比で大きくなりがち |
| テスト・CI | 仕組みは自前で構築 | Twister(テストランナー)・QEMU/シミュレータ実行が標準装備 |
使い分けの判断基準
弊社がRTOS選定の相談を受けたときに使っている判断軸です。
- FreeRTOSが向くケース:単機能の制御機器(モーター制御・計測など)/Flash 256KB未満の小容量MCU/CubeMX中心の既存開発フローを崩したくない/チームがFreeRTOS習熟済みで納期が短い/既存FreeRTOS資産の派生開発
- Zephyrが向くケース:BLE・ネットワーク・USB・OTAなどミドルウェアを複数使う製品/将来のMCUベンダー変更(供給リスク対策)を見込む/EU市場向けでCRA対応の脆弱性管理・SBOM提出が必要/複数製品でコードベースを共通化したい/CIでの自動テストを重視する
一言でまとめると、「マイコンに毛が生えた装置」はFreeRTOS、「小さなコネクテッド製品」はZephyrが第一候補です。
既存FreeRTOS資産がある場合の移行判断
「今のFreeRTOS製品をZephyrに移すべきか」という相談も増えていますが、結論から言うと動いている製品の載せ替え単体では割に合わないことが多いです。理由は3つあります。
- カーネルAPIの置換は移行工数の2割程度:前述の対応表のとおりAPI変換自体は機械的ですが、実際の工数の大半はHAL直叩きコードのZephyrドライバAPIへの置換、割り込み設計の見直し、デバイスツリー・Kconfigへの構成移植に費やされます。実質「作り直し」に近い見積もりが必要です
- 優先度の向きの反転などの地雷:優先度体系(数値の大小が逆、協調スレッドの存在)、ティック・タイムアウトの扱いなど、コンパイルは通るのに挙動が変わる差分が多く、リグレッションテストの整備が前提になります
- 検証済みという資産価値:量産で実績のあるFreeRTOSコードは、それ自体が検証コスト数人月分の資産です
移行に踏み切る合理性があるのは、次のような「どうせ大きく手を入れる」タイミングです。
- 製品のネットワーク化・無線化など大規模な機能追加で、ミドルウェア寄せ集めの限界が見えたとき
- MCUの供給問題・EOLでベンダー/シリーズ変更が必要になったとき(どうせドライバ層は書き直しになる)
- CRA対応で脆弱性監視・SBOM・セキュリティ更新の長期体制をOSSコミュニティに相乗りする形で構築したいとき
現実的な進め方としては、既存製品はFreeRTOSのまま保守を続け、新規プロジェクトや次世代機からZephyrを並行導入してチームの経験値を貯める二本立てを推奨しています。
FreeRTOS経験者がハマる落とし穴
| 症状 | 原因 | 対策 |
|---|---|---|
| 高優先のつもりのスレッドが後回しになる | 優先度の数値方向がFreeRTOSと逆(小さいほど高優先) | 移植時は優先度マッピング表を先に作る。負値(協調スレッド)は意図がある場合のみ使う |
device_is_ready() が偽 / ドライバが見つからない |
デバイスツリーで okay にしたがKconfig(CONFIG_I2C=y 等)を忘れている(またはその逆) |
デバイスツリーとprj.confは常にセットで確認。build/zephyr/.config で最終的な設定値を確認できる |
__device_dts_ord_NN undefined などの謎ビルドエラー |
デバイスツリーのノードが無効・エイリアス未定義のままAPIで参照している | 合成結果 build/zephyr/zephyr.dts で該当ノードの status とエイリアスを確認する |
west flash が失敗する |
STM32CubeProgrammer未インストール/PATH未設定 | CLI版を含めてインストール。west flash --runner openocd で代替ランナーも指定可能 |
| ボードを変えたら動かない・設定が残る | ビルドディレクトリに前ボードのキャッシュが残留 | west build -p always(pristineビルド)を習慣にする |
| printfデバッグの出力が出ない・重い | ログサブシステム未設定(Zephyrは printk/LOG_INF が流儀) |
CONFIG_LOG=y を有効化し LOG_INF() 系へ。遅延処理(deferred)モードならISRからも安全に出せる |
| スタック不足で暴走・MPUフォルト | FreeRTOS感覚の小さいスタック値(Zephyrはドライバ・ログ経由で消費が増えやすい) | CONFIG_THREAD_ANALYZER=y + CONFIG_THREAD_ANALYZER_AUTO=y で周期的にスレッド毎のスタック使用量を出力して調整(CONFIG_SHELL=y なら kernel threads コマンドでも確認可) |
west debug:OpenOCD経由でGDBが立ち上がる。VS Code + Cortex-Debug拡張との併用が快適- シェルを常設する:
CONFIG_SHELL=yにしておくと、UARTコンソールからkernel threads(スレッド一覧とスタック使用量)、device list(ドライバ初期化状態)が実機でそのまま叩けます。FreeRTOSのTask Listビューに相当する機能が最初から入っているイメージです - QEMUで先に検証:ロジック部分は
west build -b qemu_cortex_m3→west build -t runで実機なしにテストできる。CI組み込みも容易
まとめ
この記事のまとめ
- Zephyrは「カーネル」ではなく「OSディストリビューション」。学習コストの本体はwest・デバイスツリー・Kconfigにある
- 環境構築は venv →
pip install west→west init/update→west sdk installの4ステップ。Nucleo-F446REならwest build -b nucleo_f446reで即ビルドできる - デバイスツリーは「ハード構成をCコードから追い出す」仕組み。ビルド時にマクロ展開されるので実行時コストはゼロ
- 優先度は数値が小さいほど高優先(FreeRTOSと逆)。移植時最大の地雷
- 単機能・小容量・短納期はFreeRTOS、コネクテッド製品・マルチベンダー・CRA対応はZephyrが第一候補
- 既存FreeRTOS資産の載せ替え単体は非推奨。大規模改修・MCU変更・CRA対応のタイミングで判断する
RTOSの選定は、製品のライフサイクル全体のコストを左右する意思決定です。FreeRTOS・Zephyrそれぞれの得意領域を踏まえた技術選定からお手伝いできますので、お気軽にご相談ください。
RTOS選定のセカンドオピニオン、Zephyr/FreeRTOSでの新規開発、既存機器の改修まで 組込み制御・マイコン開発 として対応しています。
STM32 × RTOS(Zephyr / FreeRTOS)の受託開発
RTOS選定・アーキテクチャ設計から、ドライバ開発・量産デバッグ・長期保守体制の構築まで、20年超のSTM32受託開発実績で一貫対応します。新規開発のPoCも既存資産の改修もお任せください。
よくある質問(FAQ)
ZephyrはSTM32のどのボードで動きますか?
Nucleo・Discoveryを中心にSTM32のほぼ全シリーズ(F0/F1/F4/F7/G0/G4/H7/L4/U5/WB等)の評価ボードが公式サポートされています。本記事で使ったNucleo-F446REはボード名 nucleo_f446re として登録済みで、west build -b nucleo_f446re でそのままビルドできます。Zephyr全体では1000種類を超えるボードがサポートされています。
FreeRTOSとZephyrはどちらを選ぶべきですか?
小規模・単機能・STM32CubeMX中心の開発や既存FreeRTOS資産の改修ならFreeRTOSが合理的です。BLE・ネットワークなど複数ミドルウェアを使う製品、複数MCUベンダーへの展開、CRA対応で長期の脆弱性管理が必要な製品ではZephyrの優位性が大きくなります。詳しくは本文の比較表をご覧ください。
デバイスツリーとは何ですか?なぜ必要なのですか?
「どのペリフェラルがどのピン・アドレスにあるか」というハードウェア構成をCコードから分離して .dts/.overlay に記述する仕組みです。ビルド時にCマクロへ展開されるため実行時オーバーヘッドはなく、アプリは led0 のような論理名だけを参照するのでボードを変えてもアプリ側の修正が不要になります。
既存のFreeRTOS資産はZephyrに移行すべきですか?
安定稼働している製品を移行だけのために書き換えるのはお勧めしません。カーネルAPI・ドライバ層・ビルドシステムがすべて異なり、実質作り直しに近い工数になります。大幅な機能追加・MCUベンダー変更・CRA対応など、書き直しに見合うリターンがあるタイミングで判断し、まずは新規プロジェクトでの並行採用から始めるのが現実的です。
ZephyrはEUサイバーレジリエンス法(CRA)に対応していますか?
Zephyrプロジェクトは2017年からCVE採番機関(CNA)として登録され、PSIRTによる脆弱性対応プロセスと脆弱性アラート登録制度を運用しています。west spdx コマンドでSBOMをSPDX形式で自動生成することもできます。ただしCRAの適合義務を負うのは製品の製造者であり、Zephyrを使えば自動的に適合するわけではありません。