コグノスケ


link 未来から過去へ表示  link 過去から未来へ表示(*)

link もっと前
2024年5月31日 >>> 2024年6月30日
link もっと後

2024年5月31日

Bitbakeのクラス

目次: Yocto

Yocto Scarthgap(5.0.1)のメモです。前回同様、コードを読んで依存関係を調べるのは大変時間が掛かるので、簡易的な調査手法として全ファイルを消してエラーを観察し、エラーの原因となるファイルを復活させて次ステップに進める手段を用います。

引き続きBitbakeを実行してエラーを見て、足りないファイルを元に戻していくという方法で各パーツや設定の動作を見ます。

クラスが見つからないエラー
$ bitbake core-image-sato

ERROR: Unable to parse /home/katsuhiro/share/projects/oss/poky/bitbake/lib/bb/parse/parse_py/BBHandler.py
Traceback (most recent call last):
  File "/home/katsuhiro/share/projects/oss/poky/bitbake/lib/bb/parse/parse_py/BBHandler.py", line 71, in inherit(files=['base'], fn='configuration INHERITs', lineno=0, d=<bb.data_smart.DataSmart object at 0x7f7a85863c50>, deferred=False):
             if not os.path.exists(file):
    >            raise ParseError("Could not inherit file %s" % (file), fn, lineno)

bb.parse.ParseError: ParseError in configuration INHERITs: Could not inherit file classes/base.bbclass

なにやらclassesというディレクトリと、*.bbclassというファイル名が出てきました。これはクラス(Classes - The Yoct Project)といってレシピ間で処理を共有するための仕組みです。ドキュメントによると3種類あるそうです。

  • classes-recipe/ - レシピに個別に継承されることを意図したクラス
  • classes-global/ - グローバルに継承されることを意図したクラス
  • classes/ - 使用コンテキストが明確に定義されていないクラス

Yoctoのクラス(*.bbclassファイル)は全部meta/classes-globalかと思ったらそうでもなく、一部のクラスはmeta/classesディレクトリに配置されています。

エラーメッセージはmeta/classes/base.bbclassがないと言っていますが、ファイルの実際の在処はmeta/classes-global/base.bbclassです。どういうことでしょう?Bitbakeのソースコードを見ると、

Bitbakeのクラスの検索処理

# bitbake/lib/bb/parse/parse_py/BBHandler.py

def inherit(files, fn, lineno, d, deferred=False):
    __inherit_cache = d.getVar('__inherit_cache', False) or []
    #if "${" in files and not deferred:
    #    bb.warn("%s:%s has non deferred conditional inherit" % (fn, lineno))
    files = d.expand(files).split()

    #★★files配列には'base'だけが入っている★★
    for file in files:
        classtype = d.getVar("__bbclasstype", False)    #★★classtype = global★★
        origfile = file

        #★★classes-global/base.bbclassがなければ、classes/base.bbclassを探す★★
        for t in ["classes-" + classtype, "classes"]:
            file = origfile
            #★★パスと拡張子を連結★★
            if not os.path.isabs(file) and not file.endswith(".bbclass"):
                file = os.path.join(t, '%s.bbclass' % file)

            if not os.path.isabs(file):
                bbpath = d.getVar("BBPATH")
                abs_fn, attempts = bb.utils.which(bbpath, file, history=True)
                for af in attempts:
                    if af != abs_fn:
                        bb.parse.mark_dependency(d, af)
                if abs_fn:
                    file = abs_fn

            if os.path.exists(file):
                break

        #★★どちらもないと最後に探したパス名でエラーメッセージを出してくる★★
        if not os.path.exists(file):
            raise ParseError("Could not inherit file %s" % (file), fn, lineno)  #★★エラーメッセージを発生させる行★★

Bitbakeはclasses-globalとclassesの両方を探し、どちらにも目当てのクラスがない場合は最後に探したパス名でエラーメッセージを出力します。従ってエラーメッセージのパスは必ずmeta/classesになります。

