Zig: Arduino support?

Created on 9 Nov 2019  Â·  13Comments  Â·  Source: ziglang/zig

Is it possible to have support for Arduino and other micro controllers?
And if so, what needs to happen?

arch-avr

Most helpful comment

i had a small time to work on it,
work with :

const PORTBDATA = 0x25;
const PORTBDIR = 0x24;

export fn main () void{
    var pb = @intToPtr(*volatile u8, PORTBDATA);
    var pbd = @intToPtr(*volatile u8, PORTBDIR);
    pbd.* = 0xff;
    while(true){
        pb.* = (1 << 5);
        var i : u32 = 0;
        while (i<5000) {
            // nop
            i +=1;
            var j = pb.*;
        }
        pb.* = 0;
        i = 0;
        while (i<5000) {
            // nop
            i +=1;
            var j = pb.*;
        }
    }
}

and compile with

export PATH=/c/zig-windows-x86_64-0.5.0+51cbd9682/:$PATH
zig build-obj --release-small -target avr-freestanding-eabi test-blink.zig

export PATH=/c/projets/2019-Compteur-Facebook/arduino-1.8.9/hardware/tools/avr/bin:$PATH
avr-ld -o main.elf test-blink.o
avr-objcopy -j .text -j .data -O ihex main.elf main.hex

avrdude.exe  -C/c/projets/2019-Compteur-Facebook/arduino-1.8.9/hardware/tools/avr/etc/avrdude.conf -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:main.hex:i

All 13 comments

Arduino is AVR-based, so really it's just a matter of waiting for LLVM's AVR support to stabilize, and adding support to the standard library. In theory, basic language support should already be in place, as long as you don't use the standard library.

The real question then is how to handle stuff like the GPIO on an Arduino - e.g. digitalRead in the Arduino AVR SDK. Similar functionality could probably be added to the standard library under std.os for Arduino.

@pixelherodev What do you mean with "as long as you don't use the standard
library.", I assume the standard zig library?

Op zo 10 nov. 2019 om 01:05 schreef pixelherodev notifications@github.com:

Arduino is AVR-based, so really it's just a matter of waiting for LLVM's
AVR support to stabilize, and adding support to the standard library. In
theory, basic language support should already be in place, as long as you
don't use the standard library.

The real question then is how to handle stuff like the GPIO on an Arduino

  • e.g. digitalRead in the Arduino AVR SDK. Similar functionality could
    probably be added to the standard library under std.os for Arduino.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/ziglang/zig/issues/3637?email_source=notifications&email_token=AAFUKWXUW324SL3LX4JCFPDQS5F3TA5CNFSM4JLJLQE2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDUR74A#issuecomment-552148976,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFUKWRNL3R2YMXARBBWBL3QS5F3TANCNFSM4JLJLQEQ
.

Just to be clear, you can in fact use most of the standard library. But the cross platform OS abstractions lack Arduino support, so it would be a compile error currently to, for example, open a file.

Interesting. I might look into this more later (like 6 months from now).

auduino's digitalRead is mmio so that's pretty trivial. But as I mentioned in #3645, avr-lld support is pretty bad. Thus, for simple code I have done

zig build-obj --release-small --target avr-freestanding-eabi main.zig
avr-ld -o main.elf main.o # This is the gnu linker
llvm-objcopy -j .text -j .data -O binary main.elf main.bin

The need for llvm-objcopy should be removed after #2826

Because of #3645 (and probably other issues) the below example doesn't run with master (as of this writing) but does work with 0.5.0

const SFR=packed struct {
 pin03:u4,
 pin47:u4,
};
const PORTB = 0x38;

export fn main () void{
    var portb=@intToPtr(*volatile SFR,PORTB);
    portb.pin47=15;
    while(true){}
}

This example reads portb, changes upper nibble to 0xF and then writes data back to portb.
You can verify the output by checking the elf file or the final binary file with any disassembler

