東芝から発売されているFlashAirを用いた開発を行う人々向けのまとめwikiです。※本wikiは東芝及びフィックスターズ、キオクシアとは何の関係もありません。お問合わせは管理者へお願いします。

現在わかっている仕様orバグ

FlashAirに見つけたバグっぽい挙動を記入
古いファームウェアにある不具合は、アップデートで解消しますので、アップデートをしてください。
http://www.toshiba-personalstorage.net/support/dow...

ファームウェアバージョンW3.00.01

fa.spiのCSが動作不良?

秋月DIPボードの挙動が、fa.spiを使った時だけ妙 + mode切り替えをすると動くことがある
という話を聞いたので、mode切り替えだけで出力が切り替わるのかを調査。

初期状態
SCK = HIGH(Hi-Z)
MOSI = HIGH(Hi-Z)
INT = HIGH(Hi-Z)
SS = HIGH(Hi-Z)
MISO = HIGH(Hi-Z)

fa.spi("init")
SCK = LOW
MOSI = LOW
INT = HIGH(Hi-Z)
SS = HIGH
MISO = HIGH(Hi-Z)

→defaultではモード3とリファレンスに書いてあるが、どうみてもmode3ではない。
 ただ、1度空readをするとmode3らしき挙動になる。
 また、モードを切り替えてもinitするとまた戻される。

fa.spi("mode",0)
SCK = LOW
MOSI = LOW
INT = HIGH(Hi-Z)
SS = HIGH
MISO = HIGH(Hi-Z)

fa.spi("mode",1)
SCK = LOW
MOSI = LOW
INT = HIGH(Hi-Z)
SS = HIGH
MISO = HIGH(Hi-Z)

fa.spi("mode",2)
SCK = HIGH (時折LOWのまま)
MOSI = LOW
INT = HIGH(Hi-Z)
SS = HIGH
MISO = HIGH(Hi-Z)

fa.spi("mode",3)
SCK = HIGH (時折LOWのまま)
MOSI = LOW
INT = HIGH(Hi-Z)
SS = HIGH
MISO = HIGH(Hi-Z)

・結論
切り替わった。

ただし、時折切り替わり不良を起こしているらしき状態がある。
(mode3なのにSCKがLなど。cs切り替えでも発生する)

その場合、いくら切り替えても治らない。(極稀に治る。)
ただ、fa.spi("read")とでもして送信処理をさせれば、必ず切り替わる。

CSの前、もしくは後に空読みを入れると、不安定さが解消するようです。
参考:Lua:fa.spiサンプル

CSが反映されないことがあるバグ(or仕様)が影響し、
連続したパケットとして認識されていた可能性が高いです。
ソフトSPIで動いていたのは、このバグ(or仕様)がないためだと考えられます


ファームウェアバージョンW3.00.00

fa.spiが正常に動作しない

→解消済み
公式にfa.spiが掲載されていなかった理由がこれのようである。

Luaスクリプトでフリーズ

→解消済み

FlashAirでスクリプトを書いていると、こういうことが起きます。
  1. 突然Webサーバーにつながらなくなった
  2. インターネットにつながらなくなった(インターネット同時接続モードのとき)
  3. 突然ping応答がなくなった
  4. デジカメがSDカードエラーを吐いた(しかも差し込みなおすと治るが、スクリプトが動く条件になると再発する)
  5. 差し込んだ機械がフリーズした
  6. PCから読み込みも書き込みもできなくなった
  7. ファイルが破損した
  8. フォーマットが必要になった

これらは、FlashAirがフリーズした場合に発生します。
ちなみに私は、DSiを電源供給用に使っていて、音楽を再生していたら
スクリプトを実行した途端音楽が壊れてガチでビビりました。

また、503エラー、403エラー、応答にやたら時間がかかる、などの場合、
同様のメモリエラーが起きています。(フリーズ寸前です)

→単純に深い場合
FlashAirはメモリが小さいため、関数の中で関数を呼び出す、というのを繰り返すと、よくフリーズします。
特に、fa.requestはフリーズしやすく、また普通の関数でもフリーズします。
メモリの空き状態によってフリーズする条件が変わるので、結構困りますが、関数を深くしないということに気を付ければ
大分引っかかりにくくなります。

例1. fa.requestの場合
function f()
mes = "" b,c,h = fa.request{url = "http://example.com/", headers = {["Content-Length"] = tostring(string.len(mes))}} print("HTTP/1.1 200 OK\n") print("OK")
end

f()

この場合、
1.fa.requestを呼び出す階層を減らす (functionで囲わない)
2.tostring周辺の演算を先にしておく(公式のサンプルではそうなっています)
というのが挙げられます。

改善例
function f()
mes = "" len = tostring(string.len(mes)) b,c,h = fa.request{url = "http://example.com/", headers = {["Content-Length"] = len}} print("HTTP/1.1 200 OK\n") print("OK")
end

f()

例2. 普通の関数でも
function f(i)
print(i) return i+1
end

print("HTTP/1.1 200 OK\n")
print("OK")

f(f(f(f(f(f(f(0)))))))

