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

2024/10/30追記

暫定対処もArduino IDEでダウンロード失敗のメッセージが出ていた。

暫定対処のダウンロード先(https://web.archive.org/web/20230504110614/http://drazzy.com/package_drazzy.com_index.json)のtar(https://web.archive.org/web/20230504110614/https://github.com/SpenceKonde/arduino-tiny-841/archive/v1.0.6.tar.gzとか)をたたくとhttps://github.com/SpenceKonde/ATTinyCoreにリダイレクトされた。Installation.mdにBoards Manager Installation用のjsonのURL書いてあるけど古いまま。現役のjsonURLは見つけていない

と思ったら、書いてあるのが現役だけど、証明書が切れてるからサイト管理者が治すの待つか手動インストールしろという事らしい。(https://github.com/SpenceKonde/ATTinyCore/issues/885)日々更新するわけではないので現役(ただいま停止中)のhttp://drazzy.com/package_drazzy.com_index.jsonに戻しておとなしく待っておく。

2024/10/30追記終了

いつの日からか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がどこから拾ってきたかよくわからない。

nginxでpythonを動かす

最終的にやりたいこと

店の予約メールが入ったときにすぐわかるように家でパトランプ的なものを光らせたい。

  1. メールサーバに予約っぽいメールが来たら特定フォルダに振り分けておいて
  2. 未読メールがあるかどうか返すAPIをメールサーバに建てておいて
  3. 家のパトランプてきな端末から定期的にサーバをチェックしにいく

家の端末にサーバ側から投げるのは家のファイヤウォールあけるか端末側からつなげっぱにして切れたら再接続とか面倒なことになりそうなので端末側から定期的に見に行く。セキュリティ的にも件数返すだけAPIならあんま頑張んないでもよさげなので。

今回やる範囲

2のAPIを立てるとこ。nginxは未インストールの状態から。pythonはhttp.serverあたりを使ってnginxからproxyで飛ばす予定。あとは実作業しながら書いていく。

開始前の状況

postfix+dovecotでMaildir形式でメールサーバを構築済み。なお、”Ubuntu 22.04.3 LTS”

また、LetsEncriptでtls通信をさせているため証明書も入手済み。ただ、80番ポートが空いている前提のstandaloneモードで証明書の更新をしているためwebroot方式?だかに直さないといけないはず。

メールサーバに予約っぽいメールが来たときはsieveで規定フォルダに振り分けている。設定ファイルはしたので、題名に”予約確定通知”か”予約が確定”とあったら”INBOX.ジム.予約”フォルダに振り分けるというもの。(サンダーバードだと”「受信トレイ」の下の「ジム」の下の「予約」”)

作業開始

nginxインストール&設定

して、とりあえず443ポートをあける。(letsencript使うのに80番も開ける必要があるはずなので空いてなければそちらも)

既に作成済みの証明書を見る形でhttpsを有効にする。ついでにhttpからhttpsへのリダイレクトもかけておく。あと、nginxのバージョンも一応隠す。

で新規ファイルを作り下を追加

でnginx再起動

これでとりあえずブラウザからサーバにサクセスするとhttpsに転送されてnginxにもとから入っているwelcome画面が表示されるはず。

pythonを使えるようにする

nginx側のproxy設定

ssl.conf(と深く考えずに名前を付けたので)に直接かくものじゃないのでインクルードして/etc/nginx/conf.d/mail_api.txt に設定を書く。mail_api.confと拡張子をconfにすると/etc/nginx/nginx.confからのinclude設定と重なり多分うまく動かない。

でserver(443の方)の末尾にインクルード設定を追加

そしてmail_api.txtを作成

にて

これでsudo systemctl restart nginx したら8000番ポートで起動している奴があればそちらにリクエストをすべて飛ばすはず(location / で ルートディレクトリ以下全部)。8000番起動していなくてもとりあえずnginxを先に起動できると思う。

python側のリクエスト受信

http.serverにてnginxのproxyで指定した8000番ポートで待ち受け機能を作る。

(本来ローカルで完結するのでファイヤウォールの8000番は開かなくてよいけどVSCodeでやるとちょいちょいつなげに行こうという処理が走って面倒だった)

取り急ぎmailサーバの任意の場所に以下のmail_api.pyを作ってpython3 mail_api.pyで起動

ローカルのPCからhttps://mail.hoge.co.jp/api/reserve_countにアクセスするとstatus200 で Hello, this is the root path.という文字がかえる。

他だとstatus404 で 404 not foundという文字がかえる。

/api/reserve_count が呼ばれたときに実際に件数を返す処理を作る

response_content = b’Hello, this is the root path.’のところを件数返す関数に変更

してvi reserve_count.py し関数作る。例外処理ちゃんと入れていないので各自実装必要。

あんまり落ちなそうな気はするので実際には例外処理なしで突き進む。あと、ログイン代わりにquery_paramsみてパラメータがあっていたら件数確認処理呼び出すような緩いセキュリティ分岐を入れるつもり。

VSCodeのmarkdownlintの設定

直したこと

VSCodeにmarkdownlintの拡張を入れたらMD024 – Multiple headings with the same content と怒られた。マークダウン内に同じ見出し文言があると怒られるやつらしい。

章1ほげ

1-1.この章の概要

章2ふが

2-1.この章の概要

みたいに章をまたいで同じものを使おうとすると引っかかる。面倒なので停止。

直し方

VSCodeでCTRL+commmaから拡張機能のmarkdownlint->setting.jsonと選んで”markdownlint.config”: {        “MD024”: false    }を追加


    "editor.renderWhitespace": "all",
    "markdownlint.focusMode": false,
    "markdownlint.ignore": [],
    "markdownlint.config": {
        "MD024": false
    }
}

pythonのimport imaplibで日本語フォルダ名を使う場合はエンコードが必要

環境

  • PRETTY_NAME=”Ubuntu 22.04.3 LTS”
  • Python 3.10.12
  • pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

手順

imap_toolsというのが楽らしいのでインストール

pip install imap_tools

インポートして実行

import imap_tools
mailbox_name = "INBOX.ジム.予約"
status, messages = mail.select(imap_tools.imap_utf7.encode(mailbox_name))


※Ubuntsuを24にあげたときにインストールしたimap_tools-1.7.2ではimap_tools.imap_utf7.encodeからimap_tools.imap_utf7.utf7_encodeと微妙な名称変更が入っている

何もしない場合のエラー

mail.select(“INBOX.ジム.予約”)

として

yoshitake@mail:~/dovecot_delivery$ python3 test.py 
Traceback (most recent call last):
  File "/home/yoshitake/dovecot_delivery/test.py", line 15, in <module>
    mail.select("INBOX.ジム.予約")
  File "/usr/lib/python3.10/imaplib.py", line 756, in select
    typ, dat = self._simple_command(name, mailbox)
  File "/usr/lib/python3.10/imaplib.py", line 1230, in _simple_command
    return self._command_complete(name, self._command(name, *args))
  File "/usr/lib/python3.10/imaplib.py", line 987, in _command
    arg = bytes(arg, self._encoding)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 6-7: ordinal not in range(128)

ソース全体

import imaplib
import imap_tools
from email.header import decode_header

# IMAPサーバの設定
mail_server = 'mail.huga.co.jp'
username = 'hoge'
password = 'hugahuga'

# IMAPサーバに接続
mail = imaplib.IMAP4_SSL(mail_server)
mail.login(username, password)

# # メールボックスを選択
mailbox_name = "INBOX.ジム.予約"
status, messages = mail.select(imap_tools.imap_utf7.encode(mailbox_name))

# # メール検索(例: 未読メール)
status, messages = mail.search(None, "(UNSEEN)")
unread_count = len(messages[0].split())
print(f"未読メールの件数: {unread_count}")

# 接続を閉じる
mail.close()
mail.logout()

ロシェ桃山年末年始の営業時間

年末年始は30まで通常営業。

1/31日は18:00閉店 1/1 休業 1/2-4 は事前電話予約ある時間営業となります

12/27 14:30-23:00
12/28 14:30-23:00
12/29 14:30-23:00 
12/30 10:00-23:00 
12/31 10:00-18:00 
1/1 休業 
1/2 要電話予約(10:00-23:00) 
1/3 要電話予約(10:00-23:00) 
1/4 要電話予約(10:00-23:00)

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事態を持っていないのでレーザーカッターでアクリルを切り抜いたやつで作る予定。