困ったときはログファイル

Cubieboard2 (Arm7 Cortex Dual core 1GHz, 1GByte Ram, 4GByte Flash, OS=armhf debian 7) という、約60ドルで中国から購入したデベロッパーボードを使って運営しているホームサーバーの管理にISPConfig3という管理ソフトを導入して使用している。 Mailサーバー、Webサーバー、DNSそしてnginxプロキシなどをWEBブラウザから一括管理できるので重宝している。
このツール、HowtoForgeというサイトでサポートされていて、”Perfect Server” というシリーズで多様な組み合わせのサーバー設定のチュートリアルが掲載されている。 たとえばこの記事はOSはDebian,サーバープロキシにnginx, mailにはDoveCot、DNSにはBindを使ったサーバー構築の手順が述べられており、実は自分のサーバーはこれを参考にして立ち上げた。(DNSとNGINX、PHP、MySQLの部分はともかく、メールサーバーとメールフィルターの設定は自分ひとりの能力では手も足も出なかった。きちんと設定できたのは上の記事のおかげである)
 最近バージョンのアップデートをしようと思い立ち、コントロールパネルに指示されているiSPsonfig-update.shというコマンドを実行してみた。  アップデート自体はまったく問題なく行えたのだが、 コントロールパネルにログインしようとしてみたところいつもログイン画面が出るはずのurlが空っぽのページになっている。 
他のサービス(メール、Webサイト、DNS、SSHなど)は普通に動いているので、IPSConfigのダッシュボードへのログインが表示できないという限定された不具合だ。 幸いなことにISPConfigのUpdateツールがまず実行するのは旧バージョンのバックアップなので最悪の場合はリストアを行えばよいが、ページのヘッダー情報を見てみると、エラー番号が500、Internal Server Errorとなっているので、これはPHPの実行時、ページレンダリングの途中でおかしくなっている、とあたりをつけた。 NginxのErrorLogを眺めてみると大当たり、Fatal Errorが記録されていた。

11:54:25 [error] 3452#0: *528 FastCGI sent in stderr: "PHP message: PHP Warning:  require_once(/usr/local/ispconfig/interface/lib/config.inc.php): failed to open stream: Permission denied in /usr/local/ispconfig/interface/web/index.php on line 31
PHP message: PHP Fatal error:  require_once(): Failed opening required '../lib/config.inc.php' (include_path='.:/usr/share/php:/usr/share/pear') in /usr/local/ispconfig/interface/web/index.php on line 31" while reading response header from upstream,云々

上のエラーメッセージはindex.phpの31行目config.inc.phpを読み込もうとしたところ、拒否されました。と言っている。 ../libr/config.inc.phpのアクセスレベルがきつすぎるようだ、。
そこでこのファイルを調べてみるとOwner,GroupともISPCONFIGとなっているのは良いとして、Ownerのみに読み書き権限があたえられており、Groupレベルで読み書き禁止となっている。  それではと、Groupレベルでの読み出しも許可に書き換えてみたところ、あっさりと復活した。

#  chmod g+r config.inc.php

これが普通とは思わない。何らかの理由でサーバーのワーカープロセスとファイルのオーナー情報が背反しているためにファイルアクセスできなくなっていると考える。 少し思い当たることがあって、同じサーバー内部でModxを使ったサイトを運営しているのだが、アップデートするたびにSetupフォルダーをマニュアルで削除しなくてはならない、という作業が発生している。 Setupフォルダーの削除はインストール画面でチェックをいれてやれば自動的に行ってくれるはずなのだが、このサーバーではそれができてない。

というわけで、本日わかったこと。
1. Linuxのアクセスレベル管理がいまいち理解できてないなあ。
2. Linux 不具合解析はまずError Logを読む事。

Python でテクストファイルを読み書きする。

With と For iterater を使うとファイルを明示的にクローズしないでもよいそうだ。
例題でやっているのはTest.txtというファイルから一行ずつ読み込んでリストを作成し、それをリストオブジェクトのSortedメソドで並び替えをしたのち、test2.txtというファイルに書き戻す、という作業。 なんか簡単にできるし(簡単だけど)、コメントを入れなくても読み解きやすい感じ。このあたりがPythonの強みか。

a_list=[]
with open("test.txt", mode="r",encoding='utf-8') as a_file:
     for a_line in a_file:
         a_list.append(a_line.rstrip())

a_list = sorted(a_list)

with open("test2.txt", mode="w", encoding='utf-8') as a_file:
    for a_line in a_list:
        a_file.write(a_line+'\n')

PIC マイコンライターを入手したので….

30年ほど遅れたがPICマイコンのことを調べてみようと思った。

入門用に使ってみようと思うPICマイコン、資料を見ると16F84というのが盛んに議論されているが、Microchipのホームページをみてもこのマイコンはリストアップされていない。型番が古いためのようで、Gooligum Electronicsのサイトによれば、最近のPICマイコンのラインアップでさらに性能が向上し、かつ安価で入手性が良いのは以下のようなものになるらしい。

