目次: OpenOCD
OpenOCDではSiFive HiFive1のSPI Flashへの書き込み&消去ができます。しかしSiFive HiFive UnleashedのSPI Flashに対しては正常に動作しません。書き込みは成功しますが、消去はできません。一見すると成功しているのに一切データが消去できない謎の現象が発生します。
HiFive UnleashedのSPI FlashにOpenOCDで書き込み&消去を行った例を示します。OpenOCDの制御方法は何通りかあります。直接制御したい場合はポート4444にtelnetすると良いです。
$ telnet localhost 4444 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > reset halt JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2)
私はGDB経由で制御するほうが慣れているので、GDB経由で制御します。GDBの場合はポート3333に接続します。この例ではZephyr用のツールチェーンに含まれるGDBを使っていますが、RV64に対応していれば何でも良いです(RV32専用ではダメです、UnleashedのCPUはRV64なので)。
$ riscv64-zephyr-elf-gdb (gdb) set arch riscv:rv64 The target architecture is assumed to be riscv:rv64 (gdb) target remote :3333 Remote debugging using :3333 (gdb) monitor reset halt JTAG tap: riscv.cpu tap/device found: 0x20000913 (mfg: 0x489 (SiFive Inc), part: 0x0000, ver: 0x2) ★★monitor xxxxはremote monitor(この場合OpenOCD)へのコマンドと解釈される (gdb) monitor flash probe 0 Found flash device 'issi is25wp256d' (ID 0x0019709d) device needs paging or 4-byte addresses - not implemented ★★ん?なんだこれ flash 'fespi' found at 0x20000000 (gdb) x/32x 0x20000000 0x20000000: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000010: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000020: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000030: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000040: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000050: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000060: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000070: 0xffffffff 0xffffffff 0xffffffff 0xffffffff (gdb) monitor flash fillw 0x20000000 0xddccbbaa 0x10 Disabling abstract command writes to CSRs. wrote 64 bytes to 0x20000000 in 0.203977s (0.306 KiB/s) ★★書き込みに成功 (gdb) x/32x 0x20000000 0x20000000: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000010: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000020: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000030: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000040: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000050: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000060: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000070: 0xffffffff 0xffffffff 0xffffffff 0xffffffff ★★書き込めた (gdb) monitor flash erase_address 0x20000000 0x10000 erased address 0x20000000 (length 65536) in 0.204166s (313.470 KiB/s) ★★消去も成功したように見えるものの (gdb) x/32x 0x20000000 0x20000000: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000010: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000020: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000030: 0xddccbbaa 0xddccbbaa 0xddccbbaa 0xddccbbaa 0x20000040: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000050: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000060: 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0x20000070: 0xffffffff 0xffffffff 0xffffffff 0xffffffff ★★消えないぞ……?
書き込めるのに消せないとは?これいかに?この謎を追います。最初にOpenOCDがどうやってSPI Flashを書き換えているのか?次にどうやって消去しているのか?を追います。妙な警告メッセージが出ている点も気になります。
その名の通りSPIで接続されたFlashメモリデバイスのことです。SPIはSerial Peripheral Interfaceの略で、CE#(Chip EnableもしくはChip Select, CS# とも)、SCLK、SDI、SDOの4線で構成される非常にシンプルなI/Oバスです。
個人的には「入力と出力が常に同時に行われるのがSPIの大きな特徴」に思います。
SPIの入出力波形の例(SPI FlashのRead Product Identificationコマンド)
例えばこの波形図ではSoCからSPI FlashにInstruction(0xAB) と3バイトのダミーデータを出力(SI側の信号)しているとき、SPI FlashからSoCに意味のないデータが返ってきます(SO側の信号)。
入出力が別々に行われるバス(Ethernetなど)に慣れていると、無意味なデータを受け取る=無駄なリクエストを相手に送っている、ことを示しますから、無駄な入力はやめてくれ〜としばらく混乱しました。しかしまあ、わかってしまえば非常に単純な話でして、常に入出力が同時に行われる仕様なので、無駄は発生していません。また、無意味な入力データは受け取った後に無視すれば良いだけです。
続きはまた次回。
< | 2021 | > | ||||
<< | < | 07 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.18.
using GD 2.3.3(png support.)