Project update 6 of 9
In this update, we’ll describe the Open-V microcontroller’s Arduino compatibility, what it took to get there, and what it means for our backers.
Arduino compatibility can mean a lot of things to a lot of different people, so we’ll try to be as concrete and specific as possible. For the Open-V, Arduino compatibility encompasses standard firmware libraries, a bootloader, development tools, and interoperating on a hardware level with existing Arduino shields.
We’ve ported the standard Arduino library to the Open-V microcontroller. This involved customizing the library both for the Open-V CPU and the Open-V peripherals. The complete code is available on GitHub.
An Open-V port of the Arduino library means people familiar with other Arduino boards can use the Open-V dev board just as they would normally use any other Arduino, without knowing anything in particular about the internal workings of the Open-V microcontroller.
Part of the porting process involved writing in RISC-V assembler an initialization routine to support interrupts and function calls from C. There are also the calls to the Arduino-specific setup()
and loop()
routines:
addi x28, zero, 0
addi x29, zero, 0
addi x30, zero, 0
addi x31, zero, 0
/* set stack pointer */
li sp,4*1024
/* set gp and tp */
lui gp, %hi(0xdeadbeef)
addi gp, gp, %lo(0xdeadbeef)
addi tp, gp, 0
jal ra,main; # call to main
j reset_vec;
Basically, we follow a similar methodology used by Atmel and vendors who provide Arduino-supported microcontrollers.
Most Arduino functions are supported. Each Arduino function has been rewritten to support the Open-V microcontroller. As an example, here is the digitalWrite() function from the Wiring library, rewritten for the Open-V:
// Pin protections are hw-based
int modes = 0;
/* wiring_digital.c */
void digitalWrite(uint32_t pin, uint32_t val)
{
if(pin >= OPENV_MAX_PINS) return;
if(!bitRead(modes, pin)) return;
*(ADDR_GPIO+pin) = ((uint32_t)val | 0x2);
}
Some functions are not yet supported in the Open-V port of the Arduino library: tone()
, notone()
, analogWrite()
, attachInterrupt()
, detachInterrupt()
, interrupts()
, noInterrupts()
, and the Serial
, Stream
, and USB
functions. While it’s possible to port these functions, doing so would require using a lot of code space, which wouldn’t leave much for end user programs. This might change as we migrate to the E31 core.
We’ve written an Arduino compatible bootloader for the Open-V dev board. This means you can load compiled code into the Open-V dev board’s flash memory via a serial connection, as you would normally do with any other Arduino board. The bootloader source code is posted in the same repo as the library code.
With Open-V versions of the Arduino library and bootloader in place, the Open-V dev board can be used with any Arduino dev tools, such as the Arduino IDE. All you have to do is install the Open-V port of the library as you would for any other Arduino board and you’ll be writing code in no time. For instance, the following program blinks the LED at pin 0:
void setup()
{
pinMode(0, OUTPUT);
}
void loop()
{
delay(500);
digitalWrite(0, HIGH);
delay(500);
digitalWrite(0, LOW);
}
In addition to compatibility with the Arduino software and firmware ecosystem, we’ve designed the Open-V dev board to be compatible with the Arduino hardware ecosystem as well. This means that the layout and pinout of the Open-V dev board is such that it can interface with most standard Arduino shields and shields that work with the Arduino Uno board.
We’ve updated our live, web-streamed demos to include an Arduino mode in addition to the assembler and C modes we already have. You might also notice the relatively new Blockly modes and a refined layout of the demo page. Go write some code and see the results live streamed!