Skip to content

Commit

Permalink
UDP works as well
Browse files Browse the repository at this point in the history
  • Loading branch information
robamu committed May 21, 2024
1 parent 8dc7e7a commit 4ee22ef
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 10 deletions.
2 changes: 2 additions & 0 deletions embedded-examples/stm32h7-rtic/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion embedded-examples/stm32h7-rtic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ stm32h7xx-hal = { version="0.16", features= ["stm32h743v", "ethernet"] }
[dependencies.smoltcp]
version = "0.11.0"
default-features = false
features = ["medium-ethernet", "proto-ipv4", "socket-raw", "socket-dhcpv4"]
features = ["medium-ethernet", "proto-ipv4", "socket-raw", "socket-dhcpv4", "socket-udp", "defmt"]

[dependencies.rtic]
version = "2"
Expand Down
115 changes: 106 additions & 9 deletions embedded-examples/stm32h7-rtic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
use rtic::app;
use rtic_monotonics::systick::Systick;
use rtic_monotonics::Monotonic;
use satrs_stm32h7_nucleo_rtic as _; // global logger + panicking-behavior + memory layout
use satrs_stm32h7_nucleo_rtic as _;
use smoltcp::socket::{dhcpv4, udp}; // global logger + panicking-behavior + memory layout

use core::mem::MaybeUninit;
use smoltcp::iface::{Config, Interface, SocketSet, SocketStorage};
use smoltcp::time::Instant;
use smoltcp::iface::{Config, Interface, SocketHandle, SocketSet, SocketStorage};
use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr};
use stm32h7xx_hal::ethernet;

const DEFAULT_BLINK_FREQ_MS: u32 = 1000;
const PORT: u16 = 7301;

/// Ethernet descriptor rings are a global singleton
#[link_section = ".sram3.eth"]
Expand All @@ -26,35 +27,60 @@ pub struct NetStorageStatic<'a> {
// initialised by the runtime
static mut STORE: MaybeUninit<NetStorageStatic> = MaybeUninit::uninit();

static mut UDP_RX_META: [udp::PacketMetadata; 4] = [udp::PacketMetadata::EMPTY; 4];
static mut UDP_RX: [u8; 2048] = [0; 2048];
static mut UDP_TX_META: [udp::PacketMetadata; 4] = [udp::PacketMetadata::EMPTY; 4];
static mut UDP_TX: [u8; 2048] = [0; 2048];

/// Locally administered MAC address
const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];

pub struct Net<'a> {
iface: Interface,
ethdev: ethernet::EthernetDMA<4, 4>,
sockets: SocketSet<'a>,
dhcp_handle: SocketHandle,
udp_handle: SocketHandle,
}

impl<'a> Net<'a> {
pub fn new(
store: &'a mut NetStorageStatic<'a>,
mut ethdev: ethernet::EthernetDMA<4, 4>,
ethernet_addr: HardwareAddress,
now: Instant,
) -> Self {
let config = Config::new(ethernet_addr);
let mut iface = Interface::new(config, &mut ethdev, now);
// Set IP address
let mut iface = Interface::new(
config,
&mut ethdev,
smoltcp::time::Instant::from_millis((Systick::now() - Systick::ZERO).to_millis()),
);
let udp_rx_buffer =
smoltcp::socket::udp::PacketBuffer::new(unsafe { &mut UDP_RX_META[..] }, unsafe {
&mut UDP_RX[..]
});
let udp_tx_buffer =
smoltcp::socket::udp::PacketBuffer::new(unsafe { &mut UDP_TX_META[..] }, unsafe {
&mut UDP_TX[..]
});
let udp_socket = smoltcp::socket::udp::Socket::new(udp_rx_buffer, udp_tx_buffer);

// Create sockets
let dhcp_socket = dhcpv4::Socket::new();

iface.update_ip_addrs(|addrs| {
let _ = addrs.push(IpCidr::new(IpAddress::v4(192, 168, 1, 99), 0));
});

let sockets = SocketSet::new(&mut store.socket_storage[..]);

let mut sockets = SocketSet::new(&mut store.socket_storage[..]);
let dhcp_handle = sockets.add(dhcp_socket);
let udp_handle = sockets.add(udp_socket);
Net::<'a> {
iface,
ethdev,
sockets,
dhcp_handle,
udp_handle,
}
}

Expand All @@ -67,6 +93,73 @@ impl<'a> Net<'a> {
self.iface
.poll(timestamp, &mut self.ethdev, &mut self.sockets)
}

pub fn poll_dhcp(&mut self) -> Option<dhcpv4::Event> {
let opt_event = self
.sockets
.get_mut::<dhcpv4::Socket>(self.dhcp_handle)
.poll();
if let Some(event) = &opt_event {
match event {
dhcpv4::Event::Deconfigured => {
defmt::info!("DHCP lost configuration");
self.iface.update_ip_addrs(|addrs| addrs.clear());
self.iface.routes_mut().remove_default_ipv4_route();
}
dhcpv4::Event::Configured(config) => {
defmt::info!("DHCP configuration acquired");
defmt::info!("IP address: {}", config.address);
self.iface.update_ip_addrs(|addrs| {
addrs.clear();
addrs.push(IpCidr::Ipv4(config.address)).unwrap();
});

if let Some(router) = config.router {
defmt::debug!("Default gateway: {}", router);
self.iface
.routes_mut()
.add_default_ipv4_route(router)
.unwrap();
} else {
defmt::debug!("Default gateway: None");
self.iface.routes_mut().remove_default_ipv4_route();
}
}
}
}
opt_event
}

pub fn poll_udp(&mut self) {
let socket = self.sockets.get_mut::<udp::Socket>(self.udp_handle);
if !socket.is_open() {
if let Err(e) = socket.bind(PORT) {
defmt::warn!("binding UDP socket failed");
}
}
loop {
match socket.recv() {
Ok((data, client)) => {
/*defmt::info!("UDP: rx {} bytes from {}", data.len(), endpoint);
if let Ok(recv_str) = str::from_utf8(data) {
defmt::info!("recv: {}", recv_str);
}
*/
// TODO: Implement packet wiretapping.
// TODO: Store last endpoint.
// TODO: Send packet to PUS/CCSDS distributor via message queue.
}
Err(e) => match e {
udp::RecvError::Exhausted => {
break;
}
udp::RecvError::Truncated => {
defmt::warn!("UDP packet was truncacted");
}
},
};
}
}
}

#[app(device = stm32h7xx_hal::stm32, peripherals = true)]
Expand Down Expand Up @@ -205,7 +298,7 @@ mod app {
STORE.assume_init_mut()
};

let net = Net::new(store, eth_dma, mac_addr.into(), Instant::ZERO);
let net = Net::new(store, eth_dma, mac_addr.into());

eth_link_check::spawn().expect("eth link check failed");
blink::spawn().expect("spawning blink task failed");
Expand Down Expand Up @@ -261,6 +354,10 @@ mod app {
unsafe {
ethernet::interrupt_handler();
}
// TODO: I am not fully sure whether we should do everything here. Mabye we should
// offload this to a regular task?
cx.local.net.poll();
cx.local.net.poll_dhcp();
cx.local.net.poll_udp();
}
}

0 comments on commit 4ee22ef

Please sign in to comment.