www.mtkn.jp

Manuscripts for my personal webpage.
git clone https://git.mtkn.jp/www.mtkn.jp
Log | Files | Refs | README

commit 6533cdb8b7d9d742ad92e84d6d6aa556bd02e283
parent 77f964f5ce1fd8161aba0af654d67fe3844a71a5
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 22 Apr 2023 13:38:39 +0900

update

Diffstat:
Mman/draft/rp2040_1.html | 169+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mpub/draft/rp2040_1.html | 157+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mpub/rss.xml | 4++--
3 files changed, 313 insertions(+), 17 deletions(-)

diff --git a/man/draft/rp2040_1.html b/man/draft/rp2040_1.html @@ -348,7 +348,7 @@ fwrite32l(uint32_t d, FILE *f) uint8_t b; for (i = 0; i &lt; 32; i += 8) { b = (uint8_t) (d &gt;&gt; i & 0xff); - fwrite(&b, 1, 1, f); + fwrite(&amp;b, 1, 1, f); if (ferror(f)) { fprintf(stderr, "Fwrite32l: write error.\n"); return 0; @@ -497,14 +497,19 @@ RP2040の内蔵ROMの<code>0x00000018</code>番地に関数を検索するため 今回欲しい関数はフラッシュROMをXIPに設定するもの\ (<code>_flash_enter_cmd_xip()</code>)なので、<code>'C', 'X'</code>を渡す。\ 関数のポインタが返ってきたら、それを呼び出せばフラッシュROMとSSIはXIPモード\ -になる。 +になる: </p> <pre><code>\ - ldr r4, rom_base +.cpu cortex-m0plus +.thumb + + .section .boot2 +setup_xip: + ldr r3, rom_base - ldrh r0, [r4, #0x14] // rom_func_table + ldrh r0, [r3, #0x14] // rom_func_table ldr r1, =('C' | 'X' << 8) // _flash_enter_cmd_xip() - ldrh r2, [r4, #0x18] // rom_table_lookup + ldrh r2, [r3, #0x18] // rom_table_lookup blx r2 blx r0 /* ... */ @@ -538,15 +543,15 @@ m0plus_vtor: .word 0xe0000000 + 0xed08 </code></pre> -<h2>メインのコード<h2> +<h2>メインのコード(<code>main.s</code>)<h2> <h3>ベクターテーブル</h3> <p> メインのコードの最初には上で説明したベクターテーブルを配置する。\ ここでは割り込みの処理は考えないので、初期スタックポインタと\ -エントリーポイントだけである。初期スタックポインタはSRAMの最後\ +エントリーポイントだけである。初期スタックポインタはSRAMの最後?\ (<code>0x20040000</code>)、エントリーポイントはエントリーポイントの\ ラベルを用いて設定した。ただしこのCPUはThumbモードなので、\ -ラベルに<code>0x1</code>を足している[要説明]: +ラベルに<code>0x1</code>を足している[要説明?]: </p> <pre><code>\ .cpu cortex-m0plus @@ -557,9 +562,157 @@ vectors: .word 0x20040000 // initial SP .word (reset+1) </code></pre> + <h3>GPIOの設定</h3> +<pre><code>\ + .section .text +reset: + // unreset gpio + mov r0, #1 + lsl r0, r0, #5 // io_bank0 + ldr r3, resets_base + ldr r1, atomic_clr + str r0, [r3, r1] // RESETS: RESET + +reset_chk: + ldr r1, [r3, #0x8] // RESETS: RESET_DONE + and r0, r0, r1 + beq reset_chk + + // set gpio functions + ldr r3, io_bank0_base + mov r0, #5 // sio + mov r1, #0xcc + str r0, [r3, r1] // IO_BANK0: GPIO25_CTRL + + // enable gpio output + ldr r3, sio_base + mov r0, #1 + lsl r0, r0, #25 // gpio25 + str r0, [r3, #0x24] // SIO: GPIO_OE + +/* ... */ + +atomic_clr: + .word 0x00003000 +resets_base: + .word 0x4000c000 +io_bank0_base: + .word 0x40014000 +sio_base: + .word 0xd0000000 +</code></pre> + +<h3>LEDの点滅</h3> +<pre><code>\ + // blink led on gpio25 + ldr r4, sio_base + mov r5, r0 +loop: + str r5, [r4, #0x10] // SIO_GPIO_OUT_SET + bl delay + str r5, [r4, #0x18] // SIO_GPIO_OUT_CLR + bl delay + b loop + +delay: + mov r0, #1 + lsl r0, r0, #20 +delay_loop: + sub r0, r0, #1 + bne delay_loop + bx lr + +// literals + .align 2 +/* ... */ +sio_base: + .word 0xd0000000 +</code></pre> + +<h2>リンカスクリプト</h2> +<p> +以上のコードには<code>.boot2</code>、<code>.vectors</code>、<code>.text</code>\ +の3つのセクションが含まれる。<code>.boot2</code>はフラッシュの先頭から\ +256バイト(<code>0x100</code>)目まで、<code>.vectors</code>と<code>.text</code>\ +はその後ろに続くように配置する: +<pre><code>\ +MEMORY +{ + FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k +} + +SECTIONS +{ + .boot2 : { + *(.boot2) + . = 0x100; + } > FLASH + + .text : { + *(.vectors) + *(.text) + } > FLASH +} +</code></pre> + +<h2>Makefile</h2> +ディレクトリ構造: +<pre><code>\ +rp2040_baremetal +├── ex1 +│   ├── Makefile +│   ├── boot2.s +│   ├── main.s +│   └── memmap.ld +└── tools + ├── Makefile + ├── bin2uf2.c + └── bincrc.c +</code></pre> <p> +toolsディレクトリのMakefileは同じディレクトリのソースファイルを<code>cc</code>\ +でコンパイルするだけのものである(個人的な趣味で<code>tcc</code>を使っている)。\ +ex1ディレクトリのMakefileは以下の通り: +</p> +<pre><code>\ +AS = arm-none-eabi-as +LD = arm-none-eabi-ld +OBJCOPY = arm-none-eabi-objcopy +BINCRC = ../tools/bincrc +BIN2UF2 = ../tools/bin2uf2 + +MCPU = -mcpu=cortex-m0plus +ASFLAGS = $(MCPU) +CFLAGS = $(MCPU) -ffreestanding -nostartfiles -O0 -fpic -mthumb -c +LDFLAGS = --no-relax -nostdlib + +all: tools led.uf2 + +clean: + rm -f *.o *.elf *.uf2 *.bin + cd ../tools &amp;&amp; make clean + +.s.o: + $(AS) $(ASFLAGS) -o $@ $&lt; +led.elf: boot2.o main.o memmap.ld + $(LD) $(LDFLAGS) -o $@ -T memmap.ld boot2.o main.o + +led.bin: led.elf + $(OBJCOPY) -O binary led.elf $@ + +led.uf2: led.bin + $(BINCRC) led.bin led_crc.bin + $(BIN2UF2) led_crc.bin $@ + +flash: all + mount /dev/disk/by-label/RPI-RP2 /mnt + cp led.uf2 /mnt + +tools: + cd ../tools &amp;&amp; make +</code></pre> <h2>参考</h2> <ul> diff --git a/pub/draft/rp2040_1.html b/pub/draft/rp2040_1.html @@ -304,7 +304,7 @@ fwrite32l(uint32_t d, FILE *f) uint8_t b; for (i = 0; i &lt; 32; i += 8) { b = (uint8_t) (d &gt;&gt; i & 0xff); - fwrite(&b, 1, 1, f); + fwrite(&amp;b, 1, 1, f); if (ferror(f)) { fprintf(stderr, "Fwrite32l: write error.\n"); return 0; @@ -417,13 +417,18 @@ RP2040に電源を投入し、CRC32のチェックが通った後、フラッシ RP2040には内部にもROMがあり、中にはバージョン情報や、電源を投入した時の動作、その他便利な関数が書き込まれている。この関数のなかに外部のフラッシュROMとSSIコントローラを設定するものも含まれているので今回はこれを利用した。ただしこの方法だとフラッシュROMとの通信方式がStandard SPIのままなので少し遅い。詳しくはデータシート<sup>[3]</sup>の2.3.8. 「Bootrom Contents」を参照。 </p> <p> -RP2040の内蔵ROMの<code>0x00000018</code>番地に関数を検索するための関数がある。この関数に<code>0x00000014</code>番地の<code>rom_func_table</code>と、各関数に割り当てられた二文字の文字列を渡せば、欲しい関数へのポインタが返ってくる。なお、二文字の文字列はそれぞれASCIIコードで現し、二文字目を8ビットシフトしたものと1文字目のORを取ったものを渡すことになっている。今回欲しい関数はフラッシュROMをXIPに設定するもの(<code>_flash_enter_cmd_xip()</code>)なので、<code>'C', 'X'</code>を渡す。関数のポインタが返ってきたら、それを呼び出せばフラッシュROMとSSIはXIPモードになる。 +RP2040の内蔵ROMの<code>0x00000018</code>番地に関数を検索するための関数がある。この関数に<code>0x00000014</code>番地の<code>rom_func_table</code>と、各関数に割り当てられた二文字の文字列を渡せば、欲しい関数へのポインタが返ってくる。なお、二文字の文字列はそれぞれASCIIコードで現し、二文字目を8ビットシフトしたものと1文字目のORを取ったものを渡すことになっている。今回欲しい関数はフラッシュROMをXIPに設定するもの(<code>_flash_enter_cmd_xip()</code>)なので、<code>'C', 'X'</code>を渡す。関数のポインタが返ってきたら、それを呼び出せばフラッシュROMとSSIはXIPモードになる: </p> -<pre><code> ldr r4, rom_base +<pre><code>.cpu cortex-m0plus +.thumb + + .section .boot2 +setup_xip: + ldr r3, rom_base - ldrh r0, [r4, #0x14] // rom_func_table + ldrh r0, [r3, #0x14] // rom_func_table ldr r1, =('C' | 'X' << 8) // _flash_enter_cmd_xip() - ldrh r2, [r4, #0x18] // rom_table_lookup + ldrh r2, [r3, #0x18] // rom_table_lookup blx r2 blx r0 /* ... */ @@ -449,10 +454,10 @@ m0plus_vtor: .word 0xe0000000 + 0xed08 </code></pre> -<h2>メインのコード<h2> +<h2>メインのコード(<code>main.s</code>)<h2> <h3>ベクターテーブル</h3> <p> -メインのコードの最初には上で説明したベクターテーブルを配置する。ここでは割り込みの処理は考えないので、初期スタックポインタとエントリーポイントだけである。初期スタックポインタはSRAMの最後(<code>0x20040000</code>)、エントリーポイントはエントリーポイントのラベルを用いて設定した。ただしこのCPUはThumbモードなので、ラベルに<code>0x1</code>を足している[要説明]: +メインのコードの最初には上で説明したベクターテーブルを配置する。ここでは割り込みの処理は考えないので、初期スタックポインタとエントリーポイントだけである。初期スタックポインタはSRAMの最後?(<code>0x20040000</code>)、エントリーポイントはエントリーポイントのラベルを用いて設定した。ただしこのCPUはThumbモードなので、ラベルに<code>0x1</code>を足している[要説明?]: </p> <pre><code>.cpu cortex-m0plus .thumb @@ -462,9 +467,147 @@ vectors: .word 0x20040000 // initial SP .word (reset+1) </code></pre> + <h3>GPIOの設定</h3> +<pre><code> .section .text +reset: + // unreset gpio + mov r0, #1 + lsl r0, r0, #5 // io_bank0 + ldr r3, resets_base + ldr r1, atomic_clr + str r0, [r3, r1] // RESETS: RESET + +reset_chk: + ldr r1, [r3, #0x8] // RESETS: RESET_DONE + and r0, r0, r1 + beq reset_chk + + // set gpio functions + ldr r3, io_bank0_base + mov r0, #5 // sio + mov r1, #0xcc + str r0, [r3, r1] // IO_BANK0: GPIO25_CTRL + + // enable gpio output + ldr r3, sio_base + mov r0, #1 + lsl r0, r0, #25 // gpio25 + str r0, [r3, #0x24] // SIO: GPIO_OE + +/* ... */ + +atomic_clr: + .word 0x00003000 +resets_base: + .word 0x4000c000 +io_bank0_base: + .word 0x40014000 +sio_base: + .word 0xd0000000 +</code></pre> + +<h3>LEDの点滅</h3> +<pre><code> // blink led on gpio25 + ldr r4, sio_base + mov r5, r0 +loop: + str r5, [r4, #0x10] // SIO_GPIO_OUT_SET + bl delay + str r5, [r4, #0x18] // SIO_GPIO_OUT_CLR + bl delay + b loop + +delay: + mov r0, #1 + lsl r0, r0, #20 +delay_loop: + sub r0, r0, #1 + bne delay_loop + bx lr + +// literals + .align 2 +/* ... */ +sio_base: + .word 0xd0000000 +</code></pre> + +<h2>リンカスクリプト</h2> <p> +以上のコードには<code>.boot2</code>、<code>.vectors</code>、<code>.text</code>の3つのセクションが含まれる。<code>.boot2</code>はフラッシュの先頭から256バイト(<code>0x100</code>)目まで、<code>.vectors</code>と<code>.text</code>はその後ろに続くように配置する: +<pre><code>MEMORY +{ + FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k +} +SECTIONS +{ + .boot2 : { + *(.boot2) + . = 0x100; + } > FLASH + + .text : { + *(.vectors) + *(.text) + } > FLASH +} +</code></pre> + +<h2>Makefile</h2> +ディレクトリ構造: +<pre><code>rp2040_baremetal +├── ex1 +│   ├── Makefile +│   ├── boot2.s +│   ├── main.s +│   └── memmap.ld +└── tools + ├── Makefile + ├── bin2uf2.c + └── bincrc.c +</code></pre> +<p> +toolsディレクトリのMakefileは同じディレクトリのソースファイルを<code>cc</code>でコンパイルするだけのものである(個人的な趣味で<code>tcc</code>を使っている)。ex1ディレクトリのMakefileは以下の通り: +</p> +<pre><code>AS = arm-none-eabi-as +LD = arm-none-eabi-ld +OBJCOPY = arm-none-eabi-objcopy +BINCRC = ../tools/bincrc +BIN2UF2 = ../tools/bin2uf2 + +MCPU = -mcpu=cortex-m0plus +ASFLAGS = $(MCPU) +CFLAGS = $(MCPU) -ffreestanding -nostartfiles -O0 -fpic -mthumb -c +LDFLAGS = --no-relax -nostdlib + +all: tools led.uf2 + +clean: + rm -f *.o *.elf *.uf2 *.bin + cd ../tools &amp;&amp; make clean + +.s.o: + $(AS) $(ASFLAGS) -o $@ $&lt; + +led.elf: boot2.o main.o memmap.ld + $(LD) $(LDFLAGS) -o $@ -T memmap.ld boot2.o main.o + +led.bin: led.elf + $(OBJCOPY) -O binary led.elf $@ + +led.uf2: led.bin + $(BINCRC) led.bin led_crc.bin + $(BIN2UF2) led_crc.bin $@ + +flash: all + mount /dev/disk/by-label/RPI-RP2 /mnt + cp led.uf2 /mnt + +tools: + cd ../tools &amp;&amp; make +</code></pre> <h2>参考</h2> <ul> diff --git a/pub/rss.xml b/pub/rss.xml @@ -5,8 +5,8 @@ <description>ウェブページの更新履歴</description> <language>ja-jp</language> <link>https://www.mtkn.jp</link> -<lastBuildDate>Fri, 21 Apr 2023 19:15:50 +0900</lastBuildDate> -<pubDate>Fri, 21 Apr 2023 19:15:50 +0900</pubDate> +<lastBuildDate>Sat, 22 Apr 2023 13:38:27 +0900</lastBuildDate> +<pubDate>Sat, 22 Apr 2023 13:38:27 +0900</pubDate> <docs>https://www.rssboard.org/rss-specification</docs> <item> <title>Xlibで遊んでみる6</title>