性能によって 4つのファミリーに分けられる。
BaseLine :12ビット命令系 割り込みがないなど制限があるが単純で使いやすいとのこと。 10F200(6端子)12F509(8端子)、16F506(14端子) など
Mid-Range: 14ビット命令系 BaseLineの拡張版で割り込み制御、メモリーの増設PWM、モーターコントロール、I2C,SPI I/F やLCDコントロールなどの周辺回路の追加、、 12F629(8端子) 16F690(20端子) 16F887(40端子)など. このシリーズが16F84の系統らしい。
Enhanced Mid-range:14ビット命令系 Mid-rangeの拡張版でさらなるメモリーの追加、命令群の増設、Cコンパイラ用に最適化したメモリーアクセス手順、改善された実行速度など 12F1501(8端子)、 16F8124(14端子)、16F1946(64端子)など
High End : 16ビット命令系 いわゆる18Fシリーズ 周辺回路にUSB,Ethernet、CANとの接続性が追加され、メモリーもプログラムは128Kまで、データも4Kまで対応 18F1220(18端子)、18F2455(28端子)、18F8520(80端子) など
ややこしいのは、これらのマイコン、インストラクションは12~16ビットの幅があるが扱うデータが8ビットなのですべて8ビットマイコンだということ。

Mouser.comで値段をみると 12F509-I/P $0.85、12F629-I/P $1.10 、12F1501-I/P $0.92 (すべて8端子)ということで、 BaselineとEnhanced Mid-rangeとでは値段に差がない。 それならよりパワフルらしい12F1501をベースに勉強してみようかと思ったのだが、 データシートの最初の数ページを読んで挫折した、というか 勉強するのをやめた。
何故か。
PICマイコンはプログラム領域とデータ領域が別に取ってある。 プログラム領域は連続しているのだが、データ領域は128本の8ビットデータレジスタ(ファイルレジスタ)を一つのバンクとして、最大32のバンクを切り替えて使うようになっているらしい。 ただし同じデータをどのバンクでもアクセスできるようにいくつかのレジスタは同一レジスタへのアクセスなのだ。(たとえばバンク切り替え指定のレジスタなど) AVRに比べると煩雑な感じである。 それなりの理由があってこうなっているのだろうが、 これはもういけません。 自分の頭脳がこの先を読むのを拒否しております。

というわけでPICマイコンの勉強はしばらくおあずけ。

Arduino でAVR マイコンのプログラム

前回、手持ちのArduino MicroでAVRマイコンのライターを作成したので、それを使ってAVRマイコンをプログラムしてみる。

用意したのはAtmega168Aという28ピンのチップ。 買った状態では内部発振の1Mhzで動くようになっている。内部発振では1Mhzと8Mhzを選択できる。ちなみにArduino Unoは同系列の328P

まずは手始めにArduinoのIDEを使ってArduinoのスケッチを書き、コンパイルさせてAVRチップにアップロードしてみる。手順さえ間違わなければ これでちゃんと動作してしまうんである。

168AVRのチップのピン配列(PortB,PortC,PortD etc.,) と Arduino式の(D0~D13,A0~A5) ピン配列の関係についてはここにマッピング情報がある。 LEDのBlinkスケッチを使う場合、LEDを接続するD13に該当する出力ピンはPB5である、ということがわかる。

蛇足ながら、PB6とPB7はArduinoボードではクリスタルに接続されているために入出力ピンとしては使えないが168を内部発振で使う場合には使用可能、ただしDigitalPinの定義がないので、Cに落とした記述が必要。

IDEのメニューからTarget Board を選ばなければならいないが、当然のことながらAtmega168などという選択肢はない。ので、Arduino Pro Mini(with 8Mhz Atmega168)というのを代わりに選ぶ。

ただし、AtMega168は工場出荷時の内部クロックは1Mhzに既定値設定されている(内部発振8Mhzを8分割) 上記のBoard 選択では8Mhz 用にコンパイラがタイミングループを調整するので1秒の点滅を指定すると8秒の点滅になる。 これが嫌ならAVRDUDEを使ってAtmegaのFuseを書き換え内部クロックを8Mhzに設定するか、または Arduino/hardware/arduino/boards.txt にならって1Mhz のAtmega168をバリエーションとして追加してあげる必要がある。
8Mhzに設定するにはAVRDUDEを使ってフューズ設定を書き換えることになる。

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avrdude.exe-c arduino -p atmega168 -P com5 -U lfuse:w:0xe2:m

Boards.txtへのアイテムの追加はこの記事が参考になる。

Arduino IDEではShiftキーを押しながらアップロードボタンをクリックするとUSBに接続されているライターを使ってターゲットBoard(Arduinoまたはマイコンチップ)にコードをアップロードしてくれる仕組みになっているが、このためにはToolメニューの中からプログラマを指定する必要がある。Arduino Unoをライターとして使う場合は”Arduino as ISP” という項目を選べばよいのだが、自分が使っているArduino Micro はこれでは動作してくれない。(Leonardでも同様) この設定はArduino/hardware/arduino/programmers.txtというファイルにあるが、Unoに指定の

Arduinoisp.protocol=stk500v1

ではうまくリセットがかからないようだ。以下のようにこのprogrammers.txt にMicro/leonard 専用の選択肢を追加してIDEを再起動し解決

arduinoisp.name=Arduino Micro or Leo as ISP
arduinoisp.communication=serial
arduinoisp.protocol=arduino
arduinoisp.speed=19200

これで、Atmega168のPB5にLEDを接続し、BlinkスケッチをダウンロードするとLEDが点滅を始める。

Arduinoを使うと豊富なライブラリーが使えるという利点があり、ATtinyをArduino IDEでプログラムしようというプロジェクトもあって資料も豊富だ。

欠点としては

1.ターゲット用にBoards.txt項目を追加する必要がある。 ただし、一度の作業。

2.Arduino IDEの使い心地。 これは個人的な嗜好の問題だがAVR用にC/C++をコーディングするのならArduino IDEよりも強力な無料のIDE (Eclipse with AVR  plugin [Linux, Windows],   AtmelStudio [Windows])が存在する。