STM32H7を使ってみる8 〜SDカードの初期化で大バグを仕込み、しかも6年間放置してた件〜
←前回                       次回→
北神雄太さんのZennの記事を読んでてねむいさんも少し気を付けようと
思いました。ソースコードの確認ミスや仕様の見落としで誤った結果を
世に出してしまわないようにと・・・。
…と気を引き締めた矢先、自身が公開しているソースコードに
とんでもない爆弾を発見してしまいましたorz
●罪状
➡STM32H7のFatFs移植例(SDMMCインターフェース)で、
 "CMD6発行によるHigh Speed Modeへの移行処理"を
 せずにSDカードのクロックを25->50MHzに上げていた。
 それをソースコード公開時から約6年間放置した上
 さらにSTM32L5,STM32H5に同じバグを拡大させた。
ねむいさんの公開しているSTM32H7(STM32H747I-Disco)向けのFatFs
実装例はSDMMCインターフェースを使ってSDカード/MMCとデータの
読み書きをするようにしております。
その初期化の部分でSDカードのクロックをデフォルトスピードの
25MHzから50MHzに引き上げる操作を行っているつもりでした。
本来はCMD6コマンドを発行し、SDカードがハイスピードモードに
切り替わったことを確認して初めて50MHzに引き上げることができるの
ですがその操作を行わないままいきなり50MHzにクロックを上げて
しまっておりましたorz
SDXCの初期化の例をとると本来の初期化は下記を想定してました。
CMD0発行、カードリセット
↓
CMD8発行、SDv2初期化
↓
CMD55+ACMD41をレスポンスが有効になるまで実行
↓
CMD2発行、CID取得
↓
CMD3発行、RCA取得
↓
CMD9発行、CSD取得
↓
CMD7発行、RCA設定
↓
CMD55+ACMD13発行、SCR取得
↓
CMD55+ACMD6発行、4bitバスモード移行
(ここで4bitバスアクセスに変更)
↓
CMD6発行、ハイスピードモード移行
(ここで供給クロックを50MHzに変更)
↓
CMD16発行、ブロックサイズを512バイトに設定
(ここで読み書きのための全部の準備が完了)
↓
以後CMD17/CMD18とかCMD24/CMD25でデータ読み書き
☝バグのコードでは上記のCMD55+ACMD6とCMD16の間でCMD6の発行を
せず、ACMD6発行後に4bitに切り替えと同時に50MHzにクロックを上げて
しまっていました。
なお、"SDカード"を使用した際のみこのバグが発動し、MMC/eMMCの
初期化の際はCMD6が正しい順序で発行したうえでクロック周波数を
引きあげていたので問題はありません。
●何が起こる?
➡読み書きの操作(CMD17/CMD18やCMD24/CMD25実行)
 を行った時に以後の応答を一切しなくなる可能性がある
"可能性がある"というのはすべてのSDカードで発生するのではなく、
ごく一部のカードで起こっているからです。
ていうか私の持ってるカードの中では1枚のカードだけが操作不能に
なることに気づきました…!

それがこのカード、TranscendのTS20GUSG240Iです…。
SLCモードを搭載し、230Iと比較し書き込み耐量がさらに上昇した
カードとなります。2024年の秋に購入していました。
最初にSTM32H5-Nucleoで使った際に"認識"できず、STM32H7-Discoで
使っても"認識"できなかったのでこのカードはハイスピードモードでは
使用できない"個体不良"なのだろうと思い込みソースコードレベルの
デバッグも行わないまま捨ておきましたが…
冒頭の北神さんの記事を読んでこのカードのことを思い返して
改めてソースコードレベルのデバッグにて初期化の流れを一から
追ったら自身の大チョンボを発見してしまった次第ですorz

ちなみに発覚前はCMD17/18とかCMD24/25の発行時に10uSecくらいの
待ち時間を突っ込むとなんでか読み書きできるのを発見したので
それで茶を濁しておりました…今思えばなんて愚かしいことを…
最初にSTM32H7を触ってSDMMCを使い始めた時にデバッガでソース
コードレベルでプログラムの流れ追っかけて確認するの面倒くさがって
やっておらず、当時の手持ちのカード全部認識できてるし"動いたから
これでよし"と思い込んだのがすべての原因です…すべては私の責…!!
ただねむいさんが悪い!ただねむいさんが悪い!
●バグの影響範囲は?
➡ねむいさんのおきぱで紹介しているFatFsの移植例の中で、
 STM32H7,STM32L5,STM32H5のものが対象。
