Anvil v1.0.0 -- Arduino build tool with HAL and test scaffolding
Single-binary CLI that scaffolds testable Arduino projects, compiles, uploads, and monitors serial output. Templates embed a hardware abstraction layer, Google Mock infrastructure, and CMake-based host tests so application logic can be verified without hardware. Commands: new, doctor, setup, devices, build, upload, monitor 39 Rust tests (21 unit, 18 integration) Cross-platform: Linux and Windows
This commit is contained in:
67
templates/basic/lib/hal/hal.h
Normal file
67
templates/basic/lib/hal/hal.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef HAL_H
|
||||
#define HAL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Pin modes (match Arduino constants)
|
||||
#ifndef INPUT
|
||||
#define INPUT 0x0
|
||||
#define OUTPUT 0x1
|
||||
#define INPUT_PULLUP 0x2
|
||||
#endif
|
||||
|
||||
#ifndef LOW
|
||||
#define LOW 0x0
|
||||
#define HIGH 0x1
|
||||
#endif
|
||||
|
||||
// LED_BUILTIN for host builds
|
||||
#ifndef LED_BUILTIN
|
||||
#define LED_BUILTIN 13
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hardware Abstraction Layer
|
||||
*
|
||||
* Abstract interface over GPIO, timing, serial, and I2C. Sketch logic
|
||||
* depends on this interface only -- never on Arduino.h directly.
|
||||
*
|
||||
* Two implementations:
|
||||
* hal_arduino.h -- real hardware (included by .ino files)
|
||||
* mock_hal.h -- Google Mock (included by test files)
|
||||
*/
|
||||
class Hal {
|
||||
public:
|
||||
virtual ~Hal() = default;
|
||||
|
||||
// -- GPIO ---------------------------------------------------------------
|
||||
virtual void pinMode(uint8_t pin, uint8_t mode) = 0;
|
||||
virtual void digitalWrite(uint8_t pin, uint8_t value) = 0;
|
||||
virtual uint8_t digitalRead(uint8_t pin) = 0;
|
||||
virtual int analogRead(uint8_t pin) = 0;
|
||||
virtual void analogWrite(uint8_t pin, int value) = 0;
|
||||
|
||||
// -- Timing -------------------------------------------------------------
|
||||
virtual unsigned long millis() = 0;
|
||||
virtual unsigned long micros() = 0;
|
||||
virtual void delay(unsigned long ms) = 0;
|
||||
virtual void delayMicroseconds(unsigned long us) = 0;
|
||||
|
||||
// -- Serial -------------------------------------------------------------
|
||||
virtual void serialBegin(unsigned long baud) = 0;
|
||||
virtual void serialPrint(const char* msg) = 0;
|
||||
virtual void serialPrintln(const char* msg) = 0;
|
||||
virtual int serialAvailable() = 0;
|
||||
virtual int serialRead() = 0;
|
||||
|
||||
// -- I2C ----------------------------------------------------------------
|
||||
virtual void i2cBegin() = 0;
|
||||
virtual void i2cBeginTransmission(uint8_t addr) = 0;
|
||||
virtual size_t i2cWrite(uint8_t data) = 0;
|
||||
virtual uint8_t i2cEndTransmission() = 0;
|
||||
virtual uint8_t i2cRequestFrom(uint8_t addr, uint8_t count) = 0;
|
||||
virtual int i2cAvailable() = 0;
|
||||
virtual int i2cRead() = 0;
|
||||
};
|
||||
|
||||
#endif // HAL_H
|
||||
93
templates/basic/lib/hal/hal_arduino.h
Normal file
93
templates/basic/lib/hal/hal_arduino.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef HAL_ARDUINO_H
|
||||
#define HAL_ARDUINO_H
|
||||
|
||||
/*
|
||||
* Real hardware implementation of the HAL.
|
||||
*
|
||||
* This file includes Arduino.h and Wire.h, so it can only be compiled
|
||||
* by avr-gcc (via arduino-cli). It is included by .ino files only.
|
||||
*
|
||||
* Every method is a trivial passthrough to the real Arduino function.
|
||||
* The point is not to add logic here -- it is to keep Arduino.h out
|
||||
* of your application code so that code can compile on the host.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
#include <hal.h>
|
||||
|
||||
class ArduinoHal : public Hal {
|
||||
public:
|
||||
// -- GPIO ---------------------------------------------------------------
|
||||
void pinMode(uint8_t pin, uint8_t mode) override {
|
||||
::pinMode(pin, mode);
|
||||
}
|
||||
void digitalWrite(uint8_t pin, uint8_t value) override {
|
||||
::digitalWrite(pin, value);
|
||||
}
|
||||
uint8_t digitalRead(uint8_t pin) override {
|
||||
return ::digitalRead(pin);
|
||||
}
|
||||
int analogRead(uint8_t pin) override {
|
||||
return ::analogRead(pin);
|
||||
}
|
||||
void analogWrite(uint8_t pin, int value) override {
|
||||
::analogWrite(pin, value);
|
||||
}
|
||||
|
||||
// -- Timing -------------------------------------------------------------
|
||||
unsigned long millis() override {
|
||||
return ::millis();
|
||||
}
|
||||
unsigned long micros() override {
|
||||
return ::micros();
|
||||
}
|
||||
void delay(unsigned long ms) override {
|
||||
::delay(ms);
|
||||
}
|
||||
void delayMicroseconds(unsigned long us) override {
|
||||
::delayMicroseconds(us);
|
||||
}
|
||||
|
||||
// -- Serial -------------------------------------------------------------
|
||||
void serialBegin(unsigned long baud) override {
|
||||
Serial.begin(baud);
|
||||
}
|
||||
void serialPrint(const char* msg) override {
|
||||
Serial.print(msg);
|
||||
}
|
||||
void serialPrintln(const char* msg) override {
|
||||
Serial.println(msg);
|
||||
}
|
||||
int serialAvailable() override {
|
||||
return Serial.available();
|
||||
}
|
||||
int serialRead() override {
|
||||
return Serial.read();
|
||||
}
|
||||
|
||||
// -- I2C ----------------------------------------------------------------
|
||||
void i2cBegin() override {
|
||||
Wire.begin();
|
||||
}
|
||||
void i2cBeginTransmission(uint8_t addr) override {
|
||||
Wire.beginTransmission(addr);
|
||||
}
|
||||
size_t i2cWrite(uint8_t data) override {
|
||||
return Wire.write(data);
|
||||
}
|
||||
uint8_t i2cEndTransmission() override {
|
||||
return Wire.endTransmission();
|
||||
}
|
||||
uint8_t i2cRequestFrom(uint8_t addr, uint8_t count) override {
|
||||
return Wire.requestFrom(addr, count);
|
||||
}
|
||||
int i2cAvailable() override {
|
||||
return Wire.available();
|
||||
}
|
||||
int i2cRead() override {
|
||||
return Wire.read();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // HAL_ARDUINO_H
|
||||
Reference in New Issue
Block a user