[PR] 本記事にはプロモーションが含まれています。

【入門編 第8回】振り返りと「Web と組み込みの対応表」(Step 0・1 のまとめ)

TypeScript

はじめに

前回で、Step 1 の単位換算ツールを自宅サーバーで公開し、要件定義書の受け入れ条件をすべて満たしました。第1回で紹介したロードマップでいえば、9段階のうち、最初の2段階が終わったところです。

この回は、ここまでの区切りとして、振り返りを書きます。V字モデルの最後の工程で、ツールごとに書いている「04_振り返り.md」を、シリーズ全体に広げたものです。組み込みでいえば、プロジェクトの終わりの反省会と、そこで残すノウハウ集にあたります。

最後に、ここまでに出てきた Web の概念を、組み込みの言葉に置き換えた対応表を1つにまとめました。同じように組み込みから Web に入る方の、手元の早見表として使っていただければうれしいです。

Step 0・1 で作ったもの

Step 0:helloStep 1:unitconv
何をするツールか「Hello」とサーバーの時刻を表示する血液検査の値の単位を換算する
画面の作り方サーバーのプログラムの中で HTML を組み立てるVite でビルドした画面のファイルを返す
計算する場所サーバー(時刻を取るだけ)ブラウザ
主に学んだことビルド、常駐、中継、認証、公開の経路HTML、TypeScript、イベント、Vite、配信
組み込みでいうとLチカ入力を読み、計算して、表示するファーム

どちらのツールにも、次の4つの文書を残しています。

文書内容分量
01_要件定義.md何を作るか、何ができたら完成かA4 で1ページ強
02_設計.mdどう作るか(構成、画面、データ、ファイルの置き場所)A4 で2ページほど
03_テスト項目.md単体・結合・受け入れの確認と結果Step 1 で31項目
04_振り返り.mdできたこと、つまずいたこと、覚えたこと、次にしたいことA4 で2ページほど

ソースと文書は、ツールごとに Git で管理し、GitHub の非公開リポジトリに送っています。Step の区切りには、step0-done、step1-done という目印(タグ)を付けました。出荷したファームに版番号のラベルを付けておくのと同じで、いつでもその時点の状態を取り出せます。

ご注意:このシリーズで作るツールやアプリは、すべて学習を目的としたものです。医療的な判断には使わないでください。検査結果の解釈や健康上の判断は、必ず医師にご相談ください。

テスト項目書の書き方

第3回で要件定義書と設計書を紹介したので、V字モデルの右側にあたるテスト項目書も、ここで紹介しておきます。確認の手順と結果そのものは、第5回〜第7回で、その作業をした回に分けて載せてきました。ここでは、それを1つの文書にまとめるときの形を示します。

表の列は、すべてのツールで次の7つに統一しています。

列書くこと
No区分の記号と通し番号(U-01 など)
対応要件どの要件を確かめる項目か(F-01、N-02 など)
確認内容何を確かめるか
手順何をするか(打つコマンドや、画面での操作)
期待結果どうなれば合格か
結果OK/NG
日付確かめた日

「対応要件」の列があるので、要件定義書の F-01 などから、どの項目で確かめたかを逆にたどれます。組み込みの試験成績書で、試験項目に要求 ID を書いておくのと同じです。

項目は、V字モデルの段階に合わせて4つの区分に分け、No の先頭の記号で見分けられるようにしました。

記号区分V字モデルで対応する工程確かめる範囲Step 1 の項目数
U単体確認実装計算の関数だけ4
S画面の確認実装・設計開発サーバーで、画面の操作と表示10
I結合確認設計サーバー単体、PM2、Apache 経由12
A受け入れ確認要件定義外部の URL から、利用者と同じ使い方で5
振り返りと「Web と組み込みの対応表」:テスト項目書の書き方

各区分から、実際の項目をいくつか抜き出すと、次のようになります(URL やポートは架空の値です)。

No対応要件確認内容手順期待結果結果
U-01F-01、F-03血糖の換算100 mg/dL → SI5.55 mmol/LOK
U-04F-01、F-03クレアチニンの換算100 mg/dL → SI8840.00 µmol/LOK
S-02F-03逆向きの換算血糖・SI → mg/dL・5.5599.99 mg/dL、単位の表示が mmol/LOK
S-06F-05負の値-5 を入力「0 以上の値を入力してください」OK
I-03設計 §2JS の配信curl -sI で JS を要求200、text/javascript、immutableOK
I-06設計 §2dist/public の外を狙うcurl –path-as-is で ../../../etc/passwdNot Found(中身が出ない)OK
I-09設計 §2自動再起動プロセスを kill -9PM2 が再起動し、再起動回数が増えるOK
A-01N-02認証の後の表示PC で https://example.com/apps/unitconv/ を開く認証の後に画面が出るOK
A-04N-03スマホの実機スマホで開いて換算するはみ出さず、数字のキーボードで換算できるOK

