無意味のような生き方

組込みエンジニアが怒りと無念をさえずるブログ。

【組込みOS開拓史 PART3】機能設計_メモリ ①事前知識

組込み最重要課題のメモリ設計。

 

リンカスクリプト解説】

<コマンド系>

OUTPUT_FORMAT("ファイル形式"):実行ファイル形式

OUTPUT_ARCH():h8300h

ENTRY():

MEMORY{}:物理的メモリ構成を決める

SECTION{}:メモリ領域を役割ごとに分割する

 

<MEMORY内記法>

xxxxx(rx)             : o = 0x000000, l = 0x080000

:xxxxx→領域名。※romall ramallは?

  (rx)→読み出し・書き込みの性質を定義。

 o → 領域の開始(オリジン)アドレス

  l → 領域の長さ(レングス)。

 

<SECTION内記法>

.:ロケーションカウンタ。セクション領域の先頭に「. = 0x00 」と記述することで、後続を0x00以降にマッピングで     

  きる。アドレス配置はMEMORYコマンドで管理できるため、上記の記述は不要。

  ロケーションカウンタを取得する場合は、「_text_start = . ;」と記述する。セクションの開始/終了アドレスを

  知るために、この記述は必要。(MEMORYで定義されているstackのようなセクションでもなぜ必要なのか?)

.xxx:{ aaa.o(.bbb)} > ccc

  :xxx→セクション生成。.vector={}で、vectorというセクションが作られる。

  aaa.o(.bbb)→aaa.oというオブジェクトファイルの.bbbセクションのデータをc領域に配置。

   (初期値なし変数は.bssセクションと、どこで決まっている?)

  例:.text:{ *(.text) }> rom   *は全オブジェクトファイルファイル

 

PA≠VA対応】

初期値つき変数の場合、書き込み時のアドレス(ROM)と、実行中にアクセスするアドレス(RAM)を分ける。

プログラムの初期化時に、RAM→RAMへのコピーを行う。

このことをPA≠VA対応と言い、これによって、初期値つき変数の動的な書き換えが可能になる。

PA物理アドレス(ロード・アドレス)。変数の初期値が配置されるアドレス。

VA:仮想アドレス(リンク・アドレス)。プログラムがアクセスするアドレス。

 

【メモリ配置を考える】

※マニュアル「3.6 各動作モードのメモリマップ モード5」および『OS本』 p.92参照。

※データ長の算出

:開始アドレス「0x00」 終了アドレス「0xFF」の場合、データ長は「0x100」。

  開始アドレス0x00の領域+0x01~0xFFの領域となるため。

 

【用語一覧】

・リンクとは

コンパイルして生成された複数のオブジェクトファイルを結合すること。

 

リンカスクリプトファイルとは

:メモリ配置を定義しているファイル

 

・プログラムがRAM/ROM上で動く、とはどういうことか?

機械語コード(.text領域)がRAMにあるか、ROMにあるか。

【組込みOS開拓史 PART2】機能設計_起動 ①スタックポインタの初期化

まずは、起動に関する設計を行う。設計の対象は、マイコンの電源をONしてから、main関数がコールされるまでの処理だ。普段、仕事でやっている組込みよりも、さらに「下」の領域だ。「レジスタの操作をアセンブラで行う」という痛快なことをやる。

 とりあえずスタックポインタの初期化からはじめる。

 

【起動シーケンス】
①電源ON
②リセット割込み
 (リセット割込みベクタに登録済の関数start()がコールされる。)
 ※割込みベクタについては、別途、割込みの設計をする時に考える。
③割込みベクタ内でスタックポインタの初期化
④main関数へジャンプ
→ 以降のシーケンスは「機能設計_ブートローダ」に記載する。

 

【スタックポインタの初期化】
スタックポインタ:スタック領域の最上段*1のアドレスを格納するレジスタ。ここからスタック領域として使います!という目印としての役割を果たす。

 

