mirror of
https://git.alemi.dev/pc-monitor.git
synced 2024-11-24 00:14:49 +01:00
build: init project with avr_hal setup and target
Added avr_han project structure with arch definition and cargo config. Remember to switch to nightly! Added a basic initial project, with 4 leds (1 for CPU core). Each led grows in intensity depending on CPU core load. Added a py script to generate cpu load data on serial port.
This commit is contained in:
commit
e400459168
9 changed files with 193 additions and 0 deletions
8
.cargo/config.toml
Normal file
8
.cargo/config.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[build]
|
||||||
|
target = "avr-atmega328p.json"
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "avr")']
|
||||||
|
runner = "ravedude nano --open-console --baudrate 57600 -P /dev/ttyUSB0"
|
||||||
|
|
||||||
|
[unstable]
|
||||||
|
build-std = ["core"]
|
7
.editorconfig
Normal file
7
.editorconfig
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Default to Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 2
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Cargo.lock
|
||||||
|
/target
|
1
.rustfmt.toml
Normal file
1
.rustfmt.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
hard_tabs = true
|
35
Cargo.toml
Normal file
35
Cargo.toml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
[package]
|
||||||
|
name = "pc-monitor"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["alemidev <me@alemi.dev>"]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "pc-monitor"
|
||||||
|
test = false
|
||||||
|
bench = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
panic-halt = "0.2.0"
|
||||||
|
ufmt = "0.1.0"
|
||||||
|
nb = "1"
|
||||||
|
embedded-hal = "0.2.3"
|
||||||
|
embedded-msgpack = "0.2"
|
||||||
|
|
||||||
|
[dependencies.arduino-hal]
|
||||||
|
git = "https://github.com/rahix/avr-hal"
|
||||||
|
rev = "1aacefb335517f85d0de858231e11055d9768cdf"
|
||||||
|
features = ["arduino-nano"]
|
||||||
|
|
||||||
|
# Configure the build for minimal size - AVRs have very little program memory
|
||||||
|
[profile.dev]
|
||||||
|
panic = "abort"
|
||||||
|
lto = true
|
||||||
|
opt-level = "s"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
panic = "abort"
|
||||||
|
codegen-units = 1
|
||||||
|
debug = true
|
||||||
|
lto = true
|
||||||
|
opt-level = "s"
|
25
avr-atmega328p.json
Normal file
25
avr-atmega328p.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"arch": "avr",
|
||||||
|
"atomic-cas": false,
|
||||||
|
"cpu": "atmega328p",
|
||||||
|
"data-layout": "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8",
|
||||||
|
"eh-frame-header": false,
|
||||||
|
"exe-suffix": ".elf",
|
||||||
|
"executables": true,
|
||||||
|
"late-link-args": {
|
||||||
|
"gcc": [
|
||||||
|
"-lgcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"linker": "avr-gcc",
|
||||||
|
"llvm-target": "avr-unknown-unknown",
|
||||||
|
"max-atomic-width": 8,
|
||||||
|
"no-default-libraries": false,
|
||||||
|
"pre-link-args": {
|
||||||
|
"gcc": [
|
||||||
|
"-mmcu=atmega328p"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"target-c-int-width": "16",
|
||||||
|
"target-pointer-width": "16"
|
||||||
|
}
|
22
script/cpu-usage.py
Executable file
22
script/cpu-usage.py
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
from time import sleep
|
||||||
|
import struct
|
||||||
|
import serial
|
||||||
|
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
def avg_usage_to_serial(dev:str):
|
||||||
|
port = serial.Serial(dev, baudrate=57600)
|
||||||
|
while True:
|
||||||
|
# Map float [0:100] to int [0:255], square it to put more values in the lower end, where led is more sensible
|
||||||
|
load = [ int(((x/100) **2) * 255) for x in psutil.cpu_percent(0.1, percpu=True) ] # mypy whines but percpu returns a list
|
||||||
|
port.write(struct.pack("BBBB", *load))
|
||||||
|
port.flush()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("[!] No device specified")
|
||||||
|
else:
|
||||||
|
avg_usage_to_serial(sys.argv[1])
|
||||||
|
|
2
script/requirements.txt
Normal file
2
script/requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
psutil
|
||||||
|
pyserial
|
91
src/main.rs
Normal file
91
src/main.rs
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use panic_halt as _;
|
||||||
|
|
||||||
|
use embedded_hal::serial::Read;
|
||||||
|
|
||||||
|
use arduino_hal::{simple_pwm::*, port::{Pin, mode::{PwmOutput, PullUp, Input}}, hal::port::{PD3, PB1, PB2, PB3, PD2}};
|
||||||
|
|
||||||
|
// TODO can I make it a generic "Pin" and use a slice?
|
||||||
|
struct FourLedDisplay {
|
||||||
|
led1: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||||
|
led2: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||||
|
led3: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||||
|
led4: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||||
|
button: Pin<Input<PullUp>, PD2>,
|
||||||
|
counter: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FourLedDisplay {
|
||||||
|
fn new(
|
||||||
|
led1: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||||
|
led2: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||||
|
led3: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||||
|
led4: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||||
|
button: Pin<Input<PullUp>, PD2>,
|
||||||
|
) -> Self {
|
||||||
|
FourLedDisplay{
|
||||||
|
led1, led2, led3, led4, button,
|
||||||
|
counter: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, value: u8) {
|
||||||
|
match self.counter {
|
||||||
|
0 => self.led1.set_duty(value),
|
||||||
|
1 => self.led2.set_duty(value),
|
||||||
|
2 => self.led3.set_duty(value),
|
||||||
|
3 => self.led4.set_duty(value),
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
self.counter = (self.counter + 1) % 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(mut self) -> Self {
|
||||||
|
self.led1.enable();
|
||||||
|
self.led2.enable();
|
||||||
|
self.led3.enable();
|
||||||
|
self.led4.enable();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn should_reset(&self) -> bool { self.button.is_low() }
|
||||||
|
|
||||||
|
fn reset(&mut self) {
|
||||||
|
self.counter = 0;
|
||||||
|
self.led1.set_duty(0);
|
||||||
|
self.led2.set_duty(0);
|
||||||
|
self.led3.set_duty(0);
|
||||||
|
self.led4.set_duty(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[arduino_hal::entry]
|
||||||
|
fn main() -> ! {
|
||||||
|
// init board peripherals
|
||||||
|
let dp = arduino_hal::Peripherals::take().unwrap();
|
||||||
|
let timer1 = Timer1Pwm::new(dp.TC1, Prescaler::Prescale8);
|
||||||
|
let timer2 = Timer2Pwm::new(dp.TC2, Prescaler::Prescale8);
|
||||||
|
let pins = arduino_hal::pins!(dp);
|
||||||
|
let led1 = pins.d3.into_output().into_pwm(&timer2);
|
||||||
|
let led2 = pins.d9.into_output().into_pwm(&timer1);
|
||||||
|
let led3 = pins.d10.into_output().into_pwm(&timer1);
|
||||||
|
let led4 = pins.d11.into_output().into_pwm(&timer2);
|
||||||
|
let button = pins.d2.into_pull_up_input();
|
||||||
|
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
|
||||||
|
|
||||||
|
// prepare display struct
|
||||||
|
let mut display = FourLedDisplay::new(led1, led2, led3, led4, button).init();
|
||||||
|
|
||||||
|
loop { // main loop
|
||||||
|
if display.should_reset() {
|
||||||
|
display.reset();
|
||||||
|
} else {
|
||||||
|
match serial.read() {
|
||||||
|
Ok(value) => display.update(value),
|
||||||
|
Err(_) => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue