micropb for rust - initial
This commit is contained in:
parent
007e793ded
commit
aae8f12a56
@ -32,6 +32,13 @@ embedded-alloc = "0.6.0"
|
||||
# data structures
|
||||
ringbuffer = { version = "0.15.0", features = [] }
|
||||
|
||||
#Protobuf
|
||||
micropb = {version = "=0.1.0", features = ["alloc"]}
|
||||
|
||||
[build-dependencies]
|
||||
# Allow types from `heapless` to be used for container fields
|
||||
micropb-gen = { version = "0.1.0"}
|
||||
|
||||
[[bin]]
|
||||
name = "MRTIC"
|
||||
test = false
|
||||
|
8
build.rs
8
build.rs
@ -40,4 +40,12 @@ fn main() {
|
||||
|
||||
// Set the linker script to the one provided by cortex-m-rt.
|
||||
println!("cargo:rustc-link-arg=-Tlink.x");
|
||||
|
||||
|
||||
let mut gen = micropb_gen::Generator::new();
|
||||
gen. use_container_alloc();
|
||||
// Compile example.proto into a Rust module
|
||||
gen.compile_protos(&["src/proto/meta.proto"], std::env::var("OUT_DIR").unwrap() + "/meta.rs").unwrap();
|
||||
|
||||
|
||||
}
|
||||
|
92
src/main.rs
92
src/main.rs
@ -10,29 +10,37 @@ fn panic() -> ! {
|
||||
cortex_m::asm::udf()
|
||||
}
|
||||
|
||||
|
||||
mod proto {
|
||||
#![allow(clippy::all)]
|
||||
#![allow(nonstandard_style, unused, irrefutable_let_patterns)]
|
||||
include!(concat!(env!("OUT_DIR"), "/meta.rs"));
|
||||
}
|
||||
//use proto::space_::kscience_::dataforge_::io_::proto_::ProtoMeta_;
|
||||
use proto::space_::kscience_::dataforge_::io_::proto_::ProtoMeta_::ProtoValue_::*;
|
||||
//use proto::example_package_::*;
|
||||
#[rtic::app(device = stm32f7xx_hal::pac, peripherals = true, dispatchers = [EXTI0])]
|
||||
mod app {
|
||||
|
||||
|
||||
use proto::space_::kscience_::dataforge_::io_::proto_::ProtoMeta;
|
||||
use shared_resources::message_buffer_that_needs_to_be_locked;
|
||||
//Declare Parameters
|
||||
use core::fmt::Write;
|
||||
|
||||
systick_monotonic!(Mono, 1000);
|
||||
|
||||
use stm32f7xx_hal::{
|
||||
gpio::{GpioExt, Output, PushPull, PI1},
|
||||
pac::{Interrupt, USART1},
|
||||
prelude::*,
|
||||
rcc::RccExt,
|
||||
serial::{self, Config, Event, Rx, Serial, Tx}
|
||||
serial::{Config, Event, Rx, Serial, Tx}
|
||||
};
|
||||
|
||||
use super::*;
|
||||
use core::{fmt::Write, mem::size_of};
|
||||
use rtic_monotonics::systick::prelude::*;
|
||||
|
||||
|
||||
use alloc::string::String;
|
||||
use embedded_alloc::LlffHeap as Heap;
|
||||
use ringbuffer::{AllocRingBuffer, RingBuffer};
|
||||
use micropb::{PbRead, PbEncoder, PbDecoder, MessageDecode, MessageEncode};
|
||||
|
||||
use alloc::string::String;
|
||||
use alloc::vec::Vec;
|
||||
systick_monotonic!(Mono, 1000);
|
||||
|
||||
#[global_allocator]
|
||||
static HEAP: Heap = Heap::empty();
|
||||
@ -55,22 +63,18 @@ mod app {
|
||||
fn init(ctx: init::Context) -> (Shared, Local) {
|
||||
|
||||
//Allocator
|
||||
|
||||
{
|
||||
{
|
||||
use core::mem::MaybeUninit;
|
||||
const HEAP_SIZE: usize = 2048;
|
||||
static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
|
||||
unsafe { HEAP.init(HEAP_MEM.as_ptr() as usize, HEAP_SIZE) }
|
||||
}
|
||||
|
||||
rtic::pend(Interrupt::UART4);
|
||||
}
|
||||
|
||||
// Cortex-M peripherals
|
||||
let rcc = ctx.device.RCC.constrain();
|
||||
let clocks = rcc.cfgr.sysclk(48.MHz()).freeze();
|
||||
|
||||
//Systick
|
||||
|
||||
Mono::start(ctx.core.SYST, 36_000_000);
|
||||
|
||||
//GPIO
|
||||
@ -78,7 +82,6 @@ mod app {
|
||||
let GPIOA = ctx.device.GPIOA.split();
|
||||
let GPIOB = ctx.device.GPIOB.split();
|
||||
|
||||
|
||||
//UART
|
||||
let usart1_tx = GPIOA.pa9.into_alternate();
|
||||
let usart1_rx = GPIOB.pb7.into_alternate();
|
||||
@ -110,7 +113,13 @@ mod app {
|
||||
//TASKS
|
||||
blinker::spawn().ok();
|
||||
//serial_task::spawn().ok();
|
||||
proto_task::spawn().ok();
|
||||
let mut stream: Vec<u8> = Vec::new();
|
||||
// let mut decoder = PbDecoder::new(stream.as_slice());
|
||||
// let mut meta_out: ProtoMeta = Default::default();
|
||||
// meta_out.decode_len_delimited(&mut decoder);
|
||||
|
||||
|
||||
defmt::info!("INITED");
|
||||
(
|
||||
|
||||
@ -175,15 +184,52 @@ mod app {
|
||||
fn usart1_handler(ctx: usart1_handler::Context){
|
||||
|
||||
let serial = ctx.local.rx_vcp;
|
||||
let mut message_buffer = ctx.shared.message_buffer;
|
||||
|
||||
|
||||
defmt::trace!("RX not empty");
|
||||
|
||||
if let Ok(byte) = serial.read() {
|
||||
defmt::debug!("RX Byte value: {=u8:x}", byte);
|
||||
}
|
||||
if let Ok(byte) = serial.read() {
|
||||
message_buffer.lock(|buf| {
|
||||
buf.push(byte);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[task(shared = [message_buffer], priority = 1)]
|
||||
async fn proto_task(ctx: proto_task::Context)
|
||||
{
|
||||
let mut message_buffer = ctx.shared.message_buffer;
|
||||
let mut buffer = Vec::new();
|
||||
|
||||
let mut meta_out:ProtoMeta = Default::default();
|
||||
|
||||
loop{
|
||||
let mut is_empty = false;
|
||||
|
||||
message_buffer.lock(|buf| {
|
||||
if buf.is_empty() {
|
||||
is_empty = true;
|
||||
} else {
|
||||
defmt::info!("DATA!");
|
||||
while let Some(byte) = buf.dequeue() {
|
||||
buffer.push(byte);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if is_empty {
|
||||
// Sleep for a while if the buffer is empty
|
||||
Mono::delay(5000.millis()).await;
|
||||
defmt::trace!("await for data");
|
||||
continue;
|
||||
}
|
||||
let mut decoder = PbDecoder::new(buffer.as_slice());
|
||||
if let Ok(message) = meta_out.decode_len_delimited(&mut decoder) {
|
||||
defmt::info!("Received message: {:?}", message);
|
||||
} else {
|
||||
defmt::info!("Failed to parse message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//APP ENDS
|
||||
}
|
||||
|
17
src/proto/example.proto
Normal file
17
src/proto/example.proto
Normal file
@ -0,0 +1,17 @@
|
||||
syntax = "proto3";
|
||||
package example_package;
|
||||
message Example {
|
||||
int32 f_int32 = 1;
|
||||
int64 f_int64 = 2;
|
||||
uint32 f_uint32 = 3;
|
||||
uint64 f_uint64 = 4;
|
||||
sint32 f_sint32 = 5;
|
||||
sint64 f_sint64 = 6;
|
||||
bool f_bool = 7;
|
||||
fixed32 f_fixed32 = 8;
|
||||
fixed64 f_fixed64 = 9;
|
||||
sfixed32 f_sfixed32 = 10;
|
||||
sfixed64 f_sfixed64 = 11;
|
||||
float f_float = 12;
|
||||
double f_double = 13;
|
||||
}
|
30
src/proto/meta.proto
Normal file
30
src/proto/meta.proto
Normal file
@ -0,0 +1,30 @@
|
||||
syntax = "proto3";
|
||||
package space.kscience.dataforge.io.proto;
|
||||
|
||||
message ProtoMeta {
|
||||
message ProtoValue {
|
||||
oneof value {
|
||||
string stringValue = 2;
|
||||
bool booleanValue = 3;
|
||||
double doubleValue = 4;
|
||||
float floatValue = 5;
|
||||
int32 int32Value = 6;
|
||||
int64 int64Value = 7;
|
||||
bytes bytesValue = 8;
|
||||
ProtoValueList listValue = 9;
|
||||
Float64List float64ListValue = 10;
|
||||
}
|
||||
}
|
||||
|
||||
message ProtoValueList{
|
||||
repeated ProtoValue values = 1;
|
||||
}
|
||||
|
||||
message Float64List{
|
||||
repeated double values = 1 [packed=true];
|
||||
}
|
||||
|
||||
ProtoValue protoValue = 1;
|
||||
|
||||
map<string, ProtoMeta> items = 2;
|
||||
}
|
48
src/proto/meta_pb2.py
Normal file
48
src/proto/meta_pb2.py
Normal file
@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# NO CHECKED-IN PROTOBUF GENCODE
|
||||
# source: meta.proto
|
||||
# Protobuf Python Version: 5.27.0-rc3
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import runtime_version as _runtime_version
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
_runtime_version.ValidateProtobufRuntimeVersion(
|
||||
_runtime_version.Domain.PUBLIC,
|
||||
5,
|
||||
27,
|
||||
0,
|
||||
'-rc3',
|
||||
'meta.proto'
|
||||
)
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nmeta.proto\x12!space.kscience.dataforge.io.proto\"\xd8\x05\n\tProtoMeta\x12K\n\nprotoValue\x18\x01 \x01(\x0b\x32\x37.space.kscience.dataforge.io.proto.ProtoMeta.ProtoValue\x12\x46\n\x05items\x18\x02 \x03(\x0b\x32\x37.space.kscience.dataforge.io.proto.ProtoMeta.ItemsEntry\x1a\xdb\x02\n\nProtoValue\x12\x15\n\x0bstringValue\x18\x02 \x01(\tH\x00\x12\x16\n\x0c\x62ooleanValue\x18\x03 \x01(\x08H\x00\x12\x15\n\x0b\x64oubleValue\x18\x04 \x01(\x01H\x00\x12\x14\n\nfloatValue\x18\x05 \x01(\x02H\x00\x12\x14\n\nint32Value\x18\x06 \x01(\x05H\x00\x12\x14\n\nint64Value\x18\x07 \x01(\x03H\x00\x12\x14\n\nbytesValue\x18\x08 \x01(\x0cH\x00\x12P\n\tlistValue\x18\t \x01(\x0b\x32;.space.kscience.dataforge.io.proto.ProtoMeta.ProtoValueListH\x00\x12T\n\x10\x66loat64ListValue\x18\n \x01(\x0b\x32\x38.space.kscience.dataforge.io.proto.ProtoMeta.Float64ListH\x00\x42\x07\n\x05value\x1aY\n\x0eProtoValueList\x12G\n\x06values\x18\x01 \x03(\x0b\x32\x37.space.kscience.dataforge.io.proto.ProtoMeta.ProtoValue\x1a!\n\x0b\x46loat64List\x12\x12\n\x06values\x18\x01 \x03(\x01\x42\x02\x10\x01\x1aZ\n\nItemsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12;\n\x05value\x18\x02 \x01(\x0b\x32,.space.kscience.dataforge.io.proto.ProtoMeta:\x02\x38\x01\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meta_pb2', _globals)
|
||||
if not _descriptor._USE_C_DESCRIPTORS:
|
||||
DESCRIPTOR._loaded_options = None
|
||||
_globals['_PROTOMETA_FLOAT64LIST'].fields_by_name['values']._loaded_options = None
|
||||
_globals['_PROTOMETA_FLOAT64LIST'].fields_by_name['values']._serialized_options = b'\020\001'
|
||||
_globals['_PROTOMETA_ITEMSENTRY']._loaded_options = None
|
||||
_globals['_PROTOMETA_ITEMSENTRY']._serialized_options = b'8\001'
|
||||
_globals['_PROTOMETA']._serialized_start=50
|
||||
_globals['_PROTOMETA']._serialized_end=778
|
||||
_globals['_PROTOMETA_PROTOVALUE']._serialized_start=213
|
||||
_globals['_PROTOMETA_PROTOVALUE']._serialized_end=560
|
||||
_globals['_PROTOMETA_PROTOVALUELIST']._serialized_start=562
|
||||
_globals['_PROTOMETA_PROTOVALUELIST']._serialized_end=651
|
||||
_globals['_PROTOMETA_FLOAT64LIST']._serialized_start=653
|
||||
_globals['_PROTOMETA_FLOAT64LIST']._serialized_end=686
|
||||
_globals['_PROTOMETA_ITEMSENTRY']._serialized_start=688
|
||||
_globals['_PROTOMETA_ITEMSENTRY']._serialized_end=778
|
||||
# @@protoc_insertion_point(module_scope)
|
30
src/proto/simplified_quat.py
Normal file
30
src/proto/simplified_quat.py
Normal file
@ -0,0 +1,30 @@
|
||||
import serial
|
||||
import numpy as np
|
||||
import meta_pb2
|
||||
|
||||
# Create the Protobuf message
|
||||
quaternion = meta_pb2.ProtoMeta(
|
||||
protoValue=None,
|
||||
items={
|
||||
'quaternion': meta_pb2.ProtoMeta(
|
||||
protoValue=meta_pb2.ProtoMeta.ProtoValue(
|
||||
listValue=meta_pb2.ProtoMeta.ProtoValueList(
|
||||
values=[
|
||||
meta_pb2.ProtoMeta.ProtoValue(floatValue=np.float32(1.0)),
|
||||
meta_pb2.ProtoMeta.ProtoValue(floatValue=np.float32(0.0)),
|
||||
meta_pb2.ProtoMeta.ProtoValue(floatValue=np.float32(0.0)),
|
||||
meta_pb2.ProtoMeta.ProtoValue(floatValue=np.float32(0.0))
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
# Serialize the message
|
||||
serialized_message = quaternion.SerializeToString()
|
||||
|
||||
# Send the serialized message over COM3
|
||||
with serial.Serial('COM3', 9600, timeout=1) as ser:
|
||||
ser.write(serialized_message)
|
||||
print("Message sent over COM3")
|
Loading…
x
Reference in New Issue
Block a user