「PIC AVR 工作室」サイトの日記的なブログです。
サイトに挙げなかった他愛ないことを日記的に書き残してます。
PIC AVR 工作室 ブログ



http://minna.cert.yahoo.co.jp/lpva/9604

のび太が100点取った時の問題だそうです。

オイラは暗算苦手なので紙とペンでやりました。
4年生ののび太くんには負けなかったようです。
とりあえずよかった…。

問題自体はヒネリは無いので、分数計算を
忘れてなければ何のことはないんですが…


マイコンの検定って言うのはないんだなぁ…。



コメント ( 0 )




avr-gccで32KBを超える定数配列を
作ってflashに配置しようとすると
コンパイルエラーになっちゃうという件。

定数定義を分割してからコンパイルしなおして
みました。こんな感じ。
(半角不等号は全角に置き換えてあります)

#include <avr/pgmspace.h>

const char misaki_char1[][8] PROGMEM = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
(中略)
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
const char misaki_char2[][8] PROGMEM = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
(中略)
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};
const char misaki_char3[][8] PROGMEM = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
(中略)
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
};

こんな風に適当に3分割してみたところ、
コンパイルはすんなり通り、出来上がった実行
ファイルのサイズも約63KBと想定どおり。

実際に各配列へのアクセスは行ってませんが、
この時点でコンパイルが通っている以上
特に難しいことにはならないでしょう。

ただ、3つの領域に分割してあり、かつ
構造体とかで1つに纏めるとまたエラーが
でちゃうはずなので、ロジック上で1個の
データとして見せかけるしかありません。

関数の添え字に相当する数値を受け取って、
それに相当するビットマップデータを返す
という関数でも組めば良さそうです。
関数内で3つのうちどの配列から取り出せば
良いか判断させるという感じ。

うん、まぁこれで理論上は好きなようにアクセス
出来ることになったわけだけど…
関数コールのオーバーヘッドが生じるってことは
処理速度上マイナスだな。

C言語だけで漢字テキストのビデオ表示、みたいな
ことやろうとすると、このオーバーヘッドは
ちょっと無視できないレベルかも…

VRAMを「グラフィックVRAM」とするなら
あまり問題は無いんだけど、「テキストVRAM」
上のデータを逐次デコードしながら表示する
場合には配列へのアクセスが頻繁すぎて
デコードが間に合わなくなるのは目に見えてる…


LCD表示の場合なら、LCD側にVRAMを
保有してるだろうから、グラフィックVRAM
だろうがテキストVRAMだろうが関係ないけどね。

まぁいずれにしても、AVRならアセンブラでも
Cでも美咲フォントのデータをプログラムflash
上に配置することが出来る目処がついたな。

あとでサイトに纏めておきたいと思います。



コメント ( 4 )




avr-gccの配列サイズの制約についてさらに
調べてみたら、↓ここに
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=58517

纏めが書いてありました。曰く…

>Unfortunately, Dean, *both* limitations are valid in avr-gcc:
>1) An array index is a signed 16-bit integer, thus array indexes cannot be computed outside the range [-32768, +32767], and
>2) No single object can have a byte count greater than 32767 bytes.

>If you chop the array in half and place both halves into a struct, then the struct itself would be an object whose size is greater than 32768 bytes, and thus the compiler would generate the exact same error.

簡単に纏めると、配列の添え字は16ビット幅の
signed intなので最大でも32767までしか使えないし、
一つのオブジェクトのサイズがそもそも32767バイト
より大きく出来ない、という2つの制約があるという
ことのようです。


なので、2つの配列に分割する場合にそれらを
連続したメモリに配置するために1つの構造体に
纏めようとすると、結局合体した2つの配列の
合計が32767バイトを超えちゃうので、
それはそれでダメと言うことみたいです。

今回のオイラのケースだと、添え字のほうは
制約に引っかかってないはずだけど、バイト数は
63KBほどあるから最低でも二分割する必要は
ありそうだな…

avr-gccは、扱うCPUがAVRって
限定してるから、あまり大きな配列を扱う
前提にはなってないんだね…


で、ぼやいても仕方ないので現実解を考えてみる…


まず配列を2つに割ってみる…それぞれの配列は
2つの制約に引っかからないのでOKなはず。

ただし連続領域には配置されないので、配列の
添え字として参照するのではなく、関数の
引数として位置を引き渡すと、その関数が
どちらかの配列から値を参照して返す。

みたいな感じにすれば上手く行くかな?
あとでちょっと試してみよう。

出来れば意味のあるところで二分割したいところ
だけど、まぁ、拘る部分ではないから適当に
制約に引っかからない位置で分割すればいいのかな?

もちろん、avr-gccに関する制約だから、
他の言語系ならこのままでも上手く動くかも
しれないな。


むしろ、I2Cのeepromに押し込んじゃう
のが一番ラクチンなのかもね。



コメント ( 0 )




avr-gccで大きいサイズの配列を作ったら
コンパイラがエラーを吐き出した件、ちょっと
調べてみました。