今回登場したファイル、ディレクトリは、

  • poky/meta/classes-global/base.bbclass
  • poky/meta/classes-global/*.bbclass
  • poky/meta/classes/*.bbclass

こんなとこ。次回はディストリビューションを見ます。

編集者:すずき(2024/06/04 00:43)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年6月10日

PCBを設計して注文、第二弾

目次: Arduino

前回(2024年3月24日の日記参照)発注して燃えた(2024年4月3日の日記参照)PCBの設計を改修して発注しました。前回と同様にJLPCBにお願いしています。

JLPCBはドル決済なので円安だと支払いが増えて結構痛いんですよね……。円安がマシにならないかなーと思って1ヶ月くらい待ったんですが、特に良くなる傾向がなかったので諦めました。

編集者:すずき(2024/06/22 15:48)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年6月11日

ROCK 3Cの描画速度改善

目次: Arduino

エアガン的当てゲームを作り始めたとき(1月くらいかな?)から気になっていたのですが、ROCK 3C上でJavaを使って画面を描画すると妙に描画速度が遅いです。もうひとつ不思議なことに、マウスカーソルをぐりぐり動かすと描画が止まります。なんで?

最初はJava側の問題か?と思ったものの、秋葉原のTARGET-1に置いている機体はJava側のプログラムは全く同じなのに、描画速度がメチャ速いです(マウスカーソルを動かしても画面描画が止まらない)。ROCK 3C側(というかメインSoCであるRockchip RK3566)のグラフィック関連がどこかおかしいんでしょう。たぶん。

描画が遅い機体と速い機体で大きな違いがあるとするとaptでアップデートしたくらいです。描画速度が遅い機体を持ち帰ってきてアップデートしました。結果だけ先に言ってしまうと、描画速度はやや改善したものの全く同じにはなりませんでした。何が違うんだろう?

カーネルとlibmaliのアップデート

描画速度に効いていると思われるのは下記の2つです。

  • カーネルバージョン: 5.10.160-33-rk356x -> 5.10.160-34-rk356x
  • libmali: libmali-bifrost-g31-g2p0-x11-gbm -> libmali-bifrost-g52-g2p0-x11-gbm

アップデート方法はapt-get updateとapt-get upgradeですが、下記のようにchanged its 'Origin' value from 'AAAA' to 'BBBB'というエラーが出る場合があります。

apt-get updateのエラー
Reading package lists... Done
E: Repository 'https://radxa-repo.github.io/bullseye rockchip-bullseye InRelease' changed its 'Origin' value from 'rsdk-local rockchip-bullseye' to 'Radxa'
E: Repository 'https://radxa-repo.github.io/bullseye rockchip-bullseye InRelease' changed its 'Label' value from 'rsdk-local rockchip-bullseye' to 'Freight'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.
E: Repository 'https://radxa-repo.github.io/bullseye bullseye InRelease' changed its 'Origin' value from 'rsdk-local bullseye' to 'Radxa'
E: Repository 'https://radxa-repo.github.io/bullseye bullseye InRelease' changed its 'Label' value from 'rsdk-local bullseye' to 'Freight'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done

これはリポジトリのReleaseファイルが変わっているが良いのか?と確認してくれているためで、今回は無視して良いので--allow-releaseinfo-changeを付けてapt-get updateすれば先に進みます。

最新のRockchip用カーネルに更新
# apt-get update --allow-releaseinfo-change

(...略...)

# apt-get dist-upgrade

Hit:1 https://download.vscodium.com/debs vscodium InRelease
Hit:2 https://deb.debian.org/debian bullseye InRelease
Hit:3 https://deb.debian.org/debian bullseye-backports InRelease
Hit:4 https://deb.debian.org/debian-security bullseye-security InRelease
Hit:5 https://deb.debian.org/debian bullseye-updates InRelease
Hit:6 https://radxa-repo.github.io/bullseye rockchip-bullseye InRelease
Hit:7 https://radxa-repo.github.io/bullseye bullseye InRelease
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following NEW packages will be installed:
  librtui linux-headers-5.10.160-34-rk356x linux-image-5.10.160-34-rk356x
  r8125-dkms radxa-system-config-r8125-dkms
The following packages will be upgraded:
  aic8800-firmware aic8800-sdio-dkms aicrf-test linux-headers-rock-3c
  linux-image-rock-3c radxa-firmware radxa-overlays-dkms
  radxa-system-config-aic8800-sdio-dkms radxa-system-config-bullseye
  radxa-system-config-common radxa-system-config-kernel-cmdline-ttyfiq0
  radxa-system-config-rockchip radxa-udev rsetup rsetup-config-aic8800-ttys1
  task-rock-3c

描画速度はやや改善したものの全く同じにはなりません。描画速度が速い機種と改善後の機種を比べると、

描画が速い機種描画が遅い機種(改善後)
マウスカーソルちらつくちらつかない
マウスカーソルを動かし続ける描画が止まらない描画が止まる
描画速度16ms〜32ms(たまに1フレームスキップ)たまに16ms、ほぼ32ms〜64ms(ほぼ1フレームスキップ)

うーん?何が違うんだろう?

編集者:すずき(2024/06/22 15:42)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年6月17日

GPSDに外部から接続する方法

目次: 自宅サーバー

昔買って放置していた秋月のGPS受信機キット(太陽誘電のGYSFDMAXBを使用しているそうな)を組み立てて、サーバーPCに接続しました。GPSが送ってくるNMEAメッセージはgpsdが一旦受け取りますが、このメッセージをローカルマシン以外から見る方法が地味にわからなかったのでメモしておきます。環境はDebian Bookwarmです。

どうやらgpsdは直接ソケットをlistenしているわけではなく、gpsd -> systemd -> 外部という形になっているようです。まずsystemdの設定を変更します。

systemdのソケット設定変更
# /etc/systemd/system/sockets.target.wants/gpsd.socket

[Socket]
ListenStream=/run/gpsd.sock
#ListenStream=[::1]:2947
#ListenStream=127.0.0.1:2947
# To allow gpsd remote access, start gpsd with the -G option and
# uncomment the next two lines:
ListenStream=[::]:2947
ListenStream=0.0.0.0:2947
SocketMode=0600
BindIPv6Only=no

次にgpsdの設定を変更します。オプションに-G(外部からの接続を受け付けるためのオプション)を追加します。

gpsdの設定変更
# /etc/default/gpsd

# Other options you want to pass to gpsd
GPSD_OPTIONS="-G"

設定を反映します。

設定の反映とソケット設定の確認
# systemctl daemon-reload
# systemctl restart gpsd.socket
# systemctl restart gpsd.service

# netstat -tlp | grep gpsd
tcp        0      0 0.0.0.0:gpsd            0.0.0.0:*               LISTEN      1/init

設定を反映するとsystemd(pid=1, initプロセス)がポートgpsd(= 2947)をlistenしていること、listenアドレスがlocalhostではなく0.0.0.0つまりinaddr_anyになっていることが確認できます。

あとは外部のマシンからxgps (gpsdが動いているマシンのIP):2947などとすれば、gpsdに接続してNMEAメッセージが届いていることを確認できるはずです。

悲しいオチ

NMEAメッセージは送ってきてくれますが、窓際に設置して1時間位放置してもまったくGPS衛星を捕捉しません。壊れてしまったのだろうか……。

編集者:すずき(2024/06/22 16:26)

コメント一覧

  • hdkさん(2024/06/22 22:08)
    GPSの最初の同期を取る時は見晴らしのいい屋外に持ち出してやったほうがいいと思います。以前買ったGPS内蔵のノートパソコンでも、最初だけは外付けアンテナをつないで屋外でやっとという感じでした。スマートフォンは携帯電話の電波や無線LANの情報を元に高速同期するのであれに慣れてしまうと簡単に掴めそうに思ってしまいますが、そういうのがないGPSは窓際なんかでは厳しそうです。
  • すずきさん(2024/06/23 00:12)
    ありがとうございます。バルコニーではない出窓(天井など邪魔なものがなく、空が全面に見える)、ギリギリまで持ってきたらやっと同期が取れました。
    でも電池入れてないので、電源を切ったら同期情報が消えてしまうんですよね。もう出窓の側から動かせないぞ……これ……。
open/close この記事にコメントする



2024年6月21日

GitHubの2FA手法としてSMSが非推奨となった

タイトルのとおりなのですがGitHubアカウントの2FA(二要素認証、2 Factor Authentication)で使える手法として、SMSが非推奨になりました。最近、GitHubではこんな警告が出ます。


GitHubの2FA手法に関する警告

検索用に文字起こししておくと、

GitHubの2FA手法に関する警告、文字起こし
Please configure another 2FA method to reduce your risk of permanent account lockout.
We strongly recommend against SMS as it is prone to fraud and delivery may be unreliable
depending on your region.

(適当訳)
アカウントが永久にロックアウトされる危険性を減らすため、他の2FA手法を設定してください。
SMSは詐欺にあいやすく地域によっては配送が信用できない場合があるので、SMSはお勧めしません。
(strongly recommend against itなので「利用を避けることを推奨する」くらい強い意味かも?)

SMSが非推奨になった理由は詳しく書かれていませんが、携帯電話番号乗っ取り被害(スマホの電話番号を乗っ取られる「SIMスワップ」被害が増加 求められる対策とは? - ITmedia NEWS)を受けてのものでしょう。

SMS以外の2FA手法は下記のものがあります。


GitHubで使用可能な2FA手法の一覧

Authenticator appが最もお手軽でしょう。スマホに過剰に依存するのはあまり好きじゃないですけど。Authenticator appはスマホの紛失や破損で設定が消し飛ぶと2FAできなくなる弱点がありますから、設定のバックアップが取れるアプリを選択すると良いと思います。

例えばGoogle Authenticatorなら[アカウントを移行] - [アカウントのエクスポート]とするとQRコードが表示され、別のスマホに設定を丸ごと移行可能です。アカウントエクスポート用のQRコードがバックアップデータ代わりになりそうですが、時間制限とかあるんですかね??

Security keysはどうかと調べてみると、1つ1万円〜2万円(YubiKey 5 NFC, YubiKey 5 bio)となかなかのお値段でした。これも紛失や破損に備えるなら2つ購入した方が良いでしょうから、GitHubの2FAのために2万円〜4万円払えるか?というとうーん、嫌ですね……。

しばらくはAuthenticator appで運用したいと思います。

編集者:すずき(2024/06/29 13:46)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年6月24日

何もない組み込み環境でDOOMを動かす - その1 - 準備編

目次: RISC-V

DOOMというFPS(First Person Shooter、一人称視点のシューティングゲーム)があります。1993年にid Softwareが開発したロングセラーシリーズです。オリジナルのid Softwareによる実装も2012年にオープンソースになりました(リポジトリへのリンク)。

日本ではそれほどでもない気がしますが、海外ではDOOMの人気は絶大で海外エンジニアの間ではゲーム機ではない電子機器(プリンタ、カメラ、ATMまで)でDOOMを動作させる改造が非常に人気のようです。

DOOM移植の良いところとしては、3D描画のゲームなので画面が派手で目を引きます。それでいて昔のゲームなので、しょぼいスペックの機器でもそこそこ動きます。操作せずに放っておいてもデモが実行される点も素晴らしいです。

今回はオリジナルのDOOMではなくprboom2(リポジトリへのリンク)というクローン実装を使います。prboom2はLinuxで簡単に動作確認できて楽です。いいですね。

IWADファイル

DOOMはゲームエンジンなので実行時にはゲームデータを指定しなければなりません。ゲームデータは*.WADというファイル(Where's All Dataの略らしい)に格納されていて、オリジナルDOOMのWADファイルのことをIWAD(Internal WAD)と呼ぶようです。IWADはDOOMの製品版に付属しているはずです、見たことがないから知らないですけど。本来はオリジナルDOOMを購入しDOOM.WADを持ってくるべきですが、手に入れる手段がなさそうです……。

ネット検索するとIWADを公開しているサイトがあるのでどうにかして手に入れてください。Doom Wiki(リンク)にDOOM.WADのMD5 hashが掲載されているので、入手したIWADファイルがどのバージョンか(あるいは壊れていないか)確認しましょう。

今回はIWADファイルはDOOM.WAD、バージョン1.8のもので試します。

Linuxで動作確認

まずは普通に動かしてみます。ビルドは簡単でbootstrapとconfigureを実行してmakeするだけです。SDLがインストールされていない環境の場合はlibsdl2-devのインストールが必要かもしれません。

prboom2のビルドと動作確認
$ cd prboom2
$ ./bootstrap
$ ./configure
$ make

$ ./src/prboom -iwad DOOM.WAD

DOOM同様prboom2もゲームエンジンなので実行時にはゲームデータを指定しなければなりません。ビルド時に勝手に生成されるprboom.wadというファイルと、ゲームデータが入ったIWADファイル(オリジナルのDOOM、freedoomなど)の2つが必要です。prboom.wadはカレントディレクトリに置けば勝手に見つけます。IWADファイルはオプション-iwadで指定しましょう。


prboom2起動画面(IWAD: DOOM 1.8)

音声なしで起動したければ-nosound、フルスクリーンではなくウインドウモードが良ければ-nofullscreenというオプションが使えます。フルスクリーンとウインドウモードの切り替えはゲーム内のオプションから設定することもできます。

確認だけで終わってしまいました。次回から組み込み環境への移植を始めたいと思います。

編集者:すずき(2024/06/29 22:24)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年6月25日

何もない組み込み環境でDOOMを動かす - その2 - 組み込み環境への移植方針

目次: RISC-V

DOOMのクローン実装prboom2を組み込み環境に移植する話です。前回はLinux上で動作確認しました。今回は想定する組み込み環境と移植作戦&移植です。

組み込み環境への移植作戦

想定する組み込み環境は下記のとおりです。

  • CPU、メモリ
  • I/O: UARTのみ
  • 画面出力: なし
  • ファイル: なし
  • サウンド: なし
  • ジョイスティック入力: なし

改造元にするコードは何でも良いですけど、私は動作するコードから出発した方がやりやすいので、前回Linux上で動作を確認した実装(src/SDL/*)をベースに改造します。移植にあたって障害となりそうなものは、

  • SDL
  • サウンド機能
  • ジョイスティック入力
  • ファイルアクセス機能
  • 画面描画機能

この辺の機能が移植先の組み込み環境に存在しないことです。順番に対処しましょう。

SDL、サウンド機能、ジョイスティック入力への対処

SDL(Simple DirectMedia Layer、公式サイトへのリンクリポジトリへのリンク)はC/C++から簡単にグラフィクスや音声、各種入力機能が利用できる、素敵なライブラリです。が、しかし移植先の環境にSDLなどという高等なものはないのでSDLを使用している箇所は削除します。

メイン(src/SDL/i_main.c)、サウンド(src/SDL/i_sound.c)、画面(src/SDL/i_video.c)とジョイスティック入力(src/SDL/i_joy.c)はSDL.hをインクルードか、SDLの構造体やマクロを使用していてコンパイルエラーになるので、エラーになる箇所を全て削除します。

サウンド(src/SDL/i_sound.c)、とジョイスティック入力(src/SDL/i_joy.c)は動作しなくても問題を起こさないように、常に成功もしくは無意味な値を返すように改造します。

ファイルアクセス機能への対処

ゲームエンジンを動作させるにはprboom2ビルド時に生成されるprboom.wadとIWADファイル(オリジナルのDOOMのWADを指してこのように呼ぶそうです)の2つのファイルが必要です。が、移植先の環境にファイルなどという高尚なものはないので、下記の作戦でファイルアクセスなしでも動作するように改造します。

  • ファイルデータ: 静的配列に置き換え(変換ツールも作る)
  • ファイルデスクリプタ: 独自の構造体に置き換え
  • ファイルオープン: prboom.wadとIWADファイル以外は無視(=常にオープン処理を失敗させる)
  • ファイル読み出し: 静的配列からのコピーに置き換える
  • ファイルシーク: 静的配列のポインタ移動に置き換える

ファイルアクセスを行うコードはシステム(src/SDL/i_system.c)に実装されていますので、ファイルアクセスしている実装を全部静的配列へのアクセスに書き換えます。他の場所(src/d_main.c, src/w_wad.c)のファイルアクセスしている箇所も同様に置き換えます。

ファイルから配列へ変換

ファイルアクセス機能を置き換えたので、ファイル(DOOM.WADとprboom.wad)をC言語の静的配列に変換する方法も作りましょう。

変換方法は色々あると思いますが、昔作った「CmakeでバイナリをC言語の配列に変換する」やつを使います(2023年6月16日の日記参照)。こやつは適当に作った割に意外と便利です。

画面描画への対処

画面描画を削除するとDOOMが動いているかどうかわかりません。移植先の環境に画面を描画するような高尚な機能はないので、UARTとANSIエスケープシーケンスを利用して画面描画の代わりとします。

UARTの出力を受け取る端末には文字を出力する以外にもたくさんの機能があります。端末の各種機能のなかから「背景色の設定+空白の出力」をピクセル描画の代わりとして利用します。端末によって対応する機能は異なり(ECMA-48やANSI X3.64仕様が有名)ますが、今回の実装ではANSI X3.64のカーソル移動、文字色の変更機能を使用します。大抵の端末ソフトが実装しているはずです。たぶん。

端末の文字は縦長(縦:横=2:1くらい、フォント依存です)が多いため、Space 2文字でだいたい正方形になります。つまり背景色変更 + Spece 2文字 = 1ピクセルとすれば画面の描画ができるという寸法です。普通の文字サイズだと1ピクセルが大きくなりすぎるので、端末側のフォントサイズ設定で調整しましょう。

背景色を変更するエスケープシーケンスはこんな感じ。

  • 256-color mode: ESC[48;5;<n>m
  • 24bit color mode: ESC[48;2;<r>;<g>;<b>m

24bit色モードであれば1つのピクセルを表現するために、エスケープシーケンス16バイト+スペース2バイト = 18バイト必要になります。極めて効率が悪いですが、とりあえず動かすために先に進みましょう。

方針が決まったところで画面描画の実装(src/SDL/i_video.c)を改造します。prboom2の画面はフルカラーではなくパレット描画なので、パレット操作をする部分も合わせて改造します。


prboom2が動作している様子(ウインドウはPuTTY、画面サイズ128x120、フォントサイズ5pt)

実際描画してみるとこんな感じです。ウインドウタイトルを見るとわかりますが、SDLによる描画ではなくPuTTYという端末ソフトウェアの画面です。

とりあえず動きました。やったね。画面描画が遅い問題は、次回以降対処していこうと思います。

編集者:すずき(2024/06/29 22:23)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年6月26日

何もない組み込み環境でDOOMを動かす - その3 - 描画の高速化

目次: RISC-V

DOOMのクローン実装prboom2を組み込み環境に移植する話です。前回はUARTしかないショボい組み込み環境でも動作できるようにprboom2を改造しました。

UARTによる画面描画の問題点

Linuxの仮想端末は超速いので描画速度はあまり気になりませんが、組み込み機器に移植すると描画がめちゃくちゃ遅いことに気づくと思います。理由は簡単でUARTが遅いからです。UARTは9600bps〜115.2kbpsがよく使われる速度で、速いものでもせいぜい1.5Mbps程度です。

前回の実装では24bit色モードを使ったので、1つのピクセルを表現するために、エスケープシーケンス16バイト+スペース2バイト = 18バイト必要です。128x120の画面を1枚表示するのに276kB必要、9600bpsだと230秒(0.0043fps)、1.5Mbpsでも1.47秒(0.67fps)です。

256色モードで軽量化

端末の背景色設定は24bit色モードと256色モードがあります。256色モードの場合、エスケープシーケンス10バイト+スペース2バイト = 12バイトなので、24bit色より多少は軽量です。128x120の画面を1枚表示するのに184kB必要です。1.5Mbpsで0.98秒(1.01fps)ですね。


256色モードのパレットと色の番号

24bit色モードはエスケープシーケンスでR, G, Bの各値を指定できるのでどんな色でも指定できました。256色モードの場合はパレットの各色に番号が振られていて、エスケープシーケンスで番号を指定する仕組みです。カラーパレットは上記の配置で固定されていてパレットにない色は使えません。

DOOMの画面の各ピクセルの色を見て、256色モードパレットの色を指す番号を探す減色処理を追加します。256色モードのカラーパレット番号と色の関係は規則的です(※)から、それほど難しくないでしょう。


prboom2(オープニング画面)、256色モード

256色モードだとこんな感じです。24bit色版と比較するとややディティールが潰れていて黒っぽいですけど、まあまあ良さそうです。

(※)16-231番(216色)はR, G, Bそれぞれ6段階の組み合わせです。パレット番号を表す式は、16 + 36r + 6g + b (0 <= r, g, b <= 5) となっています。

横方向RLE

もう少し軽くできないか考えてみましょう。今は毎回「背景色変更のエスケープシーケンス + スペース2つ」を出力していますが、左隣のピクセルと色が同じピクセルであれば、背景色変更をする必要はないです。

つまり左隣と同じ色のピクセルが連続する限りエスケープシーケンスの出力を省略できます。非常に単純なRLE(Run-Length Encoding)の一種とも言えましょう。

グレースケールの活用

デモ開始直後のところがわかりやすいですが、256色モードで描画すると真っ黒になってしまう画面が散見されます。


prboom2、24bit色モード


prboom2、256色モード

DOOMの画面は比較的暗い色が多いですが、256色モードのパレットは暗い色から明るい色まで均等に割り振られているため、暗い色の表現力が低いです。単純に近似すると画面の色がほぼ真っ黒になります。

この問題を回避するために暗い色をグレースケールに置き換えます。グレースケールと暗い赤、緑、青は違う色ですが、暗い色の色味は区別しづらいのでグレースケールに置き換えてもさほど不自然にはなりません。


prboom2、256色モード + グレースケール

こんな感じです。良く見ると壁の暗い緑がグレーになっていたり若干変ですが、総じて悪くない仕上がりです。これで256色モードが活用でき、24bit色モードに比べて描画速度が1.5倍以上になりました。

今まではずっとLinuxの上で作業してきましたが、次回でようやく組み込み機器に移植します。

編集者:すずき(2024/06/29 22:23)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年6月27日

何もない組み込み環境でDOOMを動かす - その4 - 自作OSの組み込み環境へ移植

目次: RISC-V

目次: 独自OS

DOOMのクローン実装prboom2を組み込み環境に移植する話です。前回は画面描画を1.5倍ほど高速化しました。

組み込み環境の選択

今まで「組み込み環境」とひとまとめにして呼んでいましたが、OSだけでもLinux、RTOS、もっとシンプルなものも含めると無数にあります。既存のOSの上で動かすのも大変興味深いですが、今回は自作OS(2022年12月14日の日記参照)の上で動かしてみたいと思います(リポジトリへのリンク)。

今まで下記の機能を削除したり、代替機能で置き換えてきたのはこのためです。動作させるボードやSoCにHW機能がない場合もあれば、自作OSにドライバを実装しておらずHW機能があっても自作OSから使う方法がないのです。

  • SDL: 削除
  • サウンド機能: 削除
  • ジョイスティック入力: 削除
  • ファイルアクセス機能: 削除
  • 画面描画機能: UARTを使った描画で代替

自作OSの特徴は下記のようにLinuxと同じlibcを採用して、Linuxのアプリケーションを移植しやすい仕組みになっていることです。速度の遅い組み込み環境で何度も動作確認するのは大変ですから、なるべくLinux上で検証できるようにした構成です。


自作OSの構造

今回のprboom2の移植の際もC言語のコードを弄る必要はありませんでした。ビルドシステムというかMakefileを別途作っていますが、なんでだったか忘れました……。

自作OSで動かす

自作OSのランタイム側のビルドのための準備については、ドキュメント(リンク)を見ていただくとして。QEMU RISC-V 32bit向けに自作OSをビルドします。

自作OSのビルド
$ cd baremetal_crt
$ cmake ./ -G Ninja -B build \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  -DCMAKE_INSTALL_PREFIX=./test/sysroot/ \
  -DARCH=riscv \
  -DCROSS_COMPILE=riscv64-unknown-elf- \
  -DCC=gcc \
  -DDEFCONF=riscv_qemu_virt_32_xip
$ ninja -C build install

次に改造prboom2をビルドします。前回まで説明してきた改造を全て適用したprboom2をGitHubに置いた(リンク)ので、このコードを使うと簡単です。実装が適当かつ書きかけのコードとかが残っていて美しくありませんが、細かいことは気にしないでください……。

prboom2 on 自作OSのビルド
$ cd prboom2
$ ./configure --disable-gl

$ cd src/riscv
$ make USE_NEWLIB=y USE_SYSROOT=(baremetal_crtのパス)/test/sysroot all

最初のconfigureはconfig.hを作成するために実行しています。特にconfig.hを変更する予定はないので固定で置いてしまえば良かったんじゃないか?と思いましたけど、まあいいでしょう。

prboom2 on 自作OSの動作確認
$ qemu-system-riscv32 \
  -machine virt \
  -bios none \
  -net none \
  -nographic \
  -chardev stdio,id=con,mux=on \
  -serial chardev:con \
  -mon chardev=con,mode=readline \
  -smp 4 \
  -s -kernel prboom2/src/riscv/prboom

こんな感じで動作確認できます。


prboom2(オープニング画面)on 自作OS

描画速度を稼ぐため解像度を半分にしている以外、見た目が前回まで(つまりLinuxで動作させたとき)と同じなのであまり面白くないですね……。

編集者:すずき(2024/06/30 15:39)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2024年5月31日 >>> 2024年6月30日
link もっと後

管理用メニュー

link 記事を新規作成

<2024>
<<<05>>>
---1234
567891011
12131415161718
19202122232425
262728293031-

最近のコメント5件

  • link 24年6月17日
    すずきさん (06/23 00:12)
    「ありがとうございます。バルコニーではない...」
  • link 24年6月17日
    hdkさん (06/22 22:08)
    「GPSの最初の同期を取る時は見晴らしのい...」
  • link 24年5月16日
    すずきさん (05/21 11:41)
    「あー、確かにdpkg-reconfigu...」
  • link 24年5月16日
    hdkさん (05/21 08:55)
    「システム全体のlocale設定はDebi...」
  • link 24年5月17日
    すずきさん (05/20 13:16)
    「そうですねえ、普通はStandardなの...」

最近の記事3件

  • link 24年6月27日
    すずき (06/30 15:39)
    「[何もない組み込み環境でDOOMを動かす - その4 - 自作OSの組み込み環境へ移植] 目次: RISC-V目次: 独自OS...」
  • link 22年12月13日
    すずき (06/30 15:38)
    「[独自OS - まとめリンク] 目次: 独自OS一覧が欲しくなったので作りました。自作OSの紹介その1 - 概要自作OSの紹介...」
  • link 21年6月18日
    すずき (06/29 22:28)
    「[RISC-V - まとめリンク] 目次: RISC-VSiFive社ボードの話、CoreMarkの話のまとめ。RISC-V ...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 06/30 15:39