commit f74aec8c5c22c05cf9f0739693c8b1e0ebd4683f
parent 2d139ca218e9ebd74e071f2ae51d21bd90451490
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 27 Aug 2025 09:54:49 +0900
add new article for rp2040
Diffstat:
5 files changed, 569 insertions(+), 2 deletions(-)
diff --git a/data/weblog b/data/weblog
@@ -92,3 +92,21 @@
1752678000 /gallery/index.html
1752678000 /index.html
1752678000 /gallery/20250717.html
+1756134000 /computer/rp2040_3_interrupt.html
+1756134000 /computer/rp2040_3_interrupt.html
+1756134000 /computer/rp2040_3_interrupt.html
+1756134000 /computer/rp2040_3_interrupt.html
+1756134000 /computer/rp2040_3_interrupt.html
+1756134000 /computer/rp2040_3_interrupt.html
+1756134000 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
+1756220400 /computer/rp2040_3_interrupt.html
diff --git a/man/computer/rp2040_3_interrupt.html b/man/computer/rp2040_3_interrupt.html
@@ -0,0 +1,197 @@
+<h1>RP2040 SDKなし3 割り込み</h1>
+<time>2025-08-26</time><br />
+<p>
+前回UARTで通信する際、FIFOにデータが届いていないかを確認しつづけていた(ポーリング)。
+これでは電力がもったいないので、データが届くまでCPUは休ませておいて、
+届いたときだけ処理を実行するように変更する(割り込み)。
+<p>
+<p>
+前回: <a href="rp2040_2.html">RP2040 SDKなし2 Clock、UART</a><br>
+ソースコード: <a href="https://git.mtkn.jp/rp2040">git</a>/ex3_interrupt
+</p>
+
+<h2>動作環境</h2>
+<ul>
+<li>OpenBSD 7.7
+ <ul>
+ <li>arm-none-eabi-binutils-2.40</li>
+ <li>OpenBSD Make</li>
+ <li>minicom version 2.8</li>
+ </ul>
+</li>
+<li><a href="https://akizukidenshi.com/catalog/g/g108461/">FT234X 超小型USBシリアル変換モジュール</a>
+</li>
+</ul>
+
+<h2>割り込み</h2>
+<p>
+ハードウェアが外部から信号を受けとると、CPUに現在の処理を中断させてその信号を処理させるようにできる。\
+これを割り込み処理という。\
+今回はUARTにデータが届いた時に同じデータをUARTに書き込むようにしたい。\
+</p>
+
+<h3>割り込みを有効化</h3>
+<p>
+割り込みの信号を受け取るために、割り込みを有効化する。\
+CPUが割り込みを受け付けるようにする設定と、\
+UARTが割り込み信号を発生させるようにする設定が必要である。\
+</p>
+<p>
+CPU側の設定は<code>M0PLUS: NVIC_ISER</code>レジスタの有効化したい割り込みのビットに1を書くことで行う。\
+有効化できる割り込みは全部で26個ある。\
+割り込みの種類はrp2040のデータシート[1]のTable 80. Interruptsに書いてある。\
+今回有効化するのはUART0の割り込みで、この表から20番が割り当てられていることが分かるので、\
+<code>M0PLUS: NVIC_ISER</code>に、下から20番目のビットを1にしたもの書き込む:\
+</p>
+<code><pre> // enable uart interrupt in cpu
+ ldr r4, ppb_base
+ mov r5, #0xe1
+ lsl r5, #8
+ mov r0, #1
+ lsl r0, #20
+ str r0, [r4, r5] // M0PLUS: NVIC_ISER
+
+/* ... */
+
+ppb_base:
+ .word 0xe0000000
+</pre></code>
+<p>
+UART側の設定は、<code>UART: UARTIMSC</code>レジスタで行なう。\
+データを受け取ったときに割り込みを発生させたいので、\
+<code>RXIM</code>ビットに1を書き込む。\
+また、処理を開始する前に既にFIFOにデータがたまっている可能性があるので、\
+FIFOが空ではないときに割り込みを発生させるように、\
+<code>RTIM</code>にも1を書き込む:\
+</p>
+<code><pre> // enable uart interrupt in uart0 subsystem
+ ldr r1, uart0_base
+ mov r2, #(1 << 6 | 1 << 4) // RTIM | RXIM
+ str r2, [r1, #0x38] // UART: UARTIMSC
+</pre></code>
+<p>
+また、FIFOにデータがきたらすぐに割り込みを発生させたいので、\
+<code>UART: UARTIFLS</code>レジスタの<code>RXIFLSEL</code>に0を書き込む。\
+これでFIFOの1/8が埋まったら割り込みが発生する。\
+</p>
+<code><pre> // set fifo level to 0
+ mov r2, #0
+ str r2, [r1, #0x34] // UART: UARTIFLS
+</pre></code>
+<p>
+これだとFIFOに届いた瞬間には割り込みがおこらない気がするが、\
+pico-sdk(src/rp2_common/hardware_uart/include/hardware/uart.h)の\
+<code>uart_set_irqs_enabled</code>関数でもこうなってる。\
+FIFOを無効にすれば即座に割り込みがおこるかもしれないが、\
+データが失われる可能性もあるのかな。\
+</p>
+
+<h3>ベクターテーブルの設定</h3>
+<p>
+外部からの信号で割り込みが発生したときにCPUに行わせる処理はベクターテーブルにあらかじめ登録しておく必要がある。\
+ベクターテーブルの場所は<a href="rp2040_1.html">一回目</a>に登録した通り\
+<code>vectors</code>とラベルを付けた場所(main.sの先頭)である。\
+ARMの仕様書[2]によると、ベクターテーブルの0番目は初期のスタックポインタで、\
+そこから15個はARMによって使用用途が定められている。\
+16番以降の32個は各CPUの設計者が自由に決められる。\
+rp2040の割り込みについてはデータシート[1]のTable 80. Interruptsに一覧表が載っている。\
+今回使いたいのはUART0の割り込みなので16 + 20 = 36番目に、割り込み時に呼ばれたい関数のポインタ\
+(Thumb Modeなので関数のアドレスに1を足したもの)を書き込めばいい。\
+それ以外のものは今回は使わないので適当な数値でうめておく:\
+</p>
+<code><pre> .global vectors
+vectors:
+ .word 0x20040000 // initial SP
+ .word (reset+1) // entry point
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word (uart_interrupt_handler+1) // UART0_IRQ
+</pre></code>
+
+<h3>割り込み処理</h3>
+<p>
+割り込み発生時に呼ばれる関数はUARTのFIFOに届いたデータをそのまま送信するだけのものである:\
+</p>
+<code><pre> // uart_interrupt_handler echos the data arrived at uart0
+uart_interrupt_handler:
+ push {lr}
+ bl getbyte
+ bl putbyte
+ pop {pc}
+</pre></code>
+<p>
+<code>getbyte</code>、<code>putbyte</code>は前回と同じもの。
+</code>
+
+<h2>メインループ</h2>
+<p>
+UARTにデータが届いていないときは特にすることがないので\
+CPUは寝かせておく。\
+ARMには割り込みが発生するまでなにもしない<code>wfe</code>という命令があるのでこれを使う:\
+</p>
+<code><pre>\
+loop:
+ wfe
+ b loop
+</pre></code>
+
+<h2>完成</h2>
+<p>
+これで完成。\
+動作は前回と全く同じだが、消費電力をおさえられる。\
+</p>
+
+<h2>参考</h2>
+<ul>
+<li>
+[1]. <a href="https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf">RP2040 Datasheet.Raspberry Pi Foundation</a>
+</li>
+<li>
+[2]. <a href="https://developer.arm.com/documentation/ddi0419/c/">ARMv6-M Architecture Reference Manual</a>
+</li>
+<li>
+[3]. <a href="https://github.com/raspberrypi/pico-sdk">pico-sdk.github</a>
+</li>
+</ul>
diff --git a/pub/computer/rp2040_3_interrupt.html b/pub/computer/rp2040_3_interrupt.html
@@ -0,0 +1,189 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" type="image/x-icon" href="/pics/favicon.ico">
+ <title>RP2040 SDKなし3 割り込み</title>
+</head>
+<body>
+ <header>
+ <a href="/">主頁</a> |
+ <a href="/about.html">自己紹介</a> |
+ <a href="/journal">日記</a> |
+ <a href="/farm">農業</a> |
+ <a href="/kitchen">台所</a> |
+ <a href="/computer">電算機</a> |
+ <a href="/poetry">詩</a> |
+ <a href="/books">本棚</a> |
+ <a href="/gallery">絵</a> |
+ <a href="/plant">植物</a> |
+ <a href="https://git.mtkn.jp">Git</a>
+ </header>
+ <main>
+ <article>
+<h1>RP2040 SDKなし3 割り込み</h1>
+<time>2025-08-26</time><br />
+<p>
+前回UARTで通信する際、FIFOにデータが届いていないかを確認しつづけていた(ポーリング)。
+これでは電力がもったいないので、データが届くまでCPUは休ませておいて、
+届いたときだけ処理を実行するように変更する(割り込み)。
+<p>
+<p>
+前回: <a href="rp2040_2.html">RP2040 SDKなし2 Clock、UART</a><br>
+ソースコード: <a href="https://git.mtkn.jp/rp2040">git</a>/ex3_interrupt
+</p>
+
+<h2>動作環境</h2>
+<ul>
+<li>OpenBSD 7.7
+ <ul>
+ <li>arm-none-eabi-binutils-2.40</li>
+ <li>OpenBSD Make</li>
+ <li>minicom version 2.8</li>
+ </ul>
+</li>
+<li><a href="https://akizukidenshi.com/catalog/g/g108461/">FT234X 超小型USBシリアル変換モジュール</a>
+</li>
+</ul>
+
+<h2>割り込み</h2>
+<p>
+ハードウェアが外部から信号を受けとると、CPUに現在の処理を中断させてその信号を処理させるようにできる。これを割り込み処理という。今回はUARTにデータが届いた時に同じデータをUARTに書き込むようにしたい。</p>
+
+<h3>割り込みを有効化</h3>
+<p>
+割り込みの信号を受け取るために、割り込みを有効化する。CPUが割り込みを受け付けるようにする設定と、UARTが割り込み信号を発生させるようにする設定が必要である。</p>
+<p>
+CPU側の設定は<code>M0PLUS: NVIC_ISER</code>レジスタの有効化したい割り込みのビットに1を書くことで行う。有効化できる割り込みは全部で26個ある。割り込みの種類はrp2040のデータシート[1]のTable 80. Interruptsに書いてある。今回有効化するのはUART0の割り込みで、この表から20番が割り当てられていることが分かるので、<code>M0PLUS: NVIC_ISER</code>に、下から20番目のビットを1にしたもの書き込む:</p>
+<code><pre> // enable uart interrupt in cpu
+ ldr r4, ppb_base
+ mov r5, #0xe1
+ lsl r5, #8
+ mov r0, #1
+ lsl r0, #20
+ str r0, [r4, r5] // M0PLUS: NVIC_ISER
+
+/* ... */
+
+ppb_base:
+ .word 0xe0000000
+</pre></code>
+<p>
+UART側の設定は、<code>UART: UARTIMSC</code>レジスタで行なう。データを受け取ったときに割り込みを発生させたいので、<code>RXIM</code>ビットに1を書き込む。また、処理を開始する前に既にFIFOにデータがたまっている可能性があるので、FIFOが空ではないときに割り込みを発生させるように、<code>RTIM</code>にも1を書き込む:</p>
+<code><pre> // enable uart interrupt in uart0 subsystem
+ ldr r1, uart0_base
+ mov r2, #(1 << 6 | 1 << 4) // RTIM | RXIM
+ str r2, [r1, #0x38] // UART: UARTIMSC
+</pre></code>
+<p>
+また、FIFOにデータがきたらすぐに割り込みを発生させたいので、<code>UART: UARTIFLS</code>レジスタの<code>RXIFLSEL</code>に0を書き込む。これでFIFOの1/8が埋まったら割り込みが発生する。</p>
+<code><pre> // set fifo level to 0
+ mov r2, #0
+ str r2, [r1, #0x34] // UART: UARTIFLS
+</pre></code>
+<p>
+これだとFIFOに届いた瞬間には割り込みがおこらない気がするが、pico-sdk(src/rp2_common/hardware_uart/include/hardware/uart.h)の<code>uart_set_irqs_enabled</code>関数でもこうなってる。FIFOを無効にすれば即座に割り込みがおこるかもしれないが、データが失われる可能性もあるのかな。</p>
+
+<h3>ベクターテーブルの設定</h3>
+<p>
+外部からの信号で割り込みが発生したときにCPUに行わせる処理はベクターテーブルにあらかじめ登録しておく必要がある。ベクターテーブルの場所は<a href="rp2040_1.html">一回目</a>に登録した通り<code>vectors</code>とラベルを付けた場所(main.sの先頭)である。ARMの仕様書[2]によると、ベクターテーブルの0番目は初期のスタックポインタで、そこから15個はARMによって使用用途が定められている。16番以降の32個は各CPUの設計者が自由に決められる。rp2040の割り込みについてはデータシート[1]のTable 80. Interruptsに一覧表が載っている。今回使いたいのはUART0の割り込みなので16 + 20 = 36番目に、割り込み時に呼ばれたい関数のポインタ(Thumb Modeなので関数のアドレスに1を足したもの)を書き込めばいい。それ以外のものは今回は使わないので適当な数値でうめておく:</p>
+<code><pre> .global vectors
+vectors:
+ .word 0x20040000 // initial SP
+ .word (reset+1) // entry point
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word (uart_interrupt_handler+1) // UART0_IRQ
+</pre></code>
+
+<h3>割り込み処理</h3>
+<p>
+割り込み発生時に呼ばれる関数はUARTのFIFOに届いたデータをそのまま送信するだけのものである:</p>
+<code><pre> // uart_interrupt_handler echos the data arrived at uart0
+uart_interrupt_handler:
+ push {lr}
+ bl getbyte
+ bl putbyte
+ pop {pc}
+</pre></code>
+<p>
+<code>getbyte</code>、<code>putbyte</code>は前回と同じもの。
+</code>
+
+<h2>メインループ</h2>
+<p>
+UARTにデータが届いていないときは特にすることがないのでCPUは寝かせておく。ARMには割り込みが発生するまでなにもしない<code>wfe</code>という命令があるのでこれを使う:</p>
+<code><pre>loop:
+ wfe
+ b loop
+</pre></code>
+
+<h2>完成</h2>
+<p>
+これで完成。動作は前回と全く同じだが、消費電力をおさえられる。</p>
+
+<h2>参考</h2>
+<ul>
+<li>
+[1]. <a href="https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf">RP2040 Datasheet.Raspberry Pi Foundation</a>
+</li>
+<li>
+[2]. <a href="https://developer.arm.com/documentation/ddi0419/c/">ARMv6-M Architecture Reference Manual</a>
+</li>
+<li>
+[3]. <a href="https://github.com/raspberrypi/pico-sdk">pico-sdk.github</a>
+</li>
+</ul>
+ </article>
+
+ </main>
+ <footer>
+ <address>info(at)mtkn(dot)jp</address>
+ <a href="http://creativecommons.org/publicdomain/zero/1.0?ref=chooser-v1" rel="license noopener noreferrer">CC0 1.0</a>
+ </footer>
+</body>
+</html>
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>Thu, 17 Jul 2025 19:29:08 +0900</lastBuildDate>
-<pubDate>Thu, 17 Jul 2025 19:29:08 +0900</pubDate>
+<lastBuildDate>Wed, 27 Aug 2025 09:51:52 +0900</lastBuildDate>
+<pubDate>Wed, 27 Aug 2025 09:51:52 +0900</pubDate>
<docs>https://www.rssboard.org/rss-specification</docs>
<item>
<title>9P</title>
@@ -372,6 +372,168 @@ size[4] Rwstat tag[2]
]]></description>
</item>
<item>
+<title>RP2040 SDKなし3 割り込み</title>
+<link>https://www.mtkn.jp/computer/rp2040_3_interrupt.html</link>
+<guid>https://www.mtkn.jp/computer/rp2040_3_interrupt.html</guid>
+<pubDate>Wed, 27 Aug 2025 00:00:00 +0900</pubDate>
+<description><![CDATA[<h1>RP2040 SDKなし3 割り込み</h1>
+<time>2025-08-26</time><br />
+<p>
+前回UARTで通信する際、FIFOにデータが届いていないかを確認しつづけていた(ポーリング)。
+これでは電力がもったいないので、データが届くまでCPUは休ませておいて、
+届いたときだけ処理を実行するように変更する(割り込み)。
+<p>
+<p>
+前回: <a href="rp2040_2.html">RP2040 SDKなし2 Clock、UART</a><br>
+ソースコード: <a href="https://git.mtkn.jp/rp2040">git</a>/ex3_interrupt
+</p>
+
+<h2>動作環境</h2>
+<ul>
+<li>OpenBSD 7.7
+ <ul>
+ <li>arm-none-eabi-binutils-2.40</li>
+ <li>OpenBSD Make</li>
+ <li>minicom version 2.8</li>
+ </ul>
+</li>
+<li><a href="https://akizukidenshi.com/catalog/g/g108461/">FT234X 超小型USBシリアル変換モジュール</a>
+</li>
+</ul>
+
+<h2>割り込み</h2>
+<p>
+ハードウェアが外部から信号を受けとると、CPUに現在の処理を中断させてその信号を処理させるようにできる。これを割り込み処理という。今回はUARTにデータが届いた時に同じデータをUARTに書き込むようにしたい。</p>
+
+<h3>割り込みを有効化</h3>
+<p>
+割り込みの信号を受け取るために、割り込みを有効化する。CPUが割り込みを受け付けるようにする設定と、UARTが割り込み信号を発生させるようにする設定が必要である。</p>
+<p>
+CPU側の設定は<code>M0PLUS: NVIC_ISER</code>レジスタの有効化したい割り込みのビットに1を書くことで行う。有効化できる割り込みは全部で26個ある。割り込みの種類はrp2040のデータシート[1]のTable 80. Interruptsに書いてある。今回有効化するのはUART0の割り込みで、この表から20番が割り当てられていることが分かるので、<code>M0PLUS: NVIC_ISER</code>に、下から20番目のビットを1にしたもの書き込む:</p>
+<code><pre> // enable uart interrupt in cpu
+ ldr r4, ppb_base
+ mov r5, #0xe1
+ lsl r5, #8
+ mov r0, #1
+ lsl r0, #20
+ str r0, [r4, r5] // M0PLUS: NVIC_ISER
+
+/* ... */
+
+ppb_base:
+ .word 0xe0000000
+</pre></code>
+<p>
+UART側の設定は、<code>UART: UARTIMSC</code>レジスタで行なう。データを受け取ったときに割り込みを発生させたいので、<code>RXIM</code>ビットに1を書き込む。また、処理を開始する前に既にFIFOにデータがたまっている可能性があるので、FIFOが空ではないときに割り込みを発生させるように、<code>RTIM</code>にも1を書き込む:</p>
+<code><pre> // enable uart interrupt in uart0 subsystem
+ ldr r1, uart0_base
+ mov r2, #(1 << 6 | 1 << 4) // RTIM | RXIM
+ str r2, [r1, #0x38] // UART: UARTIMSC
+</pre></code>
+<p>
+また、FIFOにデータがきたらすぐに割り込みを発生させたいので、<code>UART: UARTIFLS</code>レジスタの<code>RXIFLSEL</code>に0を書き込む。これでFIFOの1/8が埋まったら割り込みが発生する。</p>
+<code><pre> // set fifo level to 0
+ mov r2, #0
+ str r2, [r1, #0x34] // UART: UARTIFLS
+</pre></code>
+<p>
+これだとFIFOに届いた瞬間には割り込みがおこらない気がするが、pico-sdk(src/rp2_common/hardware_uart/include/hardware/uart.h)の<code>uart_set_irqs_enabled</code>関数でもこうなってる。FIFOを無効にすれば即座に割り込みがおこるかもしれないが、データが失われる可能性もあるのかな。</p>
+
+<h3>ベクターテーブルの設定</h3>
+<p>
+外部からの信号で割り込みが発生したときにCPUに行わせる処理はベクターテーブルにあらかじめ登録しておく必要がある。ベクターテーブルの場所は<a href="rp2040_1.html">一回目</a>に登録した通り<code>vectors</code>とラベルを付けた場所(main.sの先頭)である。ARMの仕様書[2]によると、ベクターテーブルの0番目は初期のスタックポインタで、そこから15個はARMによって使用用途が定められている。16番以降の32個は各CPUの設計者が自由に決められる。rp2040の割り込みについてはデータシート[1]のTable 80. Interruptsに一覧表が載っている。今回使いたいのはUART0の割り込みなので16 + 20 = 36番目に、割り込み時に呼ばれたい関数のポインタ(Thumb Modeなので関数のアドレスに1を足したもの)を書き込めばいい。それ以外のものは今回は使わないので適当な数値でうめておく:</p>
+<code><pre> .global vectors
+vectors:
+ .word 0x20040000 // initial SP
+ .word (reset+1) // entry point
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+ .word 0xdeadbeef
+
+ .word (uart_interrupt_handler+1) // UART0_IRQ
+</pre></code>
+
+<h3>割り込み処理</h3>
+<p>
+割り込み発生時に呼ばれる関数はUARTのFIFOに届いたデータをそのまま送信するだけのものである:</p>
+<code><pre> // uart_interrupt_handler echos the data arrived at uart0
+uart_interrupt_handler:
+ push {lr}
+ bl getbyte
+ bl putbyte
+ pop {pc}
+</pre></code>
+<p>
+<code>getbyte</code>、<code>putbyte</code>は前回と同じもの。
+</code>
+
+<h2>メインループ</h2>
+<p>
+UARTにデータが届いていないときは特にすることがないのでCPUは寝かせておく。ARMには割り込みが発生するまでなにもしない<code>wfe</code>という命令があるのでこれを使う:</p>
+<code><pre>loop:
+ wfe
+ b loop
+</pre></code>
+
+<h2>完成</h2>
+<p>
+これで完成。動作は前回と全く同じだが、消費電力をおさえられる。</p>
+
+<h2>参考</h2>
+<ul>
+<li>
+[1]. <a href="https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf">RP2040 Datasheet.Raspberry Pi Foundation</a>
+</li>
+<li>
+[2]. <a href="https://developer.arm.com/documentation/ddi0419/c/">ARMv6-M Architecture Reference Manual</a>
+</li>
+<li>
+[3]. <a href="https://github.com/raspberrypi/pico-sdk">pico-sdk.github</a>
+</li>
+</ul>
+]]></description>
+</item>
+<item>
<title>自画像</title>
<link>https://www.mtkn.jp/gallery/20250717.html</link>
<guid>https://www.mtkn.jp/gallery/20250717.html</guid>
diff --git a/pub/sitemap.xml b/pub/sitemap.xml
@@ -3,6 +3,7 @@
<url><loc>https://www.mtkn.jp/computer/9p.html</loc><lastmod>2025-12-19</lastmod></url>
<url><loc>https://www.mtkn.jp/journal/posts/20241211.html</loc><lastmod>2025-12-11</lastmod></url>
<url><loc>https://www.mtkn.jp/journal/posts/20241202.html</loc><lastmod>2025-12-02</lastmod></url>
+<url><loc>https://www.mtkn.jp/computer/rp2040_3_interrupt.html</loc><lastmod>2025-08-27</lastmod></url>
<url><loc>https://www.mtkn.jp/</loc><lastmod>2025-07-17</lastmod></url>
<url><loc>https://www.mtkn.jp/gallery/</loc><lastmod>2025-07-17</lastmod></url>
<url><loc>https://www.mtkn.jp/gallery/20250717.html</loc><lastmod>2025-07-17</lastmod></url>