SVX日記
2004-06-21(Mon) ドリルドリルドリル
2005-06-21(Tue) PICのTimer0を理解する
今日は、残業でキーボードをバコバコと叩きまくっていて帰りが遅くなってしまった……のだが、別に家に帰ったトコロでキーボードをバコバコと叩きまくっているオイラなのであった。もし手元からPCが無くなったりしたら、窒息死するに違いない。これは、保障つきで間違いない。
で、おもむろに昨日のタイマ割り込みの間隔が短すぎる問題の解消を図りだすのである。実はオイラ、タイマ割り込みを利用するのは初めてではないのだが、やっぱりちゃんと勉強しなおしておいた方がよいだろうというコトで、PICのデータシートの一部を翻訳してみるコトにした。ちゅーワケで、PIC12F629/675のデータシート、4章Timer0モジュールの訳をどうぞ。
あ、そうそう、例によって各文末の句点などにマウスの乗せると原文がポップアップするようにしてある。このヘッポコ訳ッ!! と思ったら、原文を確認すれッ!!
4.0 TIMER0モジュール_
Timer0タイマ/カウンタモジュールには、以下の特徴があります:
・8ビットのタイマ/カウンタ_
・読み書き可能_
・ソフトウェアで選択可能な8ビットのプリスケーラ(分周器)_
・内部/外部クロックを選択可能_
・オーバフロー(FFh→00h)発生時に割り込みを発生可能_
・外部クロックのエッジ(立ち上がり/立ち下がり)を選択可能_
図4-1はTimer0モジュールとプリスケーラ(WDTと共用)の模式図です。
4.1 Timer0の操作方法_
タイマモードは、T0CSビット(OPTION_REG<5>)のクリアにより選択されます。このモードでは、インストラクションサイクル毎(1命令実行毎)にTimer0がカウントアップされます(プリスケーラ非使用の場合)。TMR0に書き込みがなされた場合、続く2インストラクションサイクルの間、TMR0はカウントアップされません。ユーザはこれを考慮の上、TMR0レジスタに値をセットすることで、意図する動きを実現可能です。
カウンタモードは、T0CSビット(OPTION_REG<5>)のセットにより選択されます。このモードでは、ピンGP2/T0CKIの変化のエッジ(立ち上がり/立ち下がり)でTimer0がカウントアップされます。カウントアップするエッジの方向は、ソースエッジ(T0SE)の選択ビット(OPTION_REG<4>)で指定可能で、T0SEビットがクリアに設定してあれば、立ち上がりでカウントアップされます。
4.2 Timer0割り込み_
TMR0タイマ/カウンタレジスタがオーバフロー(FFh→00h)すると、Timer0割り込みが発生します。このオーバフローによりT0IFビットがセットされます。T0IEビット(INTCON<5>)をクリアすることで、この割り込みを禁止することもできます。次の割り込みを有効にするためには、Timer0割り込みルーチンの中でT0IFビット(INTCON<2>)をソフトウェア的にクリアする必要があります。タイマがSLEEP中にカウントアップすることはないので、Timer0の割り込みにより、CPUをSLEEPから復帰させることはできません。
4.3 Timer0を外部クロックで使用する_
プリスケーラを利用しない場合、外部クロック入力はプリスケーラの出力と同じになります。内部クロックとT0CKIの同期は、内部クロックのQ2とQ4サイクルにプリスケーラ出力をサンプリングすることによって、実行されます。よって、T0CKIをHIGHと認識するには最低2TOSC(+20nsのRC遅れ)、LOWと認識するには最低2TOSC(+20nsのRC遅れ)が必要です。外部装置の電気的特性を確認してください。
注意:入出力ピンをデジタル入力モードに設定したい場合、ANSEL(9Fh)およびCMCON(19h)レジスタを初期化する必要があります。アナログ入力モードに設定されていると、常に'0'が返ります。なお、ANSELレジスタはPIC12F675用です。
4.4 プリスケーラ(分周器)_
この8ビットのカウンタは、Timer0モジュールのためのプリスケーラとして、またはウォッチドッグタイマのためのポストスケーラとして利用可能です(……が、以下このカウンタを一概にプリスケーラと呼ぶことにします)。プリスケーラの設定はソフトウェア的にコントロールビットPSA(OPTION_REG<3>)で行えます。PSAビットをクリアに設定すると、プリスケーラはTimer0に割り当てられるます。プリスケーラ値はPS2:PS0ビット(OPTION_REG<2:0>)により設定可能です。
プリスケーラは読み書き不可能です。プリスケーラがTimer0に割り当てられている場合、TMR0レジスタへの書き込み命令(CLRF 1、MOVWF 1、BSF 1などなど)実行の都度、プリスケーラはクリアされます。プリスケーラがWDTに割り当てられている場合、CLRWDT命令実行の際、ウォッチドッグタイマのクリアと同時にプリスケーラもクリアされます。
4.4.1 プリスケーラの設定切り替え_
プリスケーラの設定はすべてソフトウェア的に行います(つまり、プログラム実行中にホイッと変えられます)。Timer0からWDTへプリスケーラの割り当てを変える場合、以下の命令順序(例 4-1)で実行すれば、意図しないデバイスリセットを避けられます。
逆に、WDTからTimer0へプリスケーラの割り当てを変える場合、以下の命令順序(例 4-2)を使用します。例えWDTが無効にしてあっても、この方法を利用すべきです。
でだ、訳すウチに気づいてしまったのだ。それは「次の割り込みを有効にするためには、Timer0割り込みルーチンの中でT0IFビット(INTCON<2>)をソフトウェア的にクリアする必要があります」というトコロ。今回、気づかないうちに、そのコードをコメントアウトしていたんだよね。
通常、割り込みルーチンには、割り込み処理をそのまま記述するのでなく、起こった割り込みの種類をイベントフラグに記録する処理だけを記述する。そんでもって、割り込み処理自体はメインルーチンの中で行うようにするのが常套手段である。なぜなら、割り込み処理中に再び割り込みイベントが発生すると、二重に割り込みが発生することはないので、後者のイベントを取りこぼしてしまうからである。そーゆーコトではどーしよーもないので、極力取りこぼしたくないならば、極力割り込み処理自体を短時間で完了する必要があるのだ。ところが今回、割り込み処理のテストとして行ったLEDの点滅処理は非常に軽いので、割り込みルーチンの中に直接書いてしまったのが災いした。LEDの点滅処理を追加する際に、元から記述してあったT0IFビットをクリアする処理をコメントアウトしてしまったのである。これが昨日の失敗の理由だ。理解したので、サクッと修正する。
2009-06-21(Sun) 「JS-1V」内蔵ゲーム、壊れる
ゴミ箱に捨ててあった、バキッとやった「Namco TV Classics - Ms. Pac Man」のガワがイッペイに見つかって「壊しちゃダメじゃん、直してぇー」と詰め寄られてしまったのだ。「いや、これは壊したんじゃなくて、直したんだよ」とかなんとか、言い訳しつつ、中身はこっちに入れ替えたんだよ、遊んでみる? ……と、そこまではよかった。
車好きのイッペイなので、ポールポジションをやらせてみた。レバーをヒネってハンドルを切ることを教えると、意外なほど上手に運転する。んが、一度、コース脇の看板にぶつかって車が爆発すると、それが楽しくなってしまったらしく、コース脇ばかり走るようになってしまった……と、そこまでもよかった。
悲劇はその後。イッペイが調子よくコースを爆走するが、その空が曇り始めた……モノクロ化? と、思うまもなく、ちょっと化けパターンが表示されたかと思ったら、そのままブラックアウト。ウンともスンともいわなくなってしまった。
「電池なくなっちゃったの?」と、イッペイに妙に的確な診断を下され、電池を交換してみたが、直らない。「ちょっと壊れちゃったみたい。また直すよ」などとツクロいつつ、マジでヤバそうな予感も……電源をアダプタに切り替えても無応答だし……ようやく復活させたのに、ロクに遊ぶ間もないままサヨナラか? ……それは悲しすぎる。
ついでに、回転検出部を配置するための基板をレイアウトしてみる。小さく基板をカットして、基板にタッピングツールでネジ穴を掘る。必ずしもネジ穴を掘る必要はないのだが、ナットを締めるにはちょっと場所が狭いもんで。
2010-06-21(Mon) 参上ッ!! Mailmanッ!!
ふと「Webブラウザから過去のメールを閲覧したい」という要求が生じた。実現の方法は、いろいろと考えられるだろうが、メーリングリストのアーカイブ機能を流用してしまうのがラクではないかと考え、Mailmanによる実現を試みることにした。
ま、それはさておき、MTAをSendmailからPostfixに変更するところから、ボチボチと始めていくのである。なお「MTAをSentmailからPostfixに変更する理由」については、決して聞くことのないようにお願いしたい所存である。
# yum install postfix
# cd /etc/postfix
# vi main.cf
# diff -bc main.cf.org main.cf
*** main.cf.org 2010-06-21 13:12:32.000000000 +0900
--- main.cf 2010-06-21 13:13:43.000000000 +0900
***************
*** 68,73 ****
--- 68,74 ----
#
#myhostname = host.domain.tld
#myhostname = virtual.domain.tld
+ myhostname = zakato.itline.jp
# The mydomain parameter specifies the local internet domain name.
# The default is to use $myhostname minus the first component.
***************
*** 75,80 ****
--- 76,82 ----
# parameters.
#
#mydomain = domain.tld
+ mydomain = itline.jp
# SENDING MAIL
#
***************
*** 104,113 ****
#
# Note: you need to stop/start Postfix when this parameter changes.
#
! #inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
! inet_interfaces = localhost
# The proxy_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on by way of a
--- 106,115 ----
#
# Note: you need to stop/start Postfix when this parameter changes.
#
! inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
! #inet_interfaces = localhost
# The proxy_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on by way of a
以上、Postfixの基本設定の完了である。Sendmailを消してもいいが、以下のようにすれば消さずに切り替えることも可能である。Sendmailを落としてPostfixを上げる。自動起動についても確認しておく。
# update-alternatives --config mta
2 プログラムがあり 'mta' を提供します。
選択 コマンド
-----------------------------------------------
*+ 1 /usr/sbin/sendmail.sendmail
2 /usr/sbin/sendmail.postfix
Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
# service sendmail stop
# service postfix start
# chkconfig sendmail off
# chkconfig postfix on
# telnet zakato.itline.jp 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 zakato.itline.jp ESMTP Postfix
helo hoge
250 zakato.itline.jp
mail from: root@zakato.itline.jp
250 2.1.0 Ok
rcpt to: user1@zakato.itline.jp
250 2.1.5 Ok
data
354 End data with .
test1
.
250 2.0.0 Ok: queued as 70DA014DB99
quit
221 2.0.0 Bye
Connection closed by foreign host.
# tail /var/log/maillog
# tail /var/spool/mail/user1
# yum install mailman
さて、これから設定の手順に入る……んが、このページにアクセスされている状態でこんなこというのもナンではあるが、ヘンな野良サイトを見るマネする前に、オフィシャルなドキュメントや、manページを見るべきである。
というのも、通常「RPMパッケージ化されている物件」は、インストールするだけで動く、というのが基本であり、そうでない場合は、ディストリビューション(Red Hat)として「こう使うべき」というドキュメントが用意されているのが世の常なのである。
オープンソース物件は、コミュニティ提供の物件と、ディストリビュータ提供の物件とで性格が違う。ディストリビュータ提供の物件を利用する場合、極力、ディストリビュータの意向を汲んで動かすべきである。勝手にやるなら、ディストリビュータ提供の物件を利用する価値がない。
# rpm -ql mailman | grep -i redhat
/usr/share/doc/mailman-2.1.9/INSTALL.REDHAT
# /usr/share/doc/mailman-2.1.9/INSTALL.REDHAT
ほれ、あった。基本的にはこれを読みつつ設定を進めるのがよろしい。まずは、WebからMLを管理するための、Mailmanの設定ファイルを読み込ませるため、インストール直後にapacheを再起動すれ、とあるので、素直に従う。
# service httpd restart
# LANG=C /usr/lib64/mailman/bin/mmsitepass
New site password: mmpassword
Again to confirm password: mmpassword
Password changed.
# cd /usr/lib/mailman/Mailman
# cp mm_cfg.py mm_cfg.py.org
# vi mm_cfg.py
# diff -bc mm_cfg.py.org mm_cfg.py
*** mm_cfg.py.org 2010-06-21 14:23:09.000000000 +0900
--- mm_cfg.py 2010-06-21 14:26:25.000000000 +0900
***************
*** 78,85 ****
except:
fqdn = 'mm_cfg_has_unknown_host_domains'
! DEFAULT_URL_HOST = fqdn
! DEFAULT_EMAIL_HOST = fqdn
# Because we've overriden the virtual hosts above add_virtualhost
# MUST be called after they have been defined.
--- 78,85 ----
except:
fqdn = 'mm_cfg_has_unknown_host_domains'
! DEFAULT_URL_HOST = 'zakato.itline.jp'
! DEFAULT_EMAIL_HOST = 'zakato.itline.jp'
# Because we've overriden the virtual hosts above add_virtualhost
# MUST be called after they have been defined.
***************
*** 91,95 ****
--- 91,98 ----
# Put YOUR site-specific configuration below, in mm_cfg.py . #
# See Defaults.py for explanations of the values. #
+ DEFAULT_SERVER_LANGUAGE = 'ja'
+ MTA = 'Postfix'
+
# Note - if you're looking for something that is imported from mm_cfg, but you
# didn't find it above, it's probably in Defaults.py.
# LANG=C /usr/lib/mailman/bin/newlist mailman
Enter the email of the person running the list: user1@zakato.itline.jp
Initial mailman password: mmpassword
Hit enter to notify mailman owner...<Return>
# service mailman start
# tail /var/spool/mail/user1
# cd /etc/mailman
# chown mailman:mailman aliases*
# chmod 660 aliases.db
ここは、ディストリビューションとしてどうにかして欲しかったところである。上述の手順書にもロクな記載がない。どうも、Webから管理するための権限と、Mailmanとして動くための権限が衝突しているような感じだが、正直、よくわからん。
このヘンの権限の設定を誤っていると、メーリングリスト作成時、Webブラウザ上に「We're sorry, we hit a bug!」と表示され、内部のログに「/usr/sbin/postalias /etc/mailman/aliases」が失敗した、などと出たり、はたまた、メール投稿後に「Undelivered Mail Returned to Sender」としてメールが戻ってきて、その中に「Group mismatch error.」なんてエラーが記されている、などという状態に陥ったりするのようである。
チマタでは、これを解決するために、Mailmanをリコンパイルしろ、などというアドバイスが飛び出したりしているが、リコンパイルなんかしたら、なんのためのディストリビューションによるバイナリ物件の提供なのか、という話になる。
# cd /etc/postfix
# vi main.cf
# diff -bc main.cf.org main.cf
*** main.cf.org 2010-06-21 13:12:32.000000000 +0900
--- main.cf 2010-06-21 15:01:19.000000000 +0900
***************
*** 374,380 ****
# "postfix reload" to eliminate the delay.
#
#alias_maps = dbm:/etc/aliases
! alias_maps = hash:/etc/aliases
#alias_maps = hash:/etc/aliases, nis:mail.aliases
#alias_maps = netinfo:/aliases
--- 376,382 ----
# "postfix reload" to eliminate the delay.
#
#alias_maps = dbm:/etc/aliases
! alias_maps = hash:/etc/aliases, hash:/etc/mailman/aliases
#alias_maps = hash:/etc/aliases, nis:mail.aliases
#alias_maps = netinfo:/aliases
***************
*** 665,667 ****
--- 667,671 ----
# readme_directory: The location of the Postfix README files.
#
readme_directory = /usr/share/doc/postfix-2.3.3/README_FILES
+
+ owner_request_special = no
# service postfix restart
新しいメーリング リストを作成する
リストの名前: arctest1
リスト管理者アドレスの初期設定: user1@zakato.itline.jp
初期パスワードを自動生成しますか? ●はい
リスト作成者の認証パスワード: mmpassword
[リストを作成する]
リストの管理ページへ行く
リスト管理者パスワード: [mmpassword]
[ログイン]
全体的オプション
件名の先頭に付ける語句 [<空白>]
投稿メール本文の最大サイズ(KB). 0 を設定すると無制限. [0]
[変更を送信する]
プライバシーオプション
送信者フィルタ
動作が定義されていない非会員からの投稿に対する動作. ●承認
[変更を送信する]
宛先フィルタ
投稿にはリスト名が宛先(to, cc) に含まれてい なければならないでしょうか? ●いいえ
投稿を認めるメールに含まれる受信者数の上限. [0]
[変更を送信する]
# telnet zakato.itline.jp 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 zakato.itline.jp ESMTP Postfix
helo hoge
250 zakato.itline.jp
mail from: root@zakato.itline.jp
250 2.1.0 Ok
rcpt to: arctest1@zakato.itline.jp
250 2.1.5 Ok
data
354 End data with .
test2
.
250 2.0.0 Ok: queued as 332CD14DBB6
quit
221 2.0.0 Bye
Connection closed by foreign host.
「リスト総合案内のページ」を経由して「arc1test 保存書庫」へ移動する。投稿したメールが確認できれば、一応の目的の達成である。あとは、メールのインポートスクリプト等を利用して、既存のアーカイブ対象メールをメーリングリストに流し込むだけである……。
なにがどうおかしいのかわからんが、サブジェクトが文字化けしてしまう。おまけに、スレッドの認識もいまひとつような気がする。そもそも、メールのDateを見ずに、投入日時でアーカイブするのが、どーにもこーにも気に食わん……。Malimanでアーカイブされているメーリングリストは多く、あまりトラブっている様子を見たことがないので、前者ふたつは工夫の余地があるのだろうが、最後のひとつはいかんともしがたい。
Pythonが読めればどうにかなるかもしれんが、そこで思いついてしまった。我がメーラMaveのライブラリを使えば、メールのアーカイバなんぞ、ちょいちょいと書けてしまうのではないか、ということに。実装ができれば、Maveの新たな機能としてウリを追加することもできる。
2022-06-21(Tue) オレの横シュー「スケルティウス」一応の完成
自分の興味はプログラミング、特にコードにあるので、とりあえずは「横シュー」というシステムを限りなく美しく記述することが一番の目的になる。だから、長らく構想していた横シューのタイトルは「グラッス」だった。グラディウスっぽく始まって何機か敵機が飛んできたと思ったら、閉じつつあるシャッターが現れて、そこを抜けると、中にデカい脳ミソがある、みたいな、最初と最後しかない「グラディウス」。だから「グラッス」。当然ながら、不本意な言語では書きたくない。その意味で、Coffee Scriptは悪くない。ブラウザで動くから、誰にでも気軽に遊んでもらえるし。
しかし、コードを書いてみると、いろいろと気付かされるものだ。それは、コードに関してよりも、それ以外の部分の重要性。グラフィックは割と適当に描いてもそれっぽく見えたり、そうでもなかったり、適当に描くだけでも結構な労力だったり。プレイヤを殺しにかかろうとステージを設定することなんか、簡単なんだなと思ったり。R-TYPEの1面なんかは異常なほどユルく作ってあったんだな、とか。
自分で言うものなんだが、今回書いたコードは、1980年台のオーソドックスなシューティングを実現するためのパーフェクトな骨組みである。だから名前も「SKELTIUS」だ。パターンチップを並べてスクロールする地形を表現するBG(バックグラウンド)や、重ね合わせ表示可能なオブジェクト(スプライト)、64方向への直線移動や、当たり判定も汎用的に扱えるようになっている。後は、敵機やボスの行動ロジックを書いたり、ステージの仕掛けを作ったり、グラフィックを描いたりすれば、あっという間にオリジナル横シューができあがる(あー、サウンド関係だけはまだだけど……)。
というわけで、誰かに面白い横シューを作ってもらいたいと思いつつ、自分でも作ってみたいとも思っている。まずは、先日のテトランを実装しなおしてみたいな。それと、なんかこう、宇宙戦艦のブリッジで艦長に頬を張られたところで…<以下略>。
2024-06-21(Fri) ロードスターのルームミラーを交換
そう気になるほどでもないがロードスターのルームミラーの縁が汚れてきた。表面じゃない。鏡の錆か? 6年半経つものの、ちょっとショボくないか? とは思うが、同じ症状の方を発見。
車のパーツだから高いんだろうな、と思って調べたら意外。税込み2629円。安ッ!! これが自動防眩ルームミラーだと3万もするらしい。うわーNR-Aでよかったぁ……って、アレ? そもそも自動防眩ルームミラーだったら錆びてないかもしれんわな。
別にまだ交換するほどでもないが、ちょうどモノタロウのクーポンがあったのでポチる。そう。自分は逆張り野郎なので、何の工夫もなくまったく同じ純正のミラーと交換するのであった。つまらんパーツレビューやねぇw。パーツナンバはKD53-69-220B。ちな、交換にはトルクスの20番が必要になる。ナゼにトルクス? 自分は手元にあったけど。あ、イジり止め対応のトルクスである必要はない。