電子工作」カテゴリーアーカイブ

ArduinoIDEのRasberry Pi PicoボードマネージャーとWindowsの組み合わせでフォルダを握りっぱなしになっている

環境

  • Windows 11 Home 22H2 22621.3155
  • Arduino IDE 2.3.2(おそらく2.2.2-nightly-20230909が自動アップデートかかったもの)
  • python3.10(PCのやつでなくボードマネージャー個別のpythonが指定されていた)
  • Rasberry Pi Pico/PR2040 3.7.2(ボードマネージャー) <- 調査完了してないがこいつが原因
  • python3.7.2(PCのやつでなくボードマネージャー個別のpython)

状況

調査の過程でボードマネージャーからRasberry Pi Pico/PR2040をアンインストール(remove)と再インストールした時点で再現しなくなってしまったので再現待ち。多分根本解決していない。

事象

ArduinoIDEでスケッチを開いた後にスケッチの入っているフォルダを移動させようとすると「別のプログラムがこのフォルダーまたはファイルを開いているので操作を完了できません」というメッセージが表示される。リソースモニターから見るとpython3が握っていることになっている。

なお、リソースモニターはwindowsの下タブにある検索に perfmon.exe /res と入力すると起動できる。(初回はなにか選択画面出たかも)CPUタブの下にある関連付けされたハンドルにフォルダの古パスを入力すると握っているプロセス名とPIDがわかる。

取り急ぎリソースモニターの下の関連付けられたハンドルに出てきたプロセスを右クリックで終了させると解放されるけど気持ち悪い。

調査(中)

プロセス確認

MSのプロセスツリーを確認できるツールをダウンロード&解凍。dosからたたいてプロセス確認。

IDE起動中にPID9552でpythonが起動していたが、閉じたところ

単独でプロセスがのこってしまっている。

ネットをパッと見る限り情報なさそう。

ちなみに以前使っていたArduinoIDE1.8.19を起動したところ1.8.19では発生せず。2になる時に根本的に変わっているので2系の問題っぽい。

上のプロセスツリーを見る限りArduino IDEが動かしているarduino-cliが動かしているpython3がフォルダをにぎりっぱになっているのだろう。

とりあえずタスクマネージャーから引っ張ってきた怪しげなところの起動時引数が下。

名前 PID 状態 ユーザー名 CPU メモリ (アクティブなプライベート ワーキング セット) コマンド ライン アーキテクチャ 説明
arduino-cli.exe 10208 実行中 kitam 00 88,832 K "C:\Users\kitam\AppData\Local\Programs\Arduino IDE\resources\app\lib\backend\resources\arduino-cli.exe" daemon --port 0 --config-file c:\Users\kitam\.arduinoIDE\arduino-cli.yaml -v x64 arduino-cli.exe
名前 PID 状態 ユーザー名 CPU メモリ (アクティブなプライベート ワーキング セット) コマンド ライン アーキテクチャ 説明
python3.exe 15928 実行中 kitam 00 4,112 K C:\Users\kitam\AppData\Local\Arduino15\packages\rp2040\tools\pqt-python3\1.0.1-base-3a57aed/python3 -I C:\Users\kitam\AppData\Local\Arduino15\packages\rp2040\hardware\rp2040\3.7.2/tools/pluggable_discovery.py x86 Python

rp2040といっているのでraspi pico用のやつが悪さしているっぽい。

試しにボードマネージャーからRasberry Pi Pico/PR2040をアンインストール(remove)するとpythonのプ℟セス立ち上がらなくなり閉じたあともきちんと解放されるようになった。

ちなみに以下のjsonで指定しているもの。

原因ソース

多分こちら。スレッドのグローバル変数を外部から操作する思想みたいだが、操作元がいない模様。

どうしよう。

と、思っていたところ再インストールした時点で予想外に再現しなくなったので再現待ち。多分解決しておらず、なにかトリガーになるアクションを踏んでいない。

BrokenPipeError: [Errno 32] Broken pipe調査

ESP8266(ESP-WROOM-02)の内容。ESP-WROOM-32ではないので注意。

事象

esp8266 -> nginx(proxy) -> python(HTTPServer)という構成でサーバへespからサーバーへリクエストを投げたところ、かなりの確率で以下のログがpythonで吐かれていた。