avr-freaksにそれっぽいものが。
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=80105&postdays=0&postorder=asc

やっぱり32KBを超えるとエラーになるみたい。

幾つか解決方法を話し合われているみたいなんだ
けど、配列を分割するとか、バイナリデータを
リンカでリンクする時に取り込むとか、外付けの
eepromを使うとか、そんなところみたい。
決定打は見当たらないな…

うーん。



コメント ( 0 )




昨日に続き、美咲フォントを利用する作戦です。

昨日はpng画像をbmp画像にしたモノを、
HSPを使ってavr用アセンブラのソース形式
にするところまでやりました。

で、実際にAVRstudio上でmega128
用にアセンブルしてみたら…上手く行きました。
まぁ、容量さえ足りるなら特に難しいところは
ないでしょう…


次。インテルhex形式用のHSPスクリプトも
書いてみました。昨日のを流用してチョイチョイと。

で、吐き出したhexファイルを秋月のeeprom
ライター用ソフト(PICライターに付属のソフト)
で読み込んでみたところ、エラーも無く上手く読み
込めました。
容量としては60KBを超えているので512kビット
タイプ(64KB)以上のeepromじゃないと
入りきりません。

買い置きのeepromを漁ったら、約10個全部が
256kビット(32KB)タイプだったので、
書き込み確認は出来ませんでしたが…

そうそう、秋月とかで売っているSG12864Aのような
LCDの場合、ビット列が横じゃなく縦方向で
用意しないといけないので、そういう用途の場合は
ハードにあわせてスクリプトを直す必要が
あるかもしれません。

まぁ、直すのはチョイチョイだから後回し。


次。C言語ソース形式にもしてみたいな。
AVRであればWIN-AVR(AVR-gcc)
で使えるようにしたいところ。

以前デカイデータをプログラム領域(.cseg)に
押し込んでgccのプログラム組もうとした時に
散々トラブった記憶があるので、ちょっといやな
予感ですが…

とりあえず方針的にはchar型の2次配列にして、
1バイト単位でメモリ上に配置されるように
考えてみます。

で、スクリプトはすぐに出来ました。

実行して、出来たCソースをAVRstudio
のCプログラム中に取り込んでコンパイル…。

でかすぎるというエラー。あ、.dsegに配置しようと
してるな。間違えた。入る訳無い。SRAMは
4KBしかありませんからね。
あらためて.cseg上に配置するようにソースを修正…。

またしてもでかすぎるというエラー。うーん、
今回は間違えは無いはずなんだけどな…

でかいというのなら、極端に削ってみよう…
3行程度(24バイト分)にしてみた。
コンパイル通った。(あたりまえ)

これをシミュレーションに掛けてみて、プログラム
メモリ、SRAM、EEPROM、レジスタの
それぞれをメモリダンプ取ってみると…
うん。やっぱりプログラムメモリにしか配置
されてないよな。(以前の実験ではプログラムと
SRAMの両方にメモリを確保に行ってしまい、
全然ダメだったんですが、今回はそれは大丈夫
みたい)

うーん、方針は合ってるのか。

データ量を半分くらいに削ってみる…
お、コンパイル通った!

うーん、30KBくらいならOKか…
オリジナルは60KBくらいになっちゃう
ので、ここから少しずつ削りながらコンパイル
を繰り返してみると…

およそ32KBを割ったところでコンパイルが
通るようになるみたい。


うーん、AVR-gccって、32KBの壁
なんて有ったんだったっけなぁ?記憶に無いな…
あとで調べなおしてみよう…
(16FシリーズのPICは面倒くさいのが
 イロイロあった気がするけど…)

いずれにしても、このままでは8ビット版AVR
には載せられそうに無いな。


というわけで、スクリプトを書きまくったので、
あとでサイトに纏めておきたいと思います。


ちなみにeepromに格納しておけば、メモリが
ちっちゃいマイコンでも充分使い物になるかと
いう気がします。I2Cで読み出してLCDに転送
みたいに…。

SG12864Aみたいな128×64ドットLCDだと
1ドット=1ビットでも1024バイトが必要に
なるはずなんですが、テキスト文字表示だけに
特化するならマイコン側にグラフィックVRAM
を持つ必要は無いので、マイコン側に必要なのは
テキストVRAMと変換処理ロジックだけ。

128×64ドットを1キャラクターあたり
8×8ドット単位とすれば128バイトで済んで
しまいます。
tiny2313じゃぁ厳しいけど、もうちょっと
大きいマイコンなら何の問題も無いでしょう。

忘れてはならないのは、jisとshift-jis
の変換とか、その辺りに待つわる文字化けとか、
そのあたりかな。

ハヤニエLCDを工作に引っ張り出すか、
もしくはMEGA128のオンメモリに組み込んで
リアルタイムのビデオ表示に使うか…

イロイロ使い道は有りそうな予感。
( ̄ー ̄)



コメント ( 0 )



« 前ページ 次ページ »