SNSへはこちら

STM32でARMパチパチマイコンを作る その1

これまでインラインアセンブラバイナリ手打ちをしてきましたが、ふと気づいたことがあります。

書き込み時にシリアル通信という高レベルなことを使うなんてけしからん!!

というわけで

一番理解している ARM マイコンでパチパチマイコンを作ることにしました。

パチパチマイコンとは、機械語を手打ちで入力していくマイコンのことで、ネットを調べると Z80 マイコンがよく出てきます。僕自身、この Z80 の例を見て作ろうと決心しました。

さて,かなり間が空いてしまいましたが,Z80 を使ったコンピュータを作っていこうと思います。いきなり部品点数の多いものを作るのも面白そうですが,完成までの時間がかかるし,頓挫する可能性が大きい(よくある)ので,まずは最小限の構成でワンボードコンピュータっぽいものを作ろうと思います。メモリ構成についてメモリは,SRAM ...

仕様

STM32 は RAM に書き込まれたプログラムを実行することが可能です。なので、配列としてプログラムデータを書いてそれを実行できます。 以下が例です。

using hword_t = uint16_t;

#define _assign_32bit(x) _low(x), _high(x)
__attribute__((aligned(4))) hword_t programBuffer[512] = {
        0x4800 | ((0xff & 4) >> 2),     // 00: ldr r0, [pc, #4]
        0x2101,                         // 02: mov r1, #1
        0x6001,                         // 04: str r1, [r0, #0]
        0x4770,                         // 06: bx lr
        _assign_32bit(&GPIOF->ODR),     // 08: Imm32
};

こんな感じでオペコードを書けば良さそうです。今回はマイコンに搭載されている ARM 命令のサブセット、Thumb2 のみをサポートすることにしました。また、ハードウェアは秋月で売られている STM32F042K6T6 を使うこととします。

電子部品,通販,販売,半導体,IC,マイコン,電子工作STM32マイコン STM32F042K6T6秋月電子通商 電子部品通信販売

では実際に実行する方法ですが、ひとまずプログラムカウンタにジャンプ先アドレスを記載すれば良いのです。そこで以下のようなアセンブリを書きました。

.section .text

.type execute, %function
.global execute
execute:
    mov pc, r0

やっていることは簡単、pc に第1引数 r0 の値を代入しているだけです。これだけで、次のクロックで指定したアドレスに強制ジャンプします。呼び出し方は

void execute(hword_t *addr);

execute(programBuffer);

と言った感じです。簡単ですね。上の programBuffer には「PF0 の LED をつけよ」と命令しているので、予め設定をしておけばいいですね。

void allInit() {
    RCC->AHBENR |= RCC_AHBENR_GPIOFEN;

    GPIOF->MODER &= ~GPIO_MODER_MODER0_Msk;
    GPIOF->MODER |= (GPIO_MODE_OUTPUT_PP << GPIO_MODER_MODER0_Pos);
    GPIOF->ODR = 0;
}

とりあえずこれでいいようです。

実行テスト

あとはこんな感じで実行します。

int main() {
    allInit();
    while(1) {
        execute(programBuffer);
    }
}

これで PF0 の LED がつくと思います。いい感じに動いていますね。以上、仕様と実行のテストでした。次回に続く。