大事なのは、「期待結果」を、確かめる前に書いておくことです。期待結果が先に決まっていれば、結果を見たときに合否で迷いません。I-06 のように「何が出ないこと」を期待結果にする項目も、表にしておけば確かめ忘れを防げます。

正直な感想

Step 1 を終えたときに、振り返りとして書いた言葉を、そのまま載せます。

いちばん「わかった」と感じたこと:まだまだふわふわした感じで自分のものにできていないが、処理の流れが見えてきた気がする。

いちばん苦労したこと:全体的に組み込みのベアメタルと違うので、概念だけが多く、少し戸惑っている。

これからについて:TypeScript も初めて(JavaScript すら初めて)だが、計算部分だけで言えば大きくは変わらないので、ついて行けていると勝手に思っている。

戸惑いの正体を考えてみると、覚える量が多いのは、扱う「箱」の数が多いからだと思います。ベアメタルでは、CPU とメモリと周辺回路という、目に見える1台のハードウェアの上ですべてが完結していました。Web では、ブラウザ、Cloudflare、Apache、Node.js、ビルドの道具という別々の箱が、それぞれのルールでつながっています。

それでも、要求が来て、住所を引き算して、ファイルを返し、ブラウザで計算する、という流れは見えてきました。名前はまだふわふわしていても、流れが見えていれば、細かいところは使ううちに定着していくはずだと考えています。

つまずいたことと教訓

Step 0 と Step 1 でつまずいたことを、教訓とあわせて並べます。プログラムそのものより、道具や手順でのつまずきが多かったのが印象的でした。

環境と運用

つまずいたこと解決方法・教訓詳しくは
Node.js と PM2 が、ユーザーごとに別の系統で入っていた使うものを1つに決め、方針を文書にしてから触る第2回
自動起動の設定に、VS Code の PATH が紛れ込んだ必要なフォルダだけを指定して登録し直す第2回
中継するパスには .htaccess の認証が効かないURL のパスに対して、サイト全体の設定で認証をかける第2回
設定を1つ変えると、同じサーバーのブログまで止まるおそれコピー → 差分確認 → 文法チェック → 反映 → 回帰テスト、の順を崩さない第2回・第7回

理解

つまずいたこと解決方法・教訓詳しくは
Vite の base(住所の足し算と引き算)がつかめなかった要求の流れを図で1手ずつ追う第4回
「転送」が中継とリダイレクトのどちらかで混乱した誰が動くか(サーバーが渡すのか、ブラウザが要求し直すのか)で区別する第4回
1行に詰まった書き方(ITEMS.find((it) => …))が読めなかった部品に分解し、C で書いたらどうなるかに置き換える第5回

Git

つまずいたこと解決方法・教訓
保存し忘れて、空のファイルをコミットしたコミットの前に、エディタの未保存の印と git status を確かめる
日本語のファイル名が \350\250… と表示されたgit config --global core.quotepath false
初期のブランチ名が master だった/リポジトリ名が決めた規則と違った初期値を main に設定し、名前は早いうちにそろえる
push で認証エラーになったVS Code のターミナルを開き直す
コミットし忘れて、別の変更と混ざりかけた動作確認が OK になったら、次の話題に移る前にコミットする

Git のつまずきは、番外編で詳しくまとめています。

こうして並べると、ほとんどが組み込みの現場でも身につけてきた習慣で防げるものでした。「現状を調べてから触る」「変更は差分を確かめてから」「試験に通ったら記録を残す」。道具が変わっても、効くのは同じ習慣だと感じています。

Web と組み込みの対応表

このシリーズで、新しい概念に出会うたびに作ってきた「組み込みでいうと」を、1つにまとめました。まずは全体を、層ごとに大づかみに置き換えた図です。

画面、画面のプログラム、ブラウザ、通信、中継、サーバー、道具の各層を、組み込みの基板の部品、ファームウェア、メインループ、通信プロトコル、ブリッジ、ダウンローダ、ツールチェーンに対応させた図

以下は、項目ごとの対応表です。

道具とビルド

Web の概念組み込みでいうと
tsc(TypeScript のコンパイラ)コンパイラ
Vite のビルドコンパイル&リンクして ROM イメージを作る
Vite の開発サーバーと自動更新(HMR)ICE につないで、保存のたびに書き込みとリセット
base(/apps/<ツール名>/)リンカスクリプトで指定する配置アドレス
ファイル名のハッシュ(index-xxxx.js)ファーム名に CRC を含めて、版の取り違えを防ぐ
npm と package.jsonパッケージマネージャと make、部品表
node_modules/SDK のライブラリフォルダ(構成管理には入れない)
ソースマップ(.map)アドレスとソース行の対応を持つデバッグ情報
strict: true の型チェック-Wall -Werror

TypeScript の書き方

Web の概念組み込みでいうと
interface / typestruct / typedef
ユニオン型・リテラル型enum
readonly 配列const 配列
undefinedNULL
結果型 { ok: true; value } | { ok: false; error }タグ付き共用体(タグの確認を型チェックが強制)
export / importヘッダの公開宣言(extern)と #include
アロー関数とクロージャ関数ポインタ+コンテキスト(void *ctx)
as(型の指定)キャスト
async / awaitDMA を起動して、完了割り込みを待つ

