【Arduino工作〜発展編】AVR-RustでAtmega328pをLチカ!レベル2


※ 当ページには【広告/PR】を含む場合があります。
2021/10/27
2021/11/04
[Arduino工作〜発展編] RustでATmega328pのプログラムをビルドしてみる
【Arduino工作〜発展編】AVR-RustでAtmega328pからPWM波形を出力したい!
蛸壺の中の工作室|AVR-RustでAtmega328pをLチカ!レベル2
前回(RustでATmega328pのプログラムをビルドしてみる) を使ってLチカを試しました。

合同会社タコスキングダム|蛸壺の技術ブログ
[Arduino工作〜発展編] RustでATmega328pのプログラムをビルドしてみる

RustからどのようにAVRマイコン用のプログラムを使っていくのか考えていきます。



今回の記事では、このruduinoの内部の実装を参考にしながら、もう少しだけ応用範囲を拡げられるように、AVR-Rustライブラリを使った1レベル上のLチカを実装する手順を紹介します。


マイコンの書込構成(おさらい)



サラのAtmega328pにプログラムを書き込む際に利用するピンと、書込装置を正しく接続することが重要になってきます。

以前の記事 モードでのAVRマイコンへの書き込みは以下の図の6つのピンを利用します。

合同会社タコスキングダム|蛸壺の技術ブログ


AVRマイコンをSPI(ISP)モードで書き込む場合には、専用ライターが必要になります。
どのようなAVRマイコンでも安定して書き込めるように、また何かあったらヒューズビットも書き込みできるように、例えば『
』のような製品を少し高価でも一つ持っておくと良いと思います。
著者の場合はAVRだけでなくSAMも使うので正規品の
Atmel-ICE を使っています。

はロイヤリティもありこちらはかなり高価ですが、Cortexベースの組込開発にもスムーズに移行できるのでオススメです。
正規品をセールスで出ているのを狙って買うか、以下のようなサードパーティ製の互換品を購入することもできます。

ちなみに付属品のJTAGケーブルのアクセサリーは失くすと、色んなプログラミングモードでピンの番号の対応を確認しなくてはならないという地味に辛い作業をしなくてはならないので、大切に保管しましょう。
以下は、Atmel-ICEとAVRマイコンの接続例を模した図になります。

合同会社タコスキングダム|蛸壺の技術ブログ

avrdudeの準備



AVRマイコンへの実行プログラム書き込みを行うコマンドは
avrdude になります。

前回の記事 ではLinuxOS環境へのインストール手順を説明しておりましたので、詳細はそちらでご確認ください。


合同会社タコスキングダム|蛸壺の技術ブログ
[Atmel-ICE on Linux] Debianからavrdudeを使ってブレッドボード上でAtmega328pのプログラムを書き込む

新品のAtmega328pにDebian Linux & Atmel-ICEでavrdudeを使ったプログラムをブレッドボード上で書き込みする手順を特集します。




書込装置とマイコンへの接続をテストするためにAtmega328pのメモリ情報を出力します。

            $ sudo avrdude -c atmelice_isp -P usb -p m328p -v
avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/etc/avrdude.conf"
         User configuration file is "/root/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : usb
         Using Programmer              : atmelice_isp
avrdude: Found CMSIS-DAP compliant device, using EDBG protocol
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : JTAG3_ISP
         Description     : Atmel-ICE (ARM/AVR) in ISP mode
         Vtarget         : 5.0 V
         SCK period      : 8.00 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as FF

avrdude: safemode: lfuse reads as 62
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OK (E:FF, H:D9, L:62)

avrdude done.  Thank you.

        

エラーもなくAtmega328pのメモリにアクセスできているようなので、これで書き込み準備はOKです。
続いてRustでのプログラムの実装をやっていきましょう。


Rustでのプログラム実装



まず今回のプロジェクトの構造は以下のようにしています。

            $ tree
.
├── Cargo.toml
├── src
│   └── main.rs
└── avr-atmega328p.json

        

これはほとんど
ruduinoでやったときプロジェクト構造 と変わらないというか、もともとこれがAVR-Rustの作法であるので、当然と言えば当然です。
まずはruduinoを参考にしながら
Cargo.toml の中身を作成します。

            [package]
name = "std-blink"
version = "0.1.0"
authors = ["tacoskingdom<contact@tacoskingdom.com>"]
edition = "2018"

[dependencies]
avr-std-stub = "1.0.2"
avrd = "0.3.1"
avr_delay = { git = "https://github.com/avr-rust/delay" }

        

パッケージの名前は適当に
std-blink という名前にしておきます。
次にAtmega328p用にツールチェーンやビルド設定ファイル・
avr-atmega328p.json を作成します。

            {
    "arch": "avr",
    "cpu": "atmega328p",
    "data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
    "env": "",
    "executables": true,
    "linker": "avr-gcc",
    "linker-flavor": "gcc",
    "linker-is-gnu": true,
    "llvm-target": "avr-unknown-unknown",
    "no-compiler-rt": true,
    "os": "unknown",
    "position-independent-executables": false,
    "exe-suffix": ".elf",
    "eh-frame-header": false,
    "pre-link-args": {
      "gcc": ["-mmcu=atmega328p"]
    },
    "late-link-args": {
      "gcc": ["-lgcc", "-lc"]
    },
    "target-c-int-width": "16",
    "target-endian": "little",
    "target-pointer-width": "16",
    "vendor": "unknown"
}

        

このファイルについては
こちら でも触れましたが、ターゲットCPU毎に作り直す必要があります。
Atmega328p以外のAVRマイコンを使う場合には、そちらを参考にしてください。

avr_delayライブラリについて