Exception occurred during processing of request from ('127.0.0.1', 48024)
Traceback (most recent call last):
  File "/usr/lib/python3.10/socketserver.py", line 316, in _handle_request_noblock
    self.process_request(request, client_address)
  File "/usr/lib/python3.10/socketserver.py", line 347, in process_request
    self.finish_request(request, client_address)
  File "/usr/lib/python3.10/socketserver.py", line 360, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python3.10/socketserver.py", line 747, in __init__
    self.handle()
  File "/usr/lib/python3.10/http/server.py", line 433, in handle
    self.handle_one_request()
  File "/usr/lib/python3.10/http/server.py", line 421, in handle_one_request
    method()
  File "/home/yoshitake/api/mail_api.py", line 26, in do_GET
    self.wfile.write(response_content)
  File "/usr/lib/python3.10/socketserver.py", line 826, in write
    self._sock.sendall(b)
BrokenPipeError: [Errno 32] Broken pipe

直接のメッセージは、pythonがリクエスト元に書きこもうとしたら相手がすでに受信待ち状態を終了しているような場合に起きるやつ。esp側では接続したもののヘッダーも取得せずにすぐに終了している。

ちなみにnginxのaccess.logには以下のようにステータス499と(pythonのHTTPServer他で使われている非標準の)クライアントが先に閉じたよというのが残っている。

150.9.94.220 - - [26/Feb/2024:11:31:56 +0900] "GET /api/reserve_count HTTP/1.0" 499 0 "-" "ESP8266"

直接の原因箇所

リクエストを送るesp側でデータの受信待ちをしなくてすぐに閉じているのが直接の原因

delay(1000);とかを入れたらとりあえず動く。

とはいえ、リクエストを送ったのちにデータ受信後の終了信号的なものをみたらまたはタイムアウトでクローズの方がよさそう。

また、同じ接続方式でself-signed.badssl.comにリクエストを送るとレスポンスがきちんと取得できているのでサーバサイドにも何か改善点がありそう。

根本解決

クライアントサイド(ESP8266)

取り急ぎavailable()では接続できたかしか確認していない。 WiFiServerSecureBearSSL.cpp(サーバの方)を間違えてみていた。

改めてWiFiClientSecureBearSSL.cpp確認。

字面で見る限りなんか入ってたら0以外が入って、なにも入っていないとサーバ側が準備中でも一番下に入って0がくるっぽい。だいぶ中の方に書いてあるので内部データを見ると色々多変そうなので最初のデータ来るかタイムアウトまでの待ち処理を入れるのがよさそう。断続的にデータがくるならちゃんと終端処理を見た方がよいかも。

本体から、書き出しメソッド呼び出し。

サーバサイド(nginx+pythonのHTTPServer)

こちらは単純にレスポンスが早く返りだすかどうかで違いが出ていたっぽい。レスポンスが早いという理由だった場合はクライアント側の処理で解決すべき話なので深く追わない。

ESP8266用(BearSSL_Validation.ino)のSSL接続用ファイル更新

ESP8266(ESP-WROOM-02)の内容。ESP-WROOM-32ではないので注意。

こちらのBearSSL_Validation.ino事前準備の手順。試している環境はWindows11。

前提

BearSSL_Validation.inoと同じディレクトリにあるcerts.hだが、サーバ側の証明書が更新されているとつながらなかったりする。(レポジトリ側の更新タイミング次第ではつながったりつながらなかったりだと思う)

certs.hを見ると下のように書いてあり

// this file is autogenerated - any modification will be overwritten
// unused symbols will not be linked in the final binary
// generated on 2023-03-20 23:02:42
// by ['../../../../tools/cert.py', '-s', 'www.example.com', '-n', 'SSL']

して更新するらしい。他のドメイン用に作る場合もおそらくcert.pyをたたけばよいと思う。

なお、cert.pyのファイル先頭コメント

#!/usr/bin/env python3

# Script to download/update certificates and public keys
# and generate compilable source files for c++/Arduino.
# released to public domain

Windowsのはまりポイント

