2012年8月25日土曜日

Linux上でavraを使ってtiny10のアセンブラソースを書く

ATtiny2313をはじめATmega88,ATmega328などのデバイスに対応しているアセンブラ avra を利用しています。ATtiny10もavraのサポート対象に入っているのですが、先のATtiny10のライタを作ったときに添付したLチカプログラムのアセンブラソースをアセンブルしてみると下のようなエラーでアセンブルが途中で中断してしまいます。

> avra -l init.lst init.asm

AVRA: advanced AVR macro assembler Version 1.3.0 Build 1 (8 May 2010)
Copyright (C) 1998-2010. Check out README file for more info

   AVRA is an open source assembler for Atmel AVR microcontroller family
   It can be used as a replacement of 'AVRASM32.EXE' the original assembler
   shipped with AVR Studio. We do not guarantee full compatibility for avra.

   AVRA comes with NO WARRANTY, to the extent permitted by law.
   You may redistribute copies of avra under the terms
   of the GNU General Public License.
   For more information about these matters, see the files named COPYING.

Pass 1...
Pass 2...
init.asm(95) : Error   : PUSH instruction is not supported on ATtiny10
init.asm(96) : Error   : PUSH instruction is not supported on ATtiny10
init.asm(110) : Error   : POP instruction is not supported on ATtiny10
init.asm(111) : Error   : POP instruction is not supported on ATtiny10
done

Used memory blocks:
   Code      :  Start = 0x0000, End = 0x002E, Length = 0x002F

Assembly aborted with 4 errors and 0 warnings.
make: *** [init.hex] エラー 1

エラーの内容は、”ATtiny10では、push/popインストラクションをサポートしてません。”なのですが、そんな訳は無くATtiny10のデータシートのインストラクションセットのページにちゃんと紹介されています。

(ATtiny10 Datasheetより抜粋)

それではということで、AVRAのソースを調べてみる事にします。AVRAを展開したディレクトリ avra-1.3.0/src を見ると、mnemonic.c というファイルがあります。この中にはAVRAで使えるニーモニックが記述されていて、どのデバイスでどのニーモニックが利用可能かが定義されています。 230行目あたりに下のリストに示した記述が見当たります。

231         {"ror",   0x9407,          0},
232         {"asr",   0x9405,          0},
233         {"swap",  0x9402,          0},
234         {"push",  0x920f,  DF_TINY1X},
235         {"pop",   0x900f,  DF_TINY1X},
236         {"tst",   0x2000,          0},
237         {"clr",   0x2400,          0},
238         {"lsl",   0x0c00,          0},
で、この DF_TINY1X が何であるかは src/device.c の中に定義されています。
 47 struct device device_list[] =
 48 {
 49   /*        Name, Flash(words),RAM start, RAM size, EEPROM, flags */
 50   {         NULL,     4194304,      0x60,  8388608,  65536, 0}, // Total instructions: 137
 51   /* ATtiny Series */
 52   // ATtiny4
 53   // ATtiny5
 54   // ATtiny9
 55   {   "ATtiny10",         512,      0x00,        0,      0, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELP    M|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
 56   {   "ATtiny11",         512,      0x00,        0,      0, DF_NO_MUL|DF_NO_JMP|DF_TINY1X|DF_NO_XREG|DF_NO_YREG|DF_NO_LPM_X|DF_NO_ELP    M|DF_NO_SPM|DF_NO_ESPM|DF_NO_MOVW|DF_NO_BREAK|DF_NO_EICALL|DF_NO_EIJMP},
と言うわけでどうやら ATtiny10ではこのコマンドをサポートしない様に指定されているようです。
このままでは ATtiny10で push / pop が使えないので、先の mnemonic.c の中で
234         {"push",  0x920f,          0},
235         {"pop",   0x900f,          0},
236 //      {"push",  0x920f,  DF_TINY1X},
237 //      {"pop",   0x900f,  DF_TINY1X},
として push / pop をこの制限から外してしまいます。 
DF_TINY1X はATtiny10の他にもtiny11/tiny12/tiny15/tiny28/90S1200 でも使われているので、
これらのデバイスを使う際には注意が必要ですが、当面使う予定がないのでこれをコメントアウトして
avra をコンパイルし直します。
問題なく push / pop がコンパイルされるようになります。 

0 件のコメント:

++ Myself ++

普通(?)のサラリーマン -- 生活のすきま時間にキーボードとはんだごてを持ち替えてプログラミングと電子工作してます