何でこうなったかというと最初にSTM32H7で作成したバグ入りのSDMMCの
アクセスライブラリをSTM32L5,STM32H5にスライド移植させてしまったが
ためにバグまで仲良くスライド移植してしまったからですorz
STM32F7のSDMMCについては正しい手順でCMD6を発行してハイスピード
モードに移行した上でクロックを上げているため問題はありません。
STM32F1,F4についてはSDIOにエラッタが存在し、ハイスピードモードの
速度でクロックが実質使用できないのでDefaultSpeed(25MHz)までとして
います。(実験的にハイスピードモードにできるようにはしています。)
LPC4088はMCIのクロック上限が25MHzまでなのでこれも問題はありません。
LPC4357についてはSDカードのクロック上限はソフトウエアで25MHzまでと
しているのでこちらも問題はありません(MMCv4は50MHz)。
その他、SPIモードで読み書きするものについても、そもそもSDの仕様上で
SPIモードではハイスピードモードは使用できないのでこちらも問題は
ありません。(※SPIモードでもハイスピードモードが存在する説があり)
●実際の被害は?
➡現状私一人だけが被弾している状態です。
私の知る限りでは他の方が私の作例を使用し、SDカードの
読み書きができないという報告や記事はありませんでした。
しかしSTM32H7/L5/H5の私の対策前の作例をもとにTS20GUSD240Iを
使うと、確実に被弾します。再現率100%です。
●対策は?
➡"CMD6発行によるHigh Speed Mode移行"を確認してから
 SDカードへのクロックを50MHzに上げるよう修正します。
本来ならばこの記事を書く前にいち早く修正コード上げるべきですが
検証に使用するカードの種類や対応マイコンの範囲が広いので時間かけて
慎重に再検討しております…。完了したら追記で連絡いたします。
20250328追:
STM32H7の作例で上記のバグを修正し、
全体的に動作を見直し大幅更新いたしました!
20250328追:
20250421追:
STM32L5の作例も修正して更新しました!
20250421追:

古のハイスピードモードが無いSDV1.01カードとか4bitモードが無い
MMCv3カードからはじめて最新のA2対応のSDXCとかeMMCに至るまで、
洗いざらい今一度!とにもかくにも全部動作確認!
STM32H7で問題ないことを確認したらSTM32L5(更新停止してますが
今回だけ)とSTM32H5にも今回の修正を反映します。
また、STM32F1,F4,F7,LPC4000系の実装例についてもSTM32H7の修正で
気づいた点についてはフィードバックして最新化させる予定です。
多分夏いっぱいくらいかかるかと思いますが焦らずに対処いたします。
●ところでTranscendのTS20GUSD240Iですが…

このカード、UHS-2ではないのですがなんでかSDR104の限界を超えて
100MB/sec超の読み書き性能を誇っております…
UHS-2には勝てないですがコストパフォーマンス考えたらすごいです。
おそらくこれは規格外規格のDDR200ってやつですね…
検証に使ったUGREENのUHS-2対応カードリーダー(CM265)も何気にDDR200に
対応してるのが分かったので掘り出し物だったのわかってラッキーです…♥

なお、今年初頭に紹介したUltraPerformanceのカードもぶっちふぎりの
性能見せてくれてます…
もうUHS-2じゃなくてもこれらでいいかも…!
	

免責・連絡先は↑のリンクを
↓SNSもやってます↓
powered by まめわざ
	- ARM/STM32 (119)
 - OpenOCD (27)
 - ARM/NxP (34)
 - ARM/Cypress (5)
 - ARM/Others (3)
 - ARM/Raspi (1)
 - AVR (13)
 - FPGA (4)
 - GPS/GNSS (20)
 - MISC (86)
 - SDCard_Rumors (1)
 - STM8 (2)
 - Wirelessなアレ (16)
 - おきぱ (1)
 - ブラウザベンチマーク (29)
 - 日本の自然歩道 (27)
 
	- GNSSモジュールを試用する21 -SAM-M10Qが壊れた…!?と思ったら直せた(おまけあり)-