・スタックポインタをどうやって設定するか?
マイコンマニュアルによれば、「sp」というレジスタが用意されているらしい。関数をコールする際、何もしなくても、spが勝手にスタックポインタとしての役割を果たしてくれる。よって、僕がやるべきことは、spに対し、スタックポインタとしたいアドレスを代入することだけだ。

 

<スタックポインタの設定方法>
レジスタ「sp」について

f:id:ikenohotorino:20181125230515p:plain

ER0~ER7:汎用レジスタ(32bit)

 

ER7という32bitのレジスタがスタックポインタのレジスタとして使えるらしい。上の表だと(SP)というのがどの領域かわかりにくい。*2

 

レジスタへのアクセスについて
マニュアル「2.7 アドレッシングモードと実効アドレスの計算方法」を読むと以下のように書いてある。

 

レジスタ直接  Rn
レジスタ間接  @ERn
イミディエイト  #xxx(レジスタ、値)

 

他にもアクセス方法はあるが、今の所は直接アクセスの方法がわかればいい。ER7とかけば、ER7のレジスタにアクセスできるようだ。また、ER7にかんしては、spと言い換えができるらしい。*3

 

レジスタへの命令は以下のように書く。(『組込みOS入門』(以下『OS本』)より

 

mov.l #_stack,sp

 

- mov A B:A→Bへのデータ転送。(.lはlongワード型を表す。アドレスなので4バイト。)
- _stackは、stackをリンカスクリプトで定義している。_stackと記述することで、アドレスを表す。(別途記載する)
- #は、即値命令を表す。*4

 

・実際にどのアドレスから何バイトをスタック領域として使うべきか?
具体的なコードでいうと、stackをリンカスクリプトファイルのどこに書けばよいかという問題だ。スタック領域がどれだけのサイズになるかは、実行してみないと分からない。よって、『OS本』では、RAMの末端付近に配置している。

 

stack(rw) : o = 0xffff00, l = 0x000000 /* end of RAM */

 

o:開始アドアドレス
l:サイズ

 

・なんでアドレス「0xffff00」が末端付近だとわかるのか?
マニュアル「3.6 各動作モードのメモリマップ」および『OS本』 p.92に記されている。

 

【用語一覧】
・スタートアップ
:起動時に始めに実行される処理。リセットのベクタ内に書かれているorベクタからジャンプした先に書かれている。

 

*1:言い方

*2:ER7全体を使えるのか?

*3:どこに書いてある?

*4:ここがよくわからない。#を外してコンパイルしたところ、「invalid operands」というエラーになった。

【組込みOS開拓史 PART1】組込みOSはじめます。

『組込みOS自作入門』*1という本を2017年の8月から読んでいる。組込みエンジニアとしてのスタートをきった直後、何か作ってみたいとやる気に溢れて購入した。全12章のうち1章~4章くらいまで意気揚々と読んでいたものの、割込みを扱う7章くらいから理解に急ブレーキがかかり、何もかも分からなくなって、大いに挫折した。

その後、何章が読んでは別な本やゲームに気を取られて中断し、内容を忘れて読み進められなくなることが続いていた。今年の夏休みに一念発起して1章から腰を据えて取り組んだが、やっぱり割込みの章で難しくなって辞めてしまった。その時、1年前と比べて何も成長していなんじゃないかと不安になった。組込みの門をいつまでもくぐれない。

本を1ページずつ読み進めているから駄目なんじゃないか。本の説明は分かりやすいけど、覚えておくことが多いので、何日か経つと半分以上は忘れてしまい、いつも思い出すことから始めなければいけなくなる。いっそのこと、自分で作る(という体をとる)ことにしよう。

 

■要件定義

【要求1】組込みOSを自作する

要件1. 割込みによる文字列の受信処理を行う。

要件2. 優先度つきマルチタスクで動かす。

要件3. タイマ割込みを使ってストップウォッチのようなものを作る

【要求2】OSが起動するまでの処理を自作する。

要件1. ブートローダーを使用してRAM上でプログラムを動かす。

要件2. メモリ領域を設計する。

要件3. ライブラリ関数を自作する。

 

基本的には『組み込みOS入門』の内容を全部やりたいと思っている。ただ、ソースコードを(可能な限り)MISRA-Cの規約通りに書く、という所にこだわりたい。それと、本の内容だけだとつまらないので、「タイマ割込み」を使った処理を追加することにした。本当はLEDとかデバイスの操作を行いたかったが、H8マイコンの基盤にデバイスをつける方法を調べて絶望したため、放棄する。

 

■成果物

機能設計書

詳細設計書

ソースコード

試験項目書・ログ

 

大人のキッザニアなので、ちゃんと残すものを作りたい。機能設計は、タスク、メモリ、通信、など機能ごとに1ファイルを作る。オンボロPCで作業しているため、空き容量の事情でエクセルが使えないので、テキストのべた書きで妥協する。詳細設計書は関数の内容まで書くと膨大な量になりそうなので、関数Aが関数Bを呼ぶ、、みたいにコールグラフを書く程度にしようと思っている。試験については、どうやってやろうか考え中。cygwinでいきなり実行されてしまうので、細かいテストはしようがない。

 

■スケジュール

11/25-:機能設計(起動・メモリ)

12/2-:機能設計(ブートローダ・通信)

12/9-:機能設計(割込み)

12/16-:機能設計(タスク)

12/23-:詳細設計

12/30-:コーディング①

1/6-:コーディング②

1/13-:試験項目作成

1/20-1/27:テスト実施・リファクタリング作業

 

機能設計は各機能が依存し合っているのでこの通りは進まないと思う。(起動させるために割込みを使ったり、タスクのためにメモリの設計が必要となったりすると思う。)なので、機能設計は、その時点で想定している設計ができていればOKとする。例えば、11/25-のメモリ設計は、起動処理の時点でのメモリの設計書を作ること目指す。

コーディング期間が短いような気がするが、冬休みに入るのと、機能設計しながらソースも作っていく予定なので、大した量は残っていない想定。1/27日に終わらせることを目標としている。何かをやりきった経験がないので、とにかく「終わらせる」ことを目標としたい。

  

 

12ステップで作る組込みOS自作入門

12ステップで作る組込みOS自作入門

 

 

*1:すごく面白い

まあ、カズレーザーとかもいるし

 今週末、一人で映画を観に行った。

豊洲の映画館で『プーと大人になった僕』を一番遅い時間帯に鑑賞する。内容の感想はあまりない。やってほしいことを全部やってくれたので満足感が得られた。「なにもしないをするのが最高な場合もある」(売る覚え)というのがテーマだったが、「場合もある」の部分のせいで教訓めいて微妙だった。仕事と家庭を天秤にかけて仕事を選んできた男のラストが、家庭が一番大事、だけど仕事もちゃっかり上手くいく、では誰も納得せんでしょう。かといって、家庭を大事にして失職する話だったら難易度が高すぎるかもしれないが。『最高の人生の見つけ方』がそうだったが、映画の中では家族が一番大事とうたいつつ、最後に社会的にめちゃくちゃ成功するというラストがもやもやする。最終的には成功と金で納得させてるやん。

 

最近、仕事で少しやらかした。「やらかした」と文字にして書くべきだと思う。大人数かつ複数のチームで仕事をしているから、誰か一人に全責任があるということはない。けど、一番責任が大きいチームの、一番責任が大きい人間は、間違いなく僕だった。発覚したときはグエーッとなったが、後に爽やか。まだまだ自分はしょぼいという事がわかった。その仕事は片付いていないけれど、週末で燃え尽き症候群になった。何もしないで2日間丸くなり、やっと日曜の夜に映画を観に行けた。

 

映画館を出たら、観覧車が光ってた。カップルが並んで夜景を見ている間を通って、前を向いて帰る。駅までの帰り道、すれ違う人が全員普通に見える。僕が来ている服と靴と鞄はすごく変な気がする。前を横切る人たち(だいたい複数)をずっと目で追っていたけれど、僕みたいな人はいなかった。参加する資格の他に、楽しむための資格がいることが多すぎる。歩いている人全員がきちんと服を着ている時点で本当は偉いはずなのに。ファッションがまともじゃないと好かれない?まあ、カズレーザーとかもいるし、そんなこともないと思いたい。

 

終末感がある

何かと平成最後が強調されるけど、その刷り込みのせいか、世界の終わり感が強まってきているように感じる。仕事をしていても、身が入らないというか、物足りなさのような感覚をもってしまう。物足りなく感じるほど余裕があるわけではないと言いつつ、そこまで重要ではないのかなと思ってしまう。いつまでこんな日常が続くのかよくわかっていないし。天気も最近やたら雨ばかり降る。

 

敦煌

敦煌』という小説を読んだ。読んだきっかけは、シルクロードに興味があったから。大学時代、敦煌の講義を(なぜか)受けて、えらく感動した。その講義は落ちたような気もする。身の保証など全くないのに、ただ商売をするために国を超えて何万kmも歩く人達。言葉が不適切かもしれないが、すごく一途に思える。一人一人の人生もあったのだろうが、今の視点では、より世界史とか文化史を生きているように感じる。RPGに登場するキャラのように、全員が明確な役割をもっていて羨ましい。

 

 

敦煌に行きたくなったらいいなーという気持ちで読み始めたが、今敦煌に行きたいかと言われると、そうでもない。安全で金があるなら行きたいけど、行って何かをしたいわけではない。旅行に行く人の動機って何だろう。何かを見ることであれば、写真や動画で十分見ることができる。自分の経験上、観光地に行ってパンフレット以上の景色が見れたことは一度ない。写真より肉眼にこだわる理由も特にない。何かをすることであれば現地に行かなきゃならないが、日本で体験できないことってあまりない気がする。個人的にどうしてもやりたいことがない。いや、そもそも、「したことがない=今までしなくても生きてこれた」わけだから、必然的にどうしてもやらきゃならないものではないはずなのだ。そう考えると、むしろ行きたくなってくる。このくらいの気持ちでも行っていいんだと思う。

 

 

小説『敦煌』の感想。完全に自分のせいだけど、途中で登場人物を見失ったせいで、内容を完全には把握できなかった。超重要な登場人物が4人いて、そのうちの2人を同一人物だと思っていたせいで後半わけが分からなくなった。武闘派でバイリンガルで名家出身の僧侶が実は2人だったというのが一番驚きだった。それと、敦煌という地名が本文で全く使われていないのが切ない。本の中では「沙州(敦煌)」とたまに書かれているくらいで、会話では一切出てこない。歴史物あるあるだけど、現代で有名な名前が当時は使われていないことが多い。真田丸でも誰も幸村って呼ばない現象。

 

普段、歴史小説をほとんど読まないので、主人公の心情がすごく分かりづらいのが新鮮に感じた。主人公は知識人だが、生への執着が乏しく、生きる意味とかをいちいち考えない。途中で危険な出来事が色々と巻き起こるが、主人公の態度は最後まで変わらなかった。どうなってもいい(興味がない)という態度で、めちゃくちゃ弱いのに前線の兵士に自ら志願したりする。命の価値が薄いというか、自分のことを重く考えていない雰囲気が読んでいて爽やかで心地いい。

 

仏像の中に巻物を埋めるスケール感と、後に発見されるときのカタルシスのやばさ。映像にするといいのはわかる。

 

敦煌 (新潮文庫)

敦煌 (新潮文庫)