From fc1fedf890258976d613dd05131b300285f70ca9 Mon Sep 17 00:00:00 2001 From: occheung Date: Fri, 18 Dec 2020 17:46:56 +0800 Subject: [PATCH] main: incoporate alloc, tls, and flash --- src/main.rs | 144 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 100 insertions(+), 44 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0b8df43..49c5134 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,23 +2,30 @@ #![no_std] #![feature(core_intrinsics)] #![feature(assoc_char_funcs)] +#![feature(alloc_error_handler)] use log::{ trace, warn }; use stm32h7xx_hal::gpio::Speed; +use stm32h7xx_hal::rng::Rng; use stm32h7xx_hal::{pac, prelude::*, spi}; use stm32h7xx_hal::ethernet; use smoltcp as net; -use minimq::{ - embedded_nal::IpAddr, - MqttClient, QoS -}; +use smoltcp_tls as tls; + +use minimq::{ MqttClient, QoS }; use cortex_m; use cortex_m_rt::entry; +use alloc_cortex_m::CortexMHeap; use rtic::cyccnt::{Instant, U32Ext}; +use rand_core::{RngCore, CryptoRng}; +use tls::TlsRng; +use tls::tls::TlsSocket; +use tls::tcp_stack::NetworkStack; use heapless::{ String, consts, consts::* }; +use core::alloc::Layout; #[macro_use] pub mod bitmask_macro; @@ -28,8 +35,8 @@ use crate::cpld::CPLD; pub mod config_register; pub mod attenuator; pub mod dds; -pub mod nal_tcp_client; -use crate::nal_tcp_client::{ NetStorage, NetworkStack }; +pub mod net_store; +use crate::net_store::NetStorage; pub mod fpga; use crate::fpga::flash_ice40_fpga; pub mod mqtt_mux; @@ -37,10 +44,22 @@ use crate::mqtt_mux::MqttMux; pub mod urukul; use crate::urukul::Urukul; pub mod flash; -use crate::flash::read_flash; +pub mod config; +use crate::config::get_net_config; +pub mod flash_store; +use crate::flash_store::init_flash; mod logger; +#[global_allocator] +static ALLOCATOR: CortexMHeap = CortexMHeap::empty(); + +#[alloc_error_handler] +fn oom(_: Layout) -> ! { + warn!("Out of memory!"); + loop {} +} + static mut NET_STORE: NetStorage = NetStorage { // Placeholder for the real IP address, which is initialized at runtime. ip_addrs: [net::wire::IpCidr::Ipv6( @@ -53,25 +72,40 @@ static mut NET_STORE: NetStorage = NetStorage { #[link_section = ".sram3.eth"] static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new(); -macro_rules! add_socket { - ($sockets:ident, $tx_storage:ident, $rx_storage:ident) => { - let mut $rx_storage = [0; 4096]; - let mut $tx_storage = [0; 4096]; - - let tcp_socket = { - let tx_buffer = net::socket::TcpSocketBuffer::new(&mut $tx_storage[..]); - let rx_buffer = net::socket::TcpSocketBuffer::new(&mut $rx_storage[..]); - - net::socket::TcpSocket::new(tx_buffer, rx_buffer) - }; - - let _handle = $sockets.add(tcp_socket); - }; +struct RngStruct { + rng: Rng } +impl RngCore for RngStruct { + fn next_u32(&mut self) -> u32 { + self.rng.gen().unwrap() + } + + fn next_u64(&mut self) -> u64 { + (u64::from(self.next_u32()) << 32) | u64::from(self.next_u32()) + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + self.rng.fill(dest).unwrap(); + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> { + Ok(self.fill_bytes(dest)) + } +} + +impl CryptoRng for RngStruct {} + +impl TlsRng for RngStruct {} + #[entry] fn main() -> ! { + // Initialize the allocator BEFORE you use it + let start = cortex_m_rt::heap_start() as usize; + let size = 32768; // in bytes + unsafe { ALLOCATOR.init(start, size) } + let mut cp = cortex_m::Peripherals::take().unwrap(); let dp = pac::Peripherals::take().unwrap(); @@ -104,12 +138,17 @@ fn main() -> ! { cp.DWT.enable_cycle_counter(); - // Acquire client/broker IP Address, client MAC address from flash memory - let (ipv4_addr_cidr, mac_addr, broker_ipv4_addr, device_name) = { - let mut addr = 0x08100000; - read_flash(&mut addr) + // Instantiate random number generator + let mut rng = RngStruct { + rng: dp.RNG.constrain(ccdr.peripheral.RNG, &ccdr.clocks) }; + // Create sfkv store and flash storage manager + let (flash, mut flash_store) = init_flash(dp.FLASH); + + // Acquire client/broker IP Address, client MAC address from flash memory + let net_config = get_net_config(&mut flash_store); + let gpioa = dp.GPIOA.split(ccdr.peripheral.GPIOA); let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB); let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC); @@ -168,7 +207,7 @@ fn main() -> ! { dp.ETHERNET_MTL, dp.ETHERNET_DMA, &mut DES_RING, - mac_addr.clone(), + net_config.eth_addr.clone(), ) }; @@ -176,7 +215,7 @@ fn main() -> ! { let store = unsafe { &mut NET_STORE }; - store.ip_addrs[0] = ipv4_addr_cidr; + store.ip_addrs[0] = net_config.ip_cidr; let neighbor_cache = net::iface::NeighborCache::new(&mut store.neighbor_cache[..]); @@ -185,7 +224,7 @@ fn main() -> ! { routes.add_default_ipv4_route(default_v4_gw).unwrap(); let mut net_interface = net::iface::EthernetInterfaceBuilder::new(eth_dma) - .ethernet_addr(mac_addr) + .ethernet_addr(net_config.eth_addr) .neighbor_cache(neighbor_cache) .ip_addrs(&mut store.ip_addrs[..]) .routes(routes) @@ -223,12 +262,11 @@ fn main() -> ! { let switch = CPLD::new(spi, (cs0, cs1, cs2), io_update); let parts = switch.split(); - let mut urukul = Urukul::new( + let urukul = Urukul::new( parts.spi1, parts.spi2, parts.spi3, parts.spi4, parts.spi5, parts.spi6, parts.spi7 - ); - urukul.reset().unwrap(); + ); - let mut mqtt_mux = MqttMux::new(urukul, device_name.as_str()); + let mut mqtt_mux = MqttMux::new(urukul, flash, flash_store, net_config.name.as_str()); // Time unit in ms let mut time: u32 = 0; @@ -238,16 +276,35 @@ fn main() -> ! { let mut next_ms = Instant::now(); next_ms += 400_000.cycles(); - let mut socket_set_entries: [_; 8] = Default::default(); - let mut sockets = net::socket::SocketSet::new(&mut socket_set_entries[..]); - add_socket!(sockets, rx_storage, tx_storage); + let mut tls_socket_entries: [_; 1] = Default::default(); + let mut tls_socket_set = smoltcp_tls::set::TlsSocketSet::new( + &mut tls_socket_entries[..] + ); - let tcp_stack = NetworkStack::new(&mut net_interface, sockets); + let mut tx_storage = [0; 4096]; + let mut rx_storage = [0; 4096]; + let tx_buffer = net::socket::TcpSocketBuffer::new(&mut tx_storage[..]); + let rx_buffer = net::socket::TcpSocketBuffer::new(&mut rx_storage[..]); + let mut tcp_socket = net::socket::TcpSocket::new(rx_buffer, tx_buffer); + tcp_socket.set_keep_alive( + Some(net::time::Duration::from_secs(2)) + ); + + let tls_socket = TlsSocket::new( + tcp_socket, + &mut rng, + None + ); + let _ = tls_socket_set.add(tls_socket); + + let tls_stack = NetworkStack::new( + tls_socket_set + ); let mut client = MqttClient::::new( - IpAddr::V4(broker_ipv4_addr), - device_name.as_str(), - tcp_stack, + net_config.broker_ip, + net_config.name.as_str(), + tls_stack, ) .unwrap(); @@ -265,9 +322,8 @@ fn main() -> ! { // eth Poll if necessary // Do not poll if eth link is down - if tick && client.network_stack.update_delay(time) == 0 && eth_mac.phy_poll_link() { - client.network_stack.update(time); - } + while !eth_mac.phy_poll_link() {} + client.network_stack.poll(&mut net_interface, net::time::Instant::from_millis(time)); // Process MQTT messages about Urukul/Control let connection = match client @@ -277,7 +333,7 @@ fn main() -> ! { }) { Ok(_) => true, Err(e) => { - warn!("{:?}", e); + log::info!("Warn: {:?}", e); false }, }; @@ -293,7 +349,7 @@ fn main() -> ! { } if connection && !has_subscribed && tick { - let mut str_builder: String = String::from(device_name.as_str()); + let mut str_builder: String = String::from(net_config.name.as_str()); str_builder.push_str("/Control/#").unwrap(); match client.subscribe(str_builder.as_str(), &[]) { Ok(()) => has_subscribed = true,