画面とイベント

Web の概念組み込みでいうと
HTML の部品と id基板の部品と、レジスタの名前
getElementByIdレジスタのアドレスを取得する
.value を読む/.textContent に書く入力レジスタを読む/表示器のレジスタに書く
イベント(change、input)割り込み要因
イベントループ実行環境が持つメインループ
addEventListener割り込みベクタへのハンドラ登録
console.logUART への printf デバッグ

通信とサーバー

Web の概念組み込みでいうと
HTTP の要求と応答コマンド/レスポンス型の通信プロトコル
ステータスコード(200、301、404…)応答コード(ACK/NAK)
リダイレクト(301、302)「このアドレスへ再送して」という応答。再送はホストが行う
中継(Apache の ProxyPass)中継器、ルーティングテーブルの1行
サーバーが base を引くペリフェラルのアドレスデコード
境界チェック外から受け取った添字の範囲チェック
PM2ウォッチドッグ付きの起動管理
pm2 save起動構成を不揮発メモリに書き込む
環境変数(env)ディップスイッチ、設定用 EEPROM
ログのタイムスタンプ(末尾の Z)UTC で記録した RTC の時刻

もちろん、どれも完全に同じではありません。違いに気づいたところが、そのまま理解が深まったところでもありました。たとえば、TypeScript の型チェックは、C のコンパイラよりも一歩踏み込んで、NULL やタグの確認漏れまで見張ってくれます。

AI と進めていて役立ったこと

このシリーズの学習は、AI(Claude)に質問しながら進めています。ここまでで、役に立ったと感じた進め方を残しておきます。

前提と方針を文書にして、毎回読ませる

サーバーの構成や、ツール開発で守る「決定事項」を1つの文書にまとめ、AI が会話のたびに読む場所に置きました。あわせて、自分の経歴と、教え方の希望(細かいステップで、組み込みの言葉に置き換えて、1回に詰め込みすぎない)も文書にしています。会話が変わっても前提がぶれず、提案が毎回少しずつ違う、ということが減りました。

わからない1行は、そのまま聞く

ITEMS.find((it) => it.id === id) や valueInput.value.trim() のように、1行の意味がわからないときは、その行をそのまま貼って「これは何?」と聞きました。部品に分解して、C ならどう書くかと並べて説明してもらうと、ほとんどの場合すっきりしました。

図にしてもらう

文章の説明でわかったような、わからないようなときは、図にしてもらいました。base の足し算と引き算や、開発中と本番の違いは、要求の流れを1手ずつ進める図にしてもらうことで、整理できました。この連載の図も、そのときの図をもとにしています。

AI の説明も、コマンドで確かめる

AI の説明が、いつも正しいとは限りません。実際、「開発サーバーで / を開くと案内のページが出るはず」という説明が、試してみると自動で転送される動きだったこともありました。そのときは、curl で応答を見て、302 という転送が返っていることを確かめ、正しい理解に直せました。

説明を鵜呑みにせず、手元で動かして確かめる。組み込みで、データシートの記述を実機で確かめるのと同じ姿勢が、ここでも大事だと感じています。

これから

次の Step 2 では、計算 API を作ります。Step 1 ではブラウザの中で行っていた換算の計算を、サーバー側に移し、画面からサーバーに「この値を換算して」と頼んで、結果を受け取る形にします。

Step 1Step 2
計算する場所ブラウザサーバー
サーバーの仕事画面のファイルを返すだけ画面のファイルを返し、計算もする
新しく学ぶこと―HTTP の要求と応答の中身、JSON、fetch、非同期処理
組み込みでいうとターゲットだけで完結する処理ホストとターゲットが、コマンドとレスポンスでやり取りする処理

HTTP のコマンドとレスポンスは、組み込みの通信プロトコルに近い話なので、むしろ馴染みやすいのではないかと期待しています。同じ計算をブラウザとサーバーのどちらで行うかを比べることで、画面とサーバーの役割分担も見えてくるはずです。

その先は、記録ツール(データの保存)、データベース、グラフ表示、ファイルの取り込みと続き、最終目標の血液検査アプリに向かいます。紙で受け取った検査結果をスキャンした PDF から、文字認識(OCR)で値を読み取る、という難所も控えています。

この連載も、Step ごとに続けていく予定です。次は番外編として、Step 0・1 で Git につまずいたことをまとめます。

この記事は、シリーズ「組み込みエンジニアの Web 開発入門」の1本です。ほかの回は、シリーズの目次からどうぞ。

ほかの開発・プログラミングの記事は、開発・プログラミングメモの目次から、テーマ別に探せます。

このブログは、にほんブログ村と人気ブログランキングに参加しています。記事が役に立ったら、下のランキングのバナーのどれかを押して応援してもらえると励みになります。

ブログランキング・にほんブログ村へにほんブログ村

サーバー構築・運用ランキング プログラムランキング

TypeScript
watasoftdevをフォローする

コメント