Skip to content
askn37 edited this page Sep 11, 2026 · 2 revisions

FreeStanding / CVT 作成支援

<api/CVT.h>

  • 依存性:<avr/io.h> <avr/sfr_defs.h> <avr/interrupt.h>

このヘッダファイルは "ブートストラップローダー" のような "フリースタンディング" 応用コードの作成を支援する。 有効化するには "ボードメニュー" → "Build API" → "Macro API Enable without startup" を選択しなければならない。 [modernAVR] [megaAVR] で機能し、[reduceAVR] では機能しない。

CLI では -DWOSFILES=1 -Wl,-nostartfiles の付加に相当。

フリースタンディング 応用コード

割込を一切使わないことが保証された応用コードの場合、次の記述が使用できる。 これは(割込を使わない・割込禁止のまま進行する)"ブートストラップローダー" におけるテンプレートである。 このコードは Flash 領域の BOOTCODE 区分先頭に配置・実行される想定である。

#include <api/CVT.h>

FREESTANDING_STARTUP() {
  __asm__ __volatile__ ("CLR __zero_reg__");

  /* SETUP STUB */

  for (;;) {
    /* LOOP STUB without interrupt */
  }
}
  • 応用コードブロックから return で抜け出す・終了することは許されない。
  • 応用コードは割込禁止で開始される。
  • 一般的スタートアップコードは作成されない。故に応用コード先頭での ゼロレジスタ準備、スタックポインタ初期化は 自前で書かなければならない。
  • トランポリンコードは作成されない。故に、関数範囲外の グローバルな変数の 暗黙の静定数初期化、暗黙のゼロ初期化、静的な C++ クラスインスタンス初期化等は 機能しない。それらは自前で記述しなければならない。
    • 関数ブロック内でのローカル変数実行時初期化に制約はない。
    • グローバルな一般変数は、.noinit セクションに配置されるべきである。
    • 文字列定数は、static const かつ .rodata セクションに配置されるべきである。
  • C標準ライブラリのリンクを(-Wl,-nostdlibで)禁じていなければ、それらは規定通り使用できる。
  • 通常関数のプロローグ/エピローグコードは、ABI 規約に則って通常通り挿入される。

Compact Vector Table 応用コード

ユーザー定義割込が最大ふたつまでであるなら CVT "Compact Vector Table" モードを選択することができる。 この場合は <api/CVT.h> を導入する前に、すくなくともひとつの CVT_*** マクロを宣言する。 以下のテンプレートは Flash 領域の APPCODE 区分先頭に配置・実行される想定である。

/* Configure it before including the header. */

// #define CVT_NMI
#define CVT_LVL1
#define CVT_LVL0

#include <api/CVT.h>

void _startup (void) {
  __asm__ __volatile__ ("CLR __zero_reg__");

  /* SETUP STUB */

  CVT_SETUP();  /* or CVT_BOOTCODE() */
  CPUINT_LVL1VEC = USB0_BUSEVENT_vect_num;  /* example */
  CPUINT_LVL0PRI = USB0_TRNCOMPL_vect_num;  /* example */
  sei();  /* enable interrupt */
  for (;;) {
    /* LOOP STUB */
  }
}

ISR(LVL1_vect, ISR_NAKED) {
  /* INTERRUPT STUB with naked */
  reti();
}

ISR(LVL0_vect) {
  /* INTERRUPT STUB */
}
  • 応用コードは必ず void _startup (void) から開始される。
  • 応用コードで割込を許可する前に、以下のマクロのひとつを選んで実行しければならない。
    • CVT_BOOTCODE() -- BOOTCODE 区分先頭の CVT を有効にする。つまり応用コードは BOOTCODE 区分にある(割込も使う)"ブートストラップローダー" 自身である。
    • CVT_APPCODE() -- APPCODE 区分先頭の CVT を有効にする。つまり応用コードは BOOTCODE または APPCODE 区分にある "ファームウェア" である。
    • CVT_STARTUP() -- CVT_APPCODE() に同じ。
  • さらに最大ふたつの割込の実体番号を、所定のレジスタに ***_vect_num マクロ定数で指示しなければならない。
  • 割込ベクタは通常通り、ISR(...) マクロで記述できる。既定のプロローグ/エピローグも挿入されるが、それを禁じたい場合は ISR_NAKED を指示する。
  • 必要なら ISR(NMI_vect) も記述することができる。これを CVT に加えるには CVT_NMI を事前に宣言する。
  • その他の注意点は "フリースタンディングコード" に倣う。

LINKS

multix.jp/てくにかるむ(休眠中)
Multix Zinnia Product SDK [*AVR]
AVR.JP(日本語訳)
AVR-LIBC(日本語訳)

Clone this wiki locally