⇒ Kenji Arai (05/29) - GNSSモジュールを試用する21 -SAM-M10Qが壊れた…!?と思ったら直せた(おまけあり)-
⇒ ねむい (05/26) - GNSSモジュールを試用する21 -SAM-M10Qが壊れた…!?と思ったら直せた(おまけあり)-
⇒ Kenji Arai (05/24) - 中部北陸自然歩道を往く -砺波平野の県境を駆け抜ける!-
⇒ ねむい (12/18) - 中部北陸自然歩道を往く -砺波平野の県境を駆け抜ける!-
⇒ ひかわ (12/15) - STM32U0はぢめました
⇒ ねむい (08/07) - STM32U0はぢめました
⇒ ひかわ (07/28) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ ねむい (05/17) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ どじょりん (05/16) - STM32H5を使ってみる3 -待ち受ける初見殺しの罠たち-
⇒ どじょりん (05/16) 
	- October 2025 (1)
 - September 2025 (1)
 - August 2025 (1)
 - July 2025 (1)
 - June 2025 (1)
 - May 2025 (1)
 - April 2025 (1)
 - March 2025 (1)
 - February 2025 (1)
 - January 2025 (1)
 - December 2024 (2)
 - November 2024 (1)
 - October 2024 (1)
 - September 2024 (1)
 - August 2024 (1)
 - July 2024 (1)
 - June 2024 (1)
 - May 2024 (1)
 - April 2024 (1)
 - March 2024 (1)
 - February 2024 (2)
 - January 2024 (1)
 - December 2023 (4)
 - November 2023 (2)
 - October 2023 (2)
 - September 2023 (1)
 - August 2023 (2)
 - July 2023 (1)
 - June 2023 (2)
 - May 2023 (3)
 - April 2023 (1)
 - March 2023 (1)
 - February 2023 (1)
 - January 2023 (1)
 - December 2022 (2)
 - November 2022 (1)
 - October 2022 (1)
 - September 2022 (1)
 - August 2022 (1)
 - July 2022 (1)
 - June 2022 (1)
 - May 2022 (1)
 - April 2022 (1)
 - March 2022 (1)
 - February 2022 (1)
 - January 2022 (1)
 - December 2021 (2)
 - November 2021 (2)
 - October 2021 (1)
 - September 2021 (1)
 - August 2021 (1)
 - July 2021 (1)
 - June 2021 (1)
 - May 2021 (1)
 - April 2021 (1)
 - March 2021 (1)
 - February 2021 (1)
 - January 2021 (1)
 - December 2020 (3)
 - November 2020 (1)
 - October 2020 (1)
 - September 2020 (1)
 - August 2020 (1)
 - July 2020 (1)
 - June 2020 (2)
 - May 2020 (1)
 - April 2020 (1)
 - March 2020 (1)
 - February 2020 (1)
 - January 2020 (1)
 - December 2019 (3)
 - November 2019 (1)
 - October 2019 (1)
 - September 2019 (2)
 - August 2019 (1)
 - July 2019 (1)
 - June 2019 (1)
 - May 2019 (1)
 - April 2019 (1)
 - March 2019 (1)
 - February 2019 (1)
 - January 2019 (1)
 - December 2018 (3)
 - November 2018 (2)
 - October 2018 (1)
 - September 2018 (1)
 - August 2018 (1)
 - July 2018 (1)
 - June 2018 (1)
 - May 2018 (1)
 - April 2018 (2)
 - March 2018 (1)
 - February 2018 (1)
 - January 2018 (1)
 - December 2017 (2)
 - November 2017 (2)
 - October 2017 (1)
 - September 2017 (1)
 - August 2017 (1)
 - July 2017 (1)
 - June 2017 (1)
 - May 2017 (1)
 - April 2017 (1)
 - March 2017 (2)
 - February 2017 (2)
 - January 2017 (2)
 - December 2016 (7)
 - November 2016 (2)
 - October 2016 (2)
 - September 2016 (1)
 - August 2016 (1)
 - July 2016 (1)
 - June 2016 (1)
 - May 2016 (2)
 - April 2016 (1)
 - March 2016 (2)
 - February 2016 (1)
 - January 2016 (1)
 - December 2015 (3)
 - November 2015 (1)
 - October 2015 (3)
 - September 2015 (2)
 - August 2015 (2)
 - July 2015 (3)
 - June 2015 (3)
 - May 2015 (4)
 - April 2015 (2)
 - March 2015 (4)
 - February 2015 (1)
 - January 2015 (3)
 - December 2014 (3)
 - November 2014 (2)
 - October 2014 (1)
 - September 2014 (2)
 - August 2014 (2)
 - July 2014 (3)
 - June 2014 (2)
 - May 2014 (1)
 - April 2014 (1)
 - March 2014 (4)
 - February 2014 (4)
 - January 2014 (3)
 - December 2013 (5)
 - November 2013 (4)
 - October 2013 (3)
 - September 2013 (2)
 - August 2013 (2)
 - July 2013 (2)
 - June 2013 (3)
 - May 2013 (2)
 - April 2013 (2)
 - March 2013 (2)
 - February 2013 (2)
 - January 2013 (3)
 - December 2012 (4)
 - November 2012 (2)
 - October 2012 (2)
 - September 2012 (4)
 - August 2012 (1)
 - July 2012 (3)
 - June 2012 (2)
 - May 2012 (3)
 - April 2012 (3)
 - March 2012 (2)
 - February 2012 (3)
 - January 2012 (3)
 - December 2011 (5)
 - November 2011 (3)
 - October 2011 (2)
 - September 2011 (2)
 - August 2011 (2)
 - July 2011 (2)
 - June 2011 (2)
 - May 2011 (2)
 - April 2011 (2)
 - March 2011 (2)
 - February 2011 (2)
 - January 2011 (3)
 - December 2010 (7)
 - November 2010 (1)
 - October 2010 (1)
 - September 2010 (1)
 - August 2010 (3)
 - July 2010 (4)
 - May 2010 (1)
 - April 2010 (2)
 - March 2010 (2)
 - February 2010 (2)
 - January 2010 (3)
 - December 2009 (3)
 - November 2009 (8)
 - October 2009 (7)
 - September 2009 (5)
 - August 2009 (4)
 - July 2009 (6)
 - June 2009 (6)
 - May 2009 (14)
 - January 1970 (1)
 
Copyright(C) B-Blog project All rights reserved.