WindowsでMS Storeからインストールするとツールは見れない場所にありそう。(MS Storeから入れたソフト類のディレクトリは見れない模様)インストーラー直ダウンロードしたIDE場合多分下みたいな配置。

C:\Users\hoge\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266WiFi\examples\BearSSL_Validation

だと下にある

C:\Users\hoge\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.1.2\tools

MS Storeからインストールして見れない人は、レポジトリのソース一式ダウンロードしたら多分中に入っているcert.pyを使える。

環境構築

cert.pyはpython3なので必要ならインストール。

ライブラリインストール

ないと下みたいなメッセージ

python  '../../../../tools/cert.py' '-s' 'www.example.com' '-n' 'SSL'                            
Traceback (most recent call last):
  File "C:\Users\kitam\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.1.2\tools\cert.py", line 15, in <module>
    from cryptography import x509
ModuleNotFoundError: No module named 'cryptography'

もしかしたら

もいるかも。

import re
import ssl
import sys
import socket
import argparse
import datetime

あたりは元々使えると思うけど必要ならそいつらも

証明書生成実行

パスにユーザ名入っているので適宜書き換え。

出力ファイル名(test.h)も適宜書き換え

結果

PS C:\Users\kitam\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266WiFi\examples\BearSSL_Validation> python  '../../../../tools/cert.py' '-s' 'www.example.com' '-n' 'SSL' > test.h
C:\Users\kitam\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.1.2\tools\cert.py:44: CryptographyDeprecationWarning: Properties that return a naïve datetime object have been deprecated. Please switch to not_valid_before_utc.
  print('// not valid before:', xcert.not_valid_before)
C:\Users\kitam\Documents\ArduinoData\packages\esp8266\hardware\esp8266\3.1.2\tools\cert.py:45: CryptographyDeprecationWarning: Properties that return a naïve datetime object have been deprecated. Please switch to not_valid_after_utc.
  print('// not valid after: ', xcert.not_valid_after)

なんか余計な警告出ているけどchatgpt先生によると以下らしいのでとりあえず無視

この警告は、Cryptography ライブラリが提供する一部の機能において、適切なタイムゾーン情報が欠如している(naïveな)datetimeオブジェクトを返すプロパティが非推奨であることを示しています。代わりに、not_valid_before_utcというプロパティを使用することが推奨されています。

ino修正

修正目的

ExampleのBearSSL_Validation.inoを任意フォルダ(今回はデスクトップ)に保存。

その後、cert.hの中身を先ほど出力したtest.hに変更

そのまま実行すると

C:\Users\kitam\Desktop\BearSSL_Validation\BearSSL_Validation.ino: In function 'void fetchCertAuthority()':
C:\Users\kitam\Desktop\BearSSL_Validation\BearSSL_Validation.ino:15:14: error: 'cert_DigiCert_TLS_RSA_SHA256_2020_CA1' was not declared in this scope; did you mean 'cert_DigiCert_Global_G2_TLS_RSA_SHA256_2020_CA1'?
   15 | #define CERT cert_DigiCert_TLS_RSA_SHA256_2020_CA1
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:\Users\kitam\Desktop\BearSSL_Validation\BearSSL_Validation.ino:15:14: note: in definition of macro 'CERT'
   15 | #define CERT cert_DigiCert_TLS_RSA_SHA256_2020_CA1
      |              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

exit status 1

Compilation error: 'cert_DigiCert_TLS_RSA_SHA256_2020_CA1' was not declared in this scope; did you mean 'cert_DigiCert_Global_G2_TLS_RSA_SHA256_2020_CA1'?

出力されたtest.hにあるcert_DigiCert_Global_G2_TLS_RSA_SHA256_2020_CA1が元ヘッダーファイルにあったcert_DigiCert_TLS_RSA_SHA256_2020_CA1から変わっている。ちなみに、cert_DigiCert_Global_Root_G2とcert_DigiCert_Global_Root_CAも変わっている。

証明書のCNからcert.pyで自動命名しているのでしょうがない。

長期運用するならcert.pyをいじるか出てきたヘッダーの命名を書き換えて固定にした方が良いかも。深く考えないで取り急ぎinoの方を修正する。(15行目)

動作確認は元のページ

ESPのWiFiClientSecureでサーバから情報をもらう時サーバでContentsLength指定していないと面倒