I should probably write a github wiki page for avr

i had a small time to work on it,
work with :

const PORTBDATA = 0x25;
const PORTBDIR = 0x24;

export fn main () void{
    var pb = @intToPtr(*volatile u8, PORTBDATA);
    var pbd = @intToPtr(*volatile u8, PORTBDIR);
    pbd.* = 0xff;
    while(true){
        pb.* = (1 << 5);
        var i : u32 = 0;
        while (i<5000) {
            // nop
            i +=1;
            var j = pb.*;
        }
        pb.* = 0;
        i = 0;
        while (i<5000) {
            // nop
            i +=1;
            var j = pb.*;
        }
    }
}

and compile with

export PATH=/c/zig-windows-x86_64-0.5.0+51cbd9682/:$PATH
zig build-obj --release-small -target avr-freestanding-eabi test-blink.zig

export PATH=/c/projets/2019-Compteur-Facebook/arduino-1.8.9/hardware/tools/avr/bin:$PATH
avr-ld -o main.elf test-blink.o
avr-objcopy -j .text -j .data -O ihex main.elf main.hex

avrdude.exe  -C/c/projets/2019-Compteur-Facebook/arduino-1.8.9/hardware/tools/avr/etc/avrdude.conf -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:main.hex:i
const PORTBDATA = 0x25;

This could be: const PORTBDATA = @intToPtr(*volatile u8, 0x25); and then you don't need it in your main function.

sure,
sorry, i was so excited to make it work on Uno :-)

So, should standard functionality be implemented in os.arduino? I can definitely do that at some point in the next month if that's desired.

Edit: the other question then is how it should be implemented. os.arduino.digitalRead could be done, but a pin type might also work - e.g.

```zig
const led_pin = os.arduino.digital_pin(3);

export fn main() void {
led_pin.mode(os.arduino.digital_pin.output);
led_pin.write(1);
// do other stuff
}

Arduino is a microcontroller, and pin management permit to handle the hardware directly.

Seems there are different strategies in adding arduino support :

  • create a "bare bone" harware library (arduino.*, for uno, micro ... etc)
  • create a HAL (hardware abstraction layer), to have the same names, for all elements, (generic for common properties like pins .. ), and b able to add specific things also, and ease the port to other microcontrollers
  • integrate a small RT OS (chibi or FreeRT OS) -> much smart, we gain the threading, semaphores .. etc ..

none the less, i like the "pin" object description,
this also can be started simply and refactor as needed, the "bare bone" is the first step to other ones.

i would probably not put it in os. module

make sense ?
any ideas ?

i saw rust has worked also to create a dedicated project for embedded

Creating a "pin" object, leads to create a wrapper, or modify all existing libraries we could reuse.This has to be put into balance.

I don't think the std lib should have things like digtalWrite(1, true) because at the ATmega328 chip level, pin 1 means nothing. The Arduino company has designated that itself. In the future, perhaps there could be an "ArduinoUno" board-specific library which has these things.

Have I overlooked something?

I was not about the std having this functionality. For me it was more if it
was possible or not.

Op do 3 dec. 2020 om 16:32 schreef Ethan Frei notifications@github.com:

I don't think the std lib should have things like digtalWrite(1, true)
because at the ATmega328 chip level, pin 1 means nothing. The Arduino
company has designated that itself. In the future, perhaps there could be
an "ArduinoUno" board-specific library which has these things.

Have I overlooked something?

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/ziglang/zig/issues/3637#issuecomment-738081207, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AAFUKWV3O3RQTXIFA4OGRTDSS6VPJANCNFSM4JLJLQEQ
.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jayschwa picture jayschwa  Â·  3Comments

DavidYKay picture DavidYKay  Â·  3Comments

daurnimator picture daurnimator  Â·  3Comments

andrewrk picture andrewrk  Â·  3Comments

andrewrk picture andrewrk  Â·  3Comments