PROGMEM をつけると (const も必須)、その変数の示す先がプログラムメモリー領域になる。そのままだと使えないのでワーキングメモリ (SRAM) にコピーする必要がある、という話。大きい定数は SRAM に置けないので、基本的にプログラムメモリ (フラッシュメモリ) 上に置いて、必要なときだけコピーするようにする。

avr/pgmspace.h に byte やら word を読み出す関数は提供されているけど、long はない。どうするのが正しいのかなあと思ったけどよくわからなかった。

結局以下のように memcopy でうまくいった。

const uint32_t MORSE_CODES[] PROGMEM = {
    ...
};

uint32_t current_sign;
memcpy_P(¤t_sign, &MORSE_CODES[character], 4); 


progmem 調べていると prog_ が prefix された型を使え、って書いてあるのがよく検索ででてくるけど、それは obsolete で、使うとエラーになる。ヘッダを読んだほうが良い。const と PROGMEM をつけるのが正しい。

しかしヘッダ見ると far とか near とかよくわかんない関数がいっぱいあって混乱する。far は 64KB 以上のフラッシュがあるデバイスしか関係ないっぽいので気にしないほうがいいっぽい。つまり near_ だけ使っていれば良い (実際、 near も far もついていない関数は near のエイリアスになっている)

ヘッダファイルの冒頭部分の一部を訳してみた。

\note If possible, put your constant tables in the lower 64 KB and use
pgm_read_byte_near() or pgm_read_word_near() instead of
pgm_read_byte_far() or pgm_read_word_far() since it is more efficient that
way, and you can still use the upper 64K for executable code.
All functions that are suffixed with a \c _P \e require their
arguments to be in the lower 64 KB of the flash ROM, as they do
not use ELPM instructions. This is normally not a big concern as
the linker setup arranges any program space constants declared
using the macros from this header file so they are placed right after
the interrupt vectors, and in front of any executable code. However,
it can become a problem if there are too many of these constants, or
for bootloaders on devices with more than 64 KB of ROM.
All these functions will not work in that situation.

可能なら、定数テーブルは 64KB 以下に配置し、pgm_read_byte_far() や pgm_read_word_far() の代わりに pgm_read_byte_near() や pgm_read_word_near() を使ったほうが効率が良いし、なおかつ 64KB 以上は実行コードに使える。

プリフィックスに _P がついている全ての関数はELPM 命令を使わず、フラッシュROMの64KB 以下を引数にとる。これは大抵の場合、このヘッダファイルのマクロを使って定義されたプログラムスペース定数はリンカーが割込みベクターのすぐ後に配置するので、気にすることはない。

しかしながら、もしこのような定数が多すぎる場合や、デバイス上のブートローダーが 64KB 以上の場合問題をひきおこすかもしれない。これらの関数はこのような状況では一切動かないだろう。

  1. トップ
  2. avr
  3. AVR progmem に long を置く方法
  1. トップ
  2. arduino
  3. AVR progmem に long を置く方法

抵抗器とかコンデンサとかをうまく整理する方法を考えてる。とにかく種類が多いし、そこそこ体積があったりするので面倒くさい。

値わけして袋詰めするまではいいとして、袋がばらばらにあっても、ソートされていないと見つけることができないのでゴミと変わりがない。

抵抗

抵抗はそんなに大きくないので (100本ぐらいだと結構…) 100均のハガキ用バインダーにだいたい納まった。E24 系全部持ってたりすると2冊ないとダメそう。

コンデンサ

電界コンデンサだと特にだけど、そこそこ体積があるので、バインダーみたいのに入れこむのはつらい。こちらは普通に横長のプラスチックケースにソートして入れるみたいにしてみた。

本当は仕切りが可変できるパーツボックスがあればいいんだけど、結構高いのしかないので、これで我慢する。

半導体

半導体が一番悩ましい。ソートしようがないので、できるだけ 一覧性が高い形で保存したいけど、いい方法が思いついてない。

基本は用途別にわけていくのがよさそう。

  • ダイオード
    • 整流用
    • 小信号用
    • ツェナー
  • LED
    • 形別にわける
  • トランジスタ
    • 耐圧ごと? になんとなくソート?
    • フォトカプラも
  • FET
    • 耐圧ごと? になんとなくソート?
  • センサー系
  • ロジックIC
  • オーディオ関係IC
  • マイコンチップ