これはさすがにないだろ、と思われるかもしれませんが、
これは毎度必ずフリーズする条件を探った結果で、他のスクリプトの実行後などでは
f(f(0))でもフリーズすることがまれにあります。

もちろん、同じ関数でなく、f1(f2(0))でも起きますし、先のfa.requestのように、関数の処理内で関数を呼び出しても落ちることがあります。
関数は多くても3階層くらいまでにしたほうがいいでしょう。

メモリ管理不良?

→解消済み

dofileという、外部のスクリプトを読み込む機能がありますが、なぜかフリーズします。使わない方が安全です。
loadfileで関数として読み込むのはフリーズしにくいですが、前述の関数階層が-1されるので、注意してください。
requireも同じく外部からスクリプトを読み込む機能があります。
で、このrequireを使って2KB以上のスクリプトを読み込むと、その場では正常に動きますが
string.byteを呼び出すとフリーズします。他の関数でもフリーズするかもしれません。

回避策は、requireで読み込むサイズを1KB以下に抑えるか、requireを使わずスクリプトに直書きすることです。
FlashAirは最低8GBも容量がありますから、使わない手はない。富豪的に行きましょう。
...かと思いきや、べた書きでも18KBくらいで頭打ちになります。

fa.requestが動かない、HTTPGetFileで異常なデータが現れる。

→解消済み

fa.requestは3KBまでしか受信できません。これは公式の仕様です。はい。終わりです。
では、大きなファイルを受信するにはどうするかというと、HTTPGetFileを使用しますが、これまた曲者です。

FlashAirをいじってわかったこと。より。

fa.HTTPGetFileは、アクセス先のサーバーによって(条件不明)、
 ・正常に受信できる
 ・受信に成功するが、先頭と末端にゴミがつく
 ・受信失敗ということになるが、なぜか連番拡張子なしのファイルが生成され、
  中身はゴミ付きの目的のデータ
 ・受信に失敗する
 の4パターンがある。
 詳しく検証していないが、ゴミはチャンクストリームそのものの可能性もある。
です。

正常に受信できたのは以下です。
http://192.168.1.3/ (BJDで立てた自鯖)
http://example.com/
http://lashair-developers.com/ja/

正常に受信できなかったのは以下です。
http://www.google.co.jp/
http://ja.wikipedia.org/

f=fa.HTTPGetFile("http://www.google.co.jp/","test.htm")
の場合。

中身は
「8000
<!doctype html><html
〜省略〜
</body></html>



となる。先頭にゴミが付き、末端に空行がつく。
また、これは指示したtest.htmではなく、別の連番ファイルに保存される。(受信可否は失敗となっている)

f=fa.HTTPGetFile("http://ja.m.wikipedia.org/wiki/A","test.htm")の場合、
f=1で受信成功だが、test.htmの中身が
「008000
<!DOCTYPE html>
<html lang="ja"
〜省略〜

</body>
</html>


/spa」となる。
明らかに先頭と末端に余計なごみが付いている。また、一部の文字が化ける。

これらより、HTTPGetFileは極力使わない方がよさそうだということがわかる。
そもそも。SDカード内にファイルを生成すること自体が極めて高確率でFAT破壊を引き起こす。
(電源のみ供給した場合を除く)ので、やらない方がいい。

長いURLにゴミが付く

→解消済み

a.luaというスクリプトがFlashAirのルートにあるとき、
http://flashair/a.lua?b
と渡してあげれば、arg[1]で引数"b"が取り出せる。

では、この引数は何文字まで付けられるのか。
RFC上は制限がないが、このメモリの少ないFlashAirではそんなことはない。
一般的にはURL全体で255文字とか、2048文字とか言われているが、
結論から言うと、自身の名前+?(セパレータ)も含めて、142文字までで、それ以上は打ち切られる。

また、引数の末端には0x0Aがくっつく、はず。地味に邪魔なので注意。
142文字以上を入れると、末端に不可視の制御文字が紛れ込む。正直邪魔なので、それ以下の長さにした方がいい。

さらに長く、200文字くらい入れると、メモリ破壊を起こすらしく、Webサーバー機能が停止する(503/403もしくは応答なし)
javascriptなどから生成して送るときは要注意。

Luaスクリプトに引数を付けて30〜100回くらい呼び出すと落ちる

→解消済み

print(arg[1]) と書かれたスクリプトを呼び出しただけの場合で、
URLの長さが129文字の状態で実行すると、260回のアクセスでフリーズする。
これは、連続でなく、電源を入れてからの累計である。

また、複雑なスクリプトの場合、40回程度呼び出しただけでフリーズする場合がある。

つまり、利用者アンケートのようなものを記録するHTMLフォームを作った場合、40人程度でフリーズして
FlashAirを再起動するまで受け付けない、ということがあるということである。

幸いなことに、フリーズするのはLua実行機能のみで、普通のファイルを配布する機能としてのWebブラウザや
SDカードとしての機能は生きているので、その辺の心配は不要であるが。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

スマートフォンの方は画面下部よりPC版に切り替えることをおすすめします

アクセス解析中

忍者アナライズ

GoogleAnalytics

編集にはIDが必要です