ESP8266(ESP-WROOM-02)の内容。ESP-WROOM-32ではないのでがおおよそ同じと思う。

現象

ESP8266のWiFiClientSecureでサーバからデータを取得しようとした。本来レスポンスの本体(ペイロード本文)は”[0]“を期待していたが以下の下3行のようにレスポンスが期待していたものと違う形になっていた。

Connecting to https://hoge.co.jp/api/fuga
Connected to server
Server: nginx
Date: Wed, 21 Feb 2024 05:21:47 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: close

3
[0]
0

理由

これはTransfer-Encoding: chunkedになっていてペイロード本文

データ1のバイト数\r\nデータ1\r\n0\r\n

というフォーマットになっているため。長いもの送る場合は

データ1のバイト数\r\nデータ1\r\nデータ2のバイト数\r\nデータ2\r\n…データxのバイト数\r\nデータx\r\n…0\r\n

となる。なおデータのバイト数は16 進数表記。

対処

その1

対処としてそういうものとして読み込んでもよいけど、マルチバイトの場合データ1,2の間でぶった切られるのでつなげるのとか面倒。

その2

可能ならサーバ側で送る際にTransfer-Encoding: chunkedじゃなくしたい。

今回はサーバ側はpythonのBaseHTTPRequestHandlerを使っているがレスポンスにContent-Lengthをつけてやれば自動でTransfer-Encoding: chunkedじゃなくなった。「とりあえず、Content-Lengthついてないからchunkedでおくとっくわ」という仕様だったっぽい。(明示的にヘッダー付けた場合に消えるかは未確認)

http1.1の仕様的にはTransfer-Encoding: chunkedの時にはContent-Length不要らしい。

ATTinyのArduinoIDE用パッケージダウンロード先の暫定対処

いつの日からかArduinoIDEで追加ボードマネージャーURLに入れていたAttiny用(プロジェクトの正式名称ATTinyCore?megatinycore?)のjsonがダウンロード先の証明書が切れてつながらなくなっていた。

Some indexes could not be updated. Get "https://drazzy.com/package_drazzy.com_index.json": tls: failed to verify certificate: x509: certificate has expired or is not yet valid: : http://drazzy.com/package_drazzy.com_index.json

adafruitのgithubに以下の暫定対処先のURLダウンロード先がのっていたのでそちらに修正

https://web.archive.org/web/20230504110614/http://drazzy.com/package_drazzy.com_index.json

ArduinoIDEのprefarences->settingタブ->additional board manager urls

とりあえず暫定対処っぽいこと書いてあるけど、数か月前にfixされてそのままみたいなのでしばらくそのままかも

ESP8266のWiFiClientSecure系でcertを扱う時のメモ

今、調べながら試しているけどchatgptに存在しないメソッド言われたりと騙されるっぽいのでメモを残す。終了

ESP8266(ESP-WROOM-02)の内容。ESP-WROOM-32ではないので注意。

環境

  • Windows11
  • Arfuino IDE 2.3.1
  • esp8266 by ESP8266 Community 3.1.2(レポジトリ)

動きそうなやつ(これから確認、動いたら記事修正する)

WiFiClientSecureBearSSL#setInsecure

基本こちらのまんまで動いた。(リンク先はESP8266でなくESP32なので他を参考にするときはクラス仕様違うので注意)

最初は戻り値にバイト数とか入ってたけどサーバ側でcontents-length指定していないのが原因だった。

BearSSL_Validation.ino

Example->Esp8266Wifiの中にいるサンプル。

単独のCAをツールでヘッダーファイルに変えて読み込むやつだと思う。

includeで気になった奴

#include <StackThunk.h>というのがある。(実装のcpp

StackThunk.c - Allow use second stack for BearSSL calls


  BearSSL uses a significant amount of stack space, much larger than
  the default Arduino core stack. These routines handle swapping
  between a secondary, user-allocated stack on the heap and the real
  stack.

BearSSLはスタックすごい使うからうんぬんと。通常のスタックだと足りないから、ヒープを使ってごにょごにょしてくれるらしい。

サンプルソースだと割り当て関連の機能は使っておらず使用量確認のみに見えるけど中で読んでいるかも。一見、足りてそうに見えるときも内部でこいつが使い切ってるとかはあるかもしれないので心に留めておく。

事前準備

cert.pyを使用して証明書のデータを更新。(長くなったのでこちら

フィンガープリントだけで接続

フィンガープリント設定すればとりあえずつながる。

何もないよりましだといっている

The SHA-1 fingerprint of an X.509 certificate can be used to validate it
instead of the while certificate.  This is not nearly as secure as real
X.509 validation, but is better than nothing.  

自己署名証明書で接続

allowSelfSignedCertすればOKとのこと。

こいつは自己署名は誰でも作れるから注意を(略

It is also possible to accept *any* self-signed certificate.  This is
absolutely insecure as anyone can make a self-signed certificate.

ハードコード公開鍵で接続

公開鍵をハードコードしておいてそいつを使って(通常のSSLは認証プロセスを飛ばして)通信できる。一般公開しないサービスならこれでもよさそうな気がする。

The server certificate can be completely ignored and its public key
hardcoded in your application. This should be secure as the public key
needs to be paired with the private key of the site, which is obviously
private and not shared.  A MITM without the private key would not be
able to establish communications.

certをハードコード方式(多分一番固い)

certをハードコードして検証する方式。

有効期限チェックはするけれどもCRLはサポートしていないらしい。発行された証明書が有効期限内に無効化されていてもチェックされない。自己署名証明書をルートにしたチェーンも作れるらしい。

A specific certification authority can be passed in and used to validate
a chain of certificates from a given server.  These will be validated
using BearSSL's rules, which do NOT include certificate revocation lists.
A specific server's certificate, or your own self-signed root certificate
can also be used.  ESP8266 time needs to be valid for checks to pass as
BearSSL does verify the notValidBefore/After fields.

上のようにcertをルート証明書にしても動くはずだがレスポンスとりそびれるときがあるのに気づいた。ルートじゃなくてサーバのcertを使っているときも取りそびれ発生しているかもしれない。原因調査未。とり急ぎ調査はおいておいて他の方式の確認進める。と、思ったら方式別でも発生している。=> 解決方法

暗号化方式の選択

早さ優先したいときとか

client.setInsecure();

ノーチェック

client.setCiphersLessSecure();

以下のやつら指定(と思う)

// For apps which want to use less secure but faster ciphers, only
  static const uint16_t faster_suites_P[] PROGMEM = {
    BR_TLS_RSA_WITH_AES_256_CBC_SHA256,
    BR_TLS_RSA_WITH_AES_128_CBC_SHA256,
    BR_TLS_RSA_WITH_AES_256_CBC_SHA,
    BR_TLS_RSA_WITH_AES_128_CBC_SHA };
  • BR_TLS_RSA_WITH_AES_256_CBC_SHA256: RSA鍵交換、AES-256-CBC暗号、SHA-256ハッシュ
  • BR_TLS_RSA_WITH_AES_128_CBC_SHA256: RSA鍵交換、AES-128-CBC暗号、SHA-256ハッシュ
  • BR_TLS_RSA_WITH_AES_256_CBC_SHA: RSA鍵交換、AES-256-CBC暗号、SHA-1ハッシュ
  • BR_TLS_RSA_WITH_AES_128_CBC_SHA: RSA鍵交換、AES-128-CBC暗号、SHA-1ハッシュ
自分で指定

使えるリストはおそらくこちら。(さらに制限かかっているかもしれないが細かくは追っていない)

ちなみにサンプルソースのwww.example.comはsha1のBR_TLS_RSA_WITH_AES_256_CBC_SHAとBR_TLS_RSA_WITH_AES_128_CBC_SHAは通じたがsha256では通じなかったので上の指定だと接続エラーになった。

つなげるサーバの証明書を取得

こちらを参照

変数名サンプルソースと違うので適宜修正

BearSSL_CertStore.ino

モジラから読み込んだルートcaを複数ストアして使えるやつっぽい。容量気にしない状況ならこいつが使いやすそう。

証明書の更新

長くなったのでこちら

証明書のアップロード

初めにアップロード用ツールのインストール。(手順はこちら

IDEから[Ctrl] + [Shift] + [P]から ‘Upload Little FS to Pico/ESP8266‘ を選択し、(リセットボタン押したりするプログラム書き込みモードで)アップロード実行。

手順の方にも書いたけどシリアルモニター開いていると競合して書きこめないので注意

動作確認

サイトのドメイン入れて実行。大体の場合、htmlソースの表示がレスポンス待ち処理が足りなくてされない。 解決方法

課題

Upload LittleFSだとファイルシステムがすべて上書きされるらしい。一部差し換え的なことがやりたい。ファイルシステムルート直下のcerts.idxとcerts.arを差し替えたらよさそうだがcerts.idxがどこでできているのかまだ理解していない。CertStore::initCertStoreの中でcerts.idx作成しているのでcerts.arだけさしかえればよさそう。失敗したら接続できなくなりそうだけど、ネット越しにファイル放り込んで再起動とかもできそうかな。

ESP8266HTTPClientへの連携

以下の感じでcertを設定済みのWiFiClientSecureをHTTPClient のbeginメソッドに渡してやると動いた

以下蛇足

Chatgptに言われたけどなさそうな奴

無いっぽい奴1

とchatgptにいわれた。が、

C:\Users\kitam\Desktop\https\https.ino: In function 'void setup()':
https:32:10: error: 'class BearSSL::WiFiClientSecure' has no member named 'setCACertBundle'
   32 |   client.setCACertBundle(x509_crt_bundle);
      |          ^~~~~~~~~~~~~~~
exit status 1
'class BearSSL::WiFiClientSecure' has no member named 'setCACertBundle'

ないよと。ソース見ると確かにいない。なお、ESP32ならこれで動く模様。(参考

無いっぽい奴2

といわれたが、同じように

C:\Users\kitam\Desktop\https\https.ino: In function 'void setup()':
C:\Users\kitam\Desktop\https\https.ino:32:9: error: 'class BearSSL::WiFiClientSecure' has no member named 'addServerKey'
   32 |  client.addServerKey(x509_crt_bundle);
      |         ^~~~~~~~~~~~

exit status 1

Compilation error: 'class BearSSL::WiFiClientSecure' has no member named 'addServerKey'

addServerKeyはぱっとみESP32のライブラリにもなさそうなのでchatgptがどこから拾ってきたかよくわからない。

picoprobeの環境構築で手間取ったのでメモ

Interface7月号のラズパイPicoでゼロから作るOSを試そうとしたら環境構築で手間取ったのでメモ。

先に結論

Interface記載の各ダウンロード先最新のもので環境構築をするとpicoprobeのデバックが動かない。対処としてxpmで入れたopenocdを使用すると動いた。

インストール方法

node/npm/xpmが入っている環境で

cd my-project
xpm init # Only at first use.

xpm install @xpack-dev-tools/openocd@latest --verbose

事象

手順通りだとエラー。エラーメッセージを取り損ねているけどlocalhost:3333がtimeoutとかの類だったはず。

cmsis-dap.cfgを修正しadapter speed 5000を追記するという手順をしても以下エラー。

Error: Sequence 4 not supported. 
Info : DAP init failed


Error: Sequence 3 not supported.
Error: Sequence 4 not supported.

原因

Interface記載のopenocdだと今のpicoprobeの処理に対応していない。こちらのリンク先のパッチが未適用。(公式だと取り込まれていた。)Interface記載の段階では動いたようなのでおそらくpicoprobeのバージョンアップで動作が変わったと思う。(が、picoprobe側の変更履歴は確認していない。)

各バージョン

多分直接関係するのはopenocdとpicoprobeだけだと思う

C:\Users\kitam>node -v
v18.17.1

C:\Users\kitam>npm -v
9.6.7

C:\Users\kitam>xpm --version
0.16.3
picoprobe-cmsis-v1.0.3
  "xpack": {
    "minimumXpmRequired": "0.16.3",
    "dependencies": {},
    "devDependencies": {
      "@xpack-dev-tools/arm-none-eabi-gcc": {
        "specifier": "12.3.1-1.1.1",
        "local": "link",
        "platforms": "all"
      },
      "@xpack-dev-tools/windows-build-tools": {
        "specifier": "4.4.0-1.1",
        "local": "link",
        "platforms": "all"
      },
      "@xpack-dev-tools/openocd": {
        "specifier": "0.12.0-2.1",
        "local": "link",
        "platforms": "all"
      }
    },
Eclipse IDE for Embedded C/C++ Developers (includes Incubating components)

Version: 2023-06 (4.28.0)
Build id: 20230608-1333

CH32V003とWCH-LinkEでLチカ

秋月で販売開始になったCH32V003J4M6(マイコン本体)とWCH-LinkEエミュレーター(書き込み/デバック装置)で書き込みができたのでそこまでのメモ。

基本的にはこちらの記事をトレースしてわからなかったことを追記した感じ

必要だったのもの

ハード

  • CH32V003J4M6 1個
  • WCH-LinkEエミュレーター 1個
  • ピッチ変換基盤 1個(これの同等品)
  • LED 1個(3mm使った)
  • 抵抗 1個(1 KΩ 大体で)
  • ブレッドボード 1個
  • コンデンサ 0.1uF 1個
  • ジャンパーケーブル 5本ぐらい
  • 書き込み用PC Windows11(1台)

ソフト

元記事と違った箇所、または追加したとこ

「いつも通り Workspace の場所を決めて Launch をクリックします。」は出なかった。後で選べる。

File⇒Open Procets from File System をクリックします。」は「Open Procets from File System」のとこが微妙に名前変わっていた

「コンパイル」のトンカチアイコンは見当たらず、ビルドアイコンがツールバーの左寄りにあった。ダウンロードアイコンもツールバーの左寄り。

サンプルソースはGPIO_Pin_0でLチカしているけどSOP8のだとPD0は出ていないのでGPIO_Pin_6(PD6の1番ピン)に変更

書き込みのたびに、MounRiver Studioにて以下操作

  1. メニューバーからFlash選択
  2. configration選択
  3. target modeにあるqueryボタンクリック
  4. プルダウンに出てくるWCH-LinkRV選択
  5. 少し下のErase Code FlashでBy power off を選択してApplyクリック

接続

PCのUSBにPCのUSBにWCH-LinkEエミュレーター接続

WCH-LinkEエミュレーターCH32V003
GND2番ピン(VSS)
3V34番ピン(VDD)
SWDIZO8番ピン()

CH32V003の1番ピン – Lチカ用のLED – 1KΩ抵抗 – CH32V003の2番ピン(VSS)

CH32V003の2番ピン(VSS) – 0.1uFコンデンサ – CH32V003の4番ピン(VDD)

ソース

ほぼそのままだけど下の

/********************************** (C) COPYRIGHT *******************************
 * File Name          : main.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2022/08/08
 * Description        : Main program body.
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
* Attention: This software (modified or not) and binary are used for 
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/

/*
 *@Note
 GPIO routine:
 PD0 push-pull output.

*/

#include "debug.h"

/* Global define */

/* Global Variable */

/*********************************************************************
 * @fn      GPIO_Toggle_INIT
 *
 * @brief   Initializes GPIOA.0
 *
 * @return  none
 */
void GPIO_Toggle_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    u8 i = 0;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);

    printf("GPIO Toggle TEST\r\n");
    GPIO_Toggle_INIT();

    while(1)
    {
        Delay_Ms(250);
        GPIO_WriteBit(GPIOD, GPIO_Pin_6, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
    }
}

Aliで買ったLEDシリコンチューブ届いた

ここのやつ。

5mのオレンジで12Vで約1.2A。

明るさとしては室内の照明だと十分目立つけど昼の屋外だとほぼわからないぐらい。屋外で使うならやや日が傾きだしたぐらいからかな。晴れた6月の京都で18時ぐらいで見えるぐらい。

なお開封直後はゴム臭がけっこうした。

チューブに黒い点がついていてそこから切り離せるはずだけど試していない。

看板に使用したいので曲げてみた。折り目はつかないのでターンのきついところでは接着剤等で角度保持してやらなくてはならない。

ちなみに看板は最初トリマーで掘り込もうと思ったけど丁寧にやるのは時間がかかるのであきらめた。大きいCNCがあったら楽そうだけどCNC事態を持っていないのでレーザーカッターでアクリルを切り抜いたやつで作る予定。