Merge pull request #311 from quartiq/feature/dhcp-support
Feature/dhcp support
This commit is contained in:
commit
a93e823ea5
|
@ -201,7 +201,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "derive_miniconf"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/quartiq/miniconf.git?branch=develop#394d0634a9622e43a55850afc34eb4695ecababa"
|
||||
source = "git+https://github.com/quartiq/miniconf.git?branch=develop#314fa5587d1aa28e1ad70106f19e30db646e9f28"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -414,10 +414,10 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "miniconf"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/quartiq/miniconf.git?branch=develop#394d0634a9622e43a55850afc34eb4695ecababa"
|
||||
source = "git+https://github.com/quartiq/miniconf.git?branch=develop#314fa5587d1aa28e1ad70106f19e30db646e9f28"
|
||||
dependencies = [
|
||||
"derive_miniconf",
|
||||
"heapless 0.5.6",
|
||||
"heapless 0.6.1",
|
||||
"minimq",
|
||||
"serde",
|
||||
"serde-json-core",
|
||||
|
@ -426,13 +426,13 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "minimq"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/quartiq/minimq.git?branch=master#a89a6f11d0d1f63114fb15f676022eb4fe904f56"
|
||||
source = "git+https://github.com/quartiq/minimq.git#933687c2e4bc8a4d972de9a4d1508b0b554a8b38"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"embedded-nal",
|
||||
"enum-iterator",
|
||||
"generic-array 0.14.4",
|
||||
"heapless 0.5.6",
|
||||
"heapless 0.6.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -697,8 +697,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "smoltcp"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab527c390c7e107f687bd92a886a083fde61b8cdc700b37f3d7e4346ffd8fae1"
|
||||
source = "git+https://github.com/ryan-summers/smoltcp.git?branch=feature/dhcp-lease-updates#e3954ebb8149341c52a4992e037d4b5109387910"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"byteorder",
|
||||
|
@ -708,11 +707,10 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "smoltcp-nal"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4e5aeb4818706fd74c35917692008d29a5314483c8180300a582253718ce57a"
|
||||
source = "git+https://github.com/quartiq/smoltcp-nal.git?branch=main#56519012d7c6a382eaa0d7ecb26f2701771d9ce8"
|
||||
dependencies = [
|
||||
"embedded-nal",
|
||||
"heapless 0.5.6",
|
||||
"heapless 0.6.1",
|
||||
"smoltcp",
|
||||
]
|
||||
|
||||
|
|
|
@ -53,12 +53,19 @@ branch = "develop"
|
|||
|
||||
[patch.crates-io.minimq]
|
||||
git = "https://github.com/quartiq/minimq.git"
|
||||
branch = "master"
|
||||
|
||||
[patch.crates-io.smoltcp-nal]
|
||||
git = "https://github.com/quartiq/smoltcp-nal.git"
|
||||
branch = "main"
|
||||
|
||||
[patch.crates-io.serde-json-core]
|
||||
git = "https://github.com/rust-embedded-community/serde-json-core.git"
|
||||
branch = "master"
|
||||
|
||||
[patch.crates-io.smoltcp]
|
||||
git = "https://github.com/ryan-summers/smoltcp.git"
|
||||
branch = "feature/dhcp-lease-updates"
|
||||
|
||||
[dependencies.mcp23017]
|
||||
git = "https://github.com/mrd0ll4r/mcp23017.git"
|
||||
|
||||
|
|
|
@ -144,16 +144,31 @@ const APP: () = {
|
|||
|
||||
loop {
|
||||
let sleep = c.resources.mqtt_interface.lock(|interface| {
|
||||
!interface.network_stack().poll(clock.current_ms())
|
||||
match interface.network_stack().poll(clock.current_ms()) {
|
||||
Ok(updated) => !updated,
|
||||
Err(err) => {
|
||||
log::info!("Network error: {:?}", err);
|
||||
false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if c.resources
|
||||
match c
|
||||
.resources
|
||||
.mqtt_interface
|
||||
.lock(|interface| interface.update().unwrap())
|
||||
.lock(|interface| interface.update())
|
||||
{
|
||||
c.spawn.settings_update().unwrap()
|
||||
} else if sleep {
|
||||
cortex_m::asm::wfi();
|
||||
Ok(update) => {
|
||||
if update {
|
||||
c.spawn.settings_update().unwrap();
|
||||
} else if sleep {
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
Err(miniconf::MqttError::Network(
|
||||
smoltcp_nal::NetworkError::NoIpAddress,
|
||||
)) => {}
|
||||
Err(error) => log::info!("Unexpected error: {:?}", error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,16 +208,31 @@ const APP: () = {
|
|||
|
||||
loop {
|
||||
let sleep = c.resources.mqtt_interface.lock(|interface| {
|
||||
!interface.network_stack().poll(clock.current_ms())
|
||||
match interface.network_stack().poll(clock.current_ms()) {
|
||||
Ok(updated) => !updated,
|
||||
Err(err) => {
|
||||
log::info!("Network error: {:?}", err);
|
||||
false
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if c.resources
|
||||
match c
|
||||
.resources
|
||||
.mqtt_interface
|
||||
.lock(|interface| interface.update().unwrap())
|
||||
.lock(|interface| interface.update())
|
||||
{
|
||||
c.spawn.settings_update().unwrap()
|
||||
} else if sleep {
|
||||
cortex_m::asm::wfi();
|
||||
Ok(update) => {
|
||||
if update {
|
||||
c.spawn.settings_update().unwrap();
|
||||
} else if sleep {
|
||||
cortex_m::asm::wfi();
|
||||
}
|
||||
}
|
||||
Err(miniconf::MqttError::Network(
|
||||
smoltcp_nal::NetworkError::NoIpAddress,
|
||||
)) => {}
|
||||
Err(error) => log::info!("Unexpected error: {:?}", error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,38 @@ use super::{
|
|||
|
||||
pub struct NetStorage {
|
||||
pub ip_addrs: [smoltcp::wire::IpCidr; 1],
|
||||
pub sockets: [Option<smoltcp::socket::SocketSetItem<'static>>; 1],
|
||||
pub sockets: [Option<smoltcp::socket::SocketSetItem<'static>>; 2],
|
||||
pub neighbor_cache:
|
||||
[Option<(smoltcp::wire::IpAddress, smoltcp::iface::Neighbor)>; 8],
|
||||
pub routes_cache:
|
||||
[Option<(smoltcp::wire::IpCidr, smoltcp::iface::Route)>; 8],
|
||||
pub tx_storage: [u8; 4096],
|
||||
pub rx_storage: [u8; 4096],
|
||||
|
||||
pub dhcp_rx_metadata: [smoltcp::socket::RawPacketMetadata; 1],
|
||||
pub dhcp_tx_metadata: [smoltcp::socket::RawPacketMetadata; 1],
|
||||
pub dhcp_tx_storage: [u8; 600],
|
||||
pub dhcp_rx_storage: [u8; 600],
|
||||
}
|
||||
|
||||
impl NetStorage {
|
||||
pub fn new() -> Self {
|
||||
NetStorage {
|
||||
// Placeholder for the real IP address, which is initialized at runtime.
|
||||
ip_addrs: [smoltcp::wire::IpCidr::Ipv6(
|
||||
smoltcp::wire::Ipv6Cidr::SOLICITED_NODE_PREFIX,
|
||||
)],
|
||||
neighbor_cache: [None; 8],
|
||||
routes_cache: [None; 8],
|
||||
sockets: [None, None],
|
||||
tx_storage: [0; 4096],
|
||||
rx_storage: [0; 4096],
|
||||
dhcp_tx_storage: [0; 600],
|
||||
dhcp_rx_storage: [0; 600],
|
||||
dhcp_rx_metadata: [smoltcp::socket::RawPacketMetadata::EMPTY; 1],
|
||||
dhcp_tx_metadata: [smoltcp::socket::RawPacketMetadata::EMPTY; 1],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The available networking devices on Stabilizer.
|
||||
|
@ -59,22 +84,6 @@ pub struct PounderDevices {
|
|||
/// Static storage for the ethernet DMA descriptor ring.
|
||||
static mut DES_RING: ethernet::DesRing = ethernet::DesRing::new();
|
||||
|
||||
/// Static, global-scope network storage for the ethernet interface.
|
||||
///
|
||||
/// This is a static singleton so that the network storage can be referenced from all contexts.
|
||||
static mut NET_STORE: NetStorage = NetStorage {
|
||||
// Placeholder for the real IP address, which is initialized at runtime.
|
||||
ip_addrs: [smoltcp::wire::IpCidr::Ipv6(
|
||||
smoltcp::wire::Ipv6Cidr::SOLICITED_NODE_PREFIX,
|
||||
)],
|
||||
neighbor_cache: [None; 8],
|
||||
routes_cache: [None; 8],
|
||||
sockets: [None; 1],
|
||||
|
||||
tx_storage: [0; 4096],
|
||||
rx_storage: [0; 4096],
|
||||
};
|
||||
|
||||
/// Configure the stabilizer hardware for operation.
|
||||
///
|
||||
/// # Args
|
||||
|
@ -516,17 +525,23 @@ pub fn setup(
|
|||
|
||||
unsafe { ethernet::enable_interrupt() };
|
||||
|
||||
let store = unsafe { &mut NET_STORE };
|
||||
// Note(unwrap): The hardware configuration function is only allowed to be called once.
|
||||
// Unwrapping is intended to panic if called again to prevent re-use of global memory.
|
||||
let store =
|
||||
cortex_m::singleton!(: NetStorage = NetStorage::new()).unwrap();
|
||||
|
||||
store.ip_addrs[0] = smoltcp::wire::IpCidr::new(
|
||||
smoltcp::wire::IpAddress::v4(10, 34, 16, 103),
|
||||
24,
|
||||
smoltcp::wire::IpAddress::Ipv4(
|
||||
smoltcp::wire::Ipv4Address::UNSPECIFIED,
|
||||
),
|
||||
0,
|
||||
);
|
||||
|
||||
let default_v4_gw = smoltcp::wire::Ipv4Address::new(10, 34, 16, 1);
|
||||
let mut routes =
|
||||
smoltcp::iface::Routes::new(&mut store.routes_cache[..]);
|
||||
routes.add_default_ipv4_route(default_v4_gw).unwrap();
|
||||
routes
|
||||
.add_default_ipv4_route(smoltcp::wire::Ipv4Address::UNSPECIFIED)
|
||||
.unwrap();
|
||||
|
||||
let neighbor_cache =
|
||||
smoltcp::iface::NeighborCache::new(&mut store.neighbor_cache[..]);
|
||||
|
@ -538,36 +553,54 @@ pub fn setup(
|
|||
.routes(routes)
|
||||
.finalize();
|
||||
|
||||
let sockets = {
|
||||
// Note(unsafe): Configuration is only called once, so we only access the global
|
||||
// storage a single time.
|
||||
let socket_storage = unsafe { &mut NET_STORE.sockets[..] };
|
||||
let mut sockets = smoltcp::socket::SocketSet::new(socket_storage);
|
||||
let (mut sockets, handles) = {
|
||||
let mut sockets =
|
||||
smoltcp::socket::SocketSet::new(&mut store.sockets[..]);
|
||||
|
||||
let tcp_socket = {
|
||||
let rx_buffer = {
|
||||
// Note(unsafe): Configuration is only called once, so we only access the global
|
||||
// storage a single time.
|
||||
let storage = unsafe { &mut NET_STORE.rx_storage[..] };
|
||||
smoltcp::socket::TcpSocketBuffer::new(storage)
|
||||
};
|
||||
|
||||
let tx_buffer = {
|
||||
// Note(unsafe): Configuration is only called once, so we only access the global
|
||||
// storage a single time.
|
||||
let storage = unsafe { &mut NET_STORE.tx_storage[..] };
|
||||
smoltcp::socket::TcpSocketBuffer::new(storage)
|
||||
};
|
||||
let rx_buffer = smoltcp::socket::TcpSocketBuffer::new(
|
||||
&mut store.rx_storage[..],
|
||||
);
|
||||
let tx_buffer = smoltcp::socket::TcpSocketBuffer::new(
|
||||
&mut store.tx_storage[..],
|
||||
);
|
||||
|
||||
smoltcp::socket::TcpSocket::new(rx_buffer, tx_buffer)
|
||||
};
|
||||
|
||||
sockets.add(tcp_socket);
|
||||
sockets
|
||||
let handle = sockets.add(tcp_socket);
|
||||
(sockets, [handle])
|
||||
};
|
||||
|
||||
let dhcp_client = {
|
||||
let dhcp_rx_buffer = smoltcp::socket::RawSocketBuffer::new(
|
||||
&mut store.dhcp_rx_metadata[..],
|
||||
&mut store.dhcp_rx_storage[..],
|
||||
);
|
||||
|
||||
let dhcp_tx_buffer = smoltcp::socket::RawSocketBuffer::new(
|
||||
&mut store.dhcp_tx_metadata[..],
|
||||
&mut store.dhcp_tx_storage[..],
|
||||
);
|
||||
|
||||
smoltcp::dhcp::Dhcpv4Client::new(
|
||||
&mut sockets,
|
||||
dhcp_rx_buffer,
|
||||
dhcp_tx_buffer,
|
||||
// Smoltcp indicates that an instant with a negative time is indicative that time is
|
||||
// not yet available. We can't get the current instant yet, so indicate an invalid
|
||||
// time value.
|
||||
smoltcp::time::Instant::from_millis(-1),
|
||||
)
|
||||
};
|
||||
|
||||
NetworkDevices {
|
||||
stack: smoltcp_nal::NetworkStack::new(interface, sockets),
|
||||
stack: smoltcp_nal::NetworkStack::new(
|
||||
interface,
|
||||
sockets,
|
||||
&handles,
|
||||
Some(dhcp_client),
|
||||
),
|
||||
phy: lan8742a,
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue