Difference between revisions of "D on AVR"

From D Wiki
Jump to: navigation, search
m (Fix build)
 
(One intermediate revision by the same user not shown)
Line 5: Line 5:
 
The merge of the AVR backend for LLVM (https://github.com/avr-llvm) in the upstream LLVM project has given rise to the porting of modern languages ​​to develop on AVR, such as Rust (https://github.com/avr-rust), Go (https://github.com/tinygo-org/tinygo) and Swift (http://swiftforarduino.com/).
 
The merge of the AVR backend for LLVM (https://github.com/avr-llvm) in the upstream LLVM project has given rise to the porting of modern languages ​​to develop on AVR, such as Rust (https://github.com/avr-rust), Go (https://github.com/tinygo-org/tinygo) and Swift (http://swiftforarduino.com/).
  
D has its frontend for LLVM so you can use it to program on AVR.
+
D has its frontend for LLVM so you can use it to program on AVR and this comes with LDC.
 
 
== Get LLVM source ==
 
 
 
<syntaxhighlight lang="shell">
 
  $ wget https://releases.llvm.org/9.0.0/llvm-9.0.0.src.tar.xz
 
  $ tar xf llvm-9.0.0.src.tar.xz
 
</syntaxhighlight>
 
 
 
== Build and install LLVM with AVR target ==
 
<syntaxhighlight lang="shell">
 
  $ cd llvm-9.0.0.src
 
  $ mkdir build
 
  $ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD=AVR \
 
    -DLLVM_TARGETS_TO_BUILD= -DLLVM_BINUTILS_INCDIR=/usr/include \
 
    -D CMAKE_INSTALL_PREFIX=/opt/llvm-avr
 
  $ sudo ninja install
 
</syntaxhighlight>
 
 
 
== Get LDC source ==
 
<syntaxhighlight lang="shell">
 
  $ git clone https://github.com/ldc-developers/ldc -b v1.18.0
 
</syntaxhighlight>
 
 
 
== Build and install LDC with LLVM AVR ==
 
<syntaxhighlight lang="shell">
 
  $ cd ldc
 
  $ mkdir build
 
  $ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/opt/ldc-avr -DLLVM_ROOT_DIR=/opt/llvm-avr
 
  $ ninja
 
  $ sudo ninja install
 
</syntaxhighlight>
 
  
 
== Test D with AVR ==
 
== Test D with AVR ==
Line 83: Line 52:
 
== Current projects for use D on AVR ==
 
== Current projects for use D on AVR ==
 
* AVRD - https://github.com/WebFreak001/avrd
 
* AVRD - https://github.com/WebFreak001/avrd
 +
 +
== Blogs about D on AVR ==
 +
* http://dpldocs.info/this-week-in-d/Blog.Posted_2022_10_10.html#hello-arduino
  
 
== Info about the GNU/LINUX distros ==
 
== Info about the GNU/LINUX distros ==
 
* ArchLinux, The llvm package in the official repo is already builded with the AVR flag (https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/llvm#n40), therefore the ArchLinux LDC package also supports the AVR target out-of-the-box
 
* ArchLinux, The llvm package in the official repo is already builded with the AVR flag (https://git.archlinux.org/svntogit/packages.git/tree/trunk/PKGBUILD?h=packages/llvm#n40), therefore the ArchLinux LDC package also supports the AVR target out-of-the-box

Latest revision as of 16:57, 10 October 2022

AVR is a family of 8-bit RISC microcontrollers, are widely used for embedded applications where a simple, inexpensive and low-powered microcontroller is needed.

In the FOSS community, AVR-GCC has always been used as a toolchian for AVR which includes all the tools needed to compile a C source, copy the object files into a hex file and write it to the ROM of the microcontroller.

The merge of the AVR backend for LLVM (https://github.com/avr-llvm) in the upstream LLVM project has given rise to the porting of modern languages ​​to develop on AVR, such as Rust (https://github.com/avr-rust), Go (https://github.com/tinygo-org/tinygo) and Swift (http://swiftforarduino.com/).

D has its frontend for LLVM so you can use it to program on AVR and this comes with LDC.

Test D with AVR

enum AVR_ARCH = 5; // AVR architecture of your MCU

static if (AVR_ARCH >= 100) {
 enum SFR_OFFSET = 0x00;
} else {
 enum SFR_OFFSET = 0x20;
}

enum ubyte* MMIO_BYTE(ubyte memAddr) = cast(ubyte*) memAddr;
enum ubyte* SFR_IO8(ubyte ioAddr) = MMIO_BYTE!(ioAddr + SFR_OFFSET);

enum ubyte* PINB = SFR_IO8!(0x03);
enum ubyte* DDRB = SFR_IO8!(0x04);
enum ubyte* PORTB = SFR_IO8!(0x05);

extern(C) void main() {
  import core.bitop;

  volatileStore(DDRB, 0xFF);  // Set all PORT B to output
  
  while (true) {
    volatileStore(PORTB, 0xFF); // Set all PORT B to high
  }
}

This simple code will set all I/O PORTS B to high, on Arduino UNO for example the PORT B ​​is connected to the digital pins from 8 to 13 and this code will cause the internal LED to light up as it is connected to PIN 13.

How to build and run the test code

First of all to generate an object file for AVR, convert it to HEX and then flash it into the flash memory of the MCU is advisable to use AVR GCC as C toolchain, linker, objcopy (to convert to hex) and avrdude (to load it into flash).

Therefore it is necessary to install AVR-GCC, to do this consult the documentation of your operating system.

The following commands need AVR-GCC installed and in a directory present in the PATH environment variable and are meant to be used with Arduino UNO, minor modifications are needed for other AVR MCUs

  $ /opt/ldc-avr/bin/ldc2 -betterC -Oz -mtriple=avr -mcpu=atmega328p -Xcc=-mmcu=atmega328p -gcc=avr-gcc test.d
  $ avr-objcopy -O ihex -R .eeprom  test test.hex // -R .eeprom is used to avoid overwriting the EEPROM, since is used to store data
  $ avrdude -F -V -c arduino -p ATMEGA328P -P /dev/ttyACM0 -b 115200 -U flash:w:test.hex // Write the hex in the ROM and reset MCU

Current projects for use D on AVR

Blogs about D on AVR

Info about the GNU/LINUX distros