Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Remove static muts from examples #513

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ tinybmp = "0.5"
embedded-graphics = "0.8"
otm8009a = "0.1"
eg-seven-segment = "0.2.0"
static_cell = "2.1.0"

[features]
default = ["rt"]
Expand Down
1 change: 1 addition & 0 deletions examples/dma.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Example of Memory to Memory Transfer with the DMA

#![deny(warnings)]
#![allow(static_mut_refs)]
#![no_main]
#![no_std]

Expand Down
49 changes: 22 additions & 27 deletions examples/ethernet-nucleo-h743zi2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#![no_std]

extern crate cortex_m_rt as rt;
use core::mem::MaybeUninit;
use core::sync::atomic::{AtomicU32, Ordering};
use rt::{entry, exception};

Expand All @@ -22,6 +21,7 @@ extern crate cortex_m;
#[macro_use]
mod utilities;
use log::info;
use static_cell::StaticCell;

use stm32h7xx_hal::rcc::CoreClocks;
use stm32h7xx_hal::{ethernet, ethernet::PHY};
Expand Down Expand Up @@ -52,8 +52,7 @@ const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];

/// Ethernet descriptor rings are a global singleton
#[link_section = ".sram3.eth"]
static mut DES_RING: MaybeUninit<ethernet::DesRing<4, 4>> =
MaybeUninit::uninit();
static DES_RING: StaticCell<ethernet::DesRing<4, 4>> = StaticCell::new();

// the program entry point
#[entry]
Expand Down Expand Up @@ -113,30 +112,26 @@ fn main() -> ! {
assert_eq!(ccdr.clocks.pclk4().raw(), 100_000_000); // PCLK 100MHz

let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS);
let (_eth_dma, eth_mac) = unsafe {
DES_RING.write(ethernet::DesRing::new());

ethernet::new(
dp.ETHERNET_MAC,
dp.ETHERNET_MTL,
dp.ETHERNET_DMA,
(
rmii_ref_clk,
rmii_mdio,
rmii_mdc,
rmii_crs_dv,
rmii_rxd0,
rmii_rxd1,
rmii_tx_en,
rmii_txd0,
rmii_txd1,
),
DES_RING.assume_init_mut(),
mac_addr,
ccdr.peripheral.ETH1MAC,
&ccdr.clocks,
)
};
let (_eth_dma, eth_mac) = ethernet::new(
dp.ETHERNET_MAC,
dp.ETHERNET_MTL,
dp.ETHERNET_DMA,
(
rmii_ref_clk,
rmii_mdio,
rmii_mdc,
rmii_crs_dv,
rmii_rxd0,
rmii_rxd1,
rmii_tx_en,
rmii_txd0,
rmii_txd1,
),
DES_RING.init_with(ethernet::DesRing::new),
mac_addr,
ccdr.peripheral.ETH1MAC,
&ccdr.clocks,
);

// Initialise ethernet PHY...
let mut lan8742a = ethernet::phy::LAN8742A::new(eth_mac.set_phy_addr(0));
Expand Down
72 changes: 28 additions & 44 deletions examples/ethernet-rtic-nucleo-h723zg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
#[allow(unused)]
mod utilities;

use core::mem::MaybeUninit;
use core::ptr::addr_of_mut;
use core::sync::atomic::AtomicU32;

use smoltcp::iface::{Config, Interface, SocketSet, SocketStorage};
use smoltcp::time::Instant;
use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr};

use static_cell::StaticCell;

use stm32h7xx_hal::{ethernet, rcc::CoreClocks, stm32};

/// Configure SYSTICK for 1ms timebase
Expand All @@ -49,17 +49,16 @@ const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];

/// Ethernet descriptor rings are a global singleton
#[link_section = ".axisram.eth"]
static mut DES_RING: MaybeUninit<ethernet::DesRing<4, 4>> =
MaybeUninit::uninit();
static DES_RING: StaticCell<ethernet::DesRing<4, 4>> = StaticCell::new();

/// Net storage with static initialisation - another global singleton
pub struct NetStorageStatic<'a> {
socket_storage: [SocketStorage<'a>; 8],
}

// MaybeUninit allows us write code that is correct even if STORE is not
// StaticCell allows us write code that is correct even if STORE is not
// initialised by the runtime
static mut STORE: MaybeUninit<NetStorageStatic> = MaybeUninit::uninit();
static STORE: StaticCell<NetStorageStatic> = StaticCell::new();

pub struct Net<'a> {
iface: Interface,
Expand Down Expand Up @@ -163,30 +162,26 @@ mod app {
assert_eq!(ccdr.clocks.pclk4().raw(), 100_000_000); // PCLK 100MHz

let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS);
let (eth_dma, eth_mac) = unsafe {
DES_RING.write(ethernet::DesRing::new());

ethernet::new(
ctx.device.ETHERNET_MAC,
ctx.device.ETHERNET_MTL,
ctx.device.ETHERNET_DMA,
(
rmii_ref_clk,
rmii_mdio,
rmii_mdc,
rmii_crs_dv,
rmii_rxd0,
rmii_rxd1,
rmii_tx_en,
rmii_txd0,
rmii_txd1,
),
DES_RING.assume_init_mut(),
mac_addr,
ccdr.peripheral.ETH1MAC,
&ccdr.clocks,
)
};
let (eth_dma, eth_mac) = ethernet::new(
ctx.device.ETHERNET_MAC,
ctx.device.ETHERNET_MTL,
ctx.device.ETHERNET_DMA,
(
rmii_ref_clk,
rmii_mdio,
rmii_mdc,
rmii_crs_dv,
rmii_rxd0,
rmii_rxd1,
rmii_tx_en,
rmii_txd0,
rmii_txd1,
),
DES_RING.init_with(ethernet::DesRing::new),
mac_addr,
ccdr.peripheral.ETH1MAC,
&ccdr.clocks,
);

// Initialise ethernet PHY...
let mut lan8742a = ethernet::phy::LAN8742A::new(eth_mac);
Expand All @@ -196,20 +191,9 @@ mod app {

unsafe { ethernet::enable_interrupt() };

// unsafe: mutable reference to static storage, we only do this once
let store = unsafe {
let store_ptr = STORE.as_mut_ptr();

// Initialise the socket_storage field. Using `write` instead of
// assignment via `=` to not call `drop` on the old, uninitialised
// value
addr_of_mut!((*store_ptr).socket_storage)
.write([SocketStorage::EMPTY; 8]);

// Now that all fields are initialised we can safely use
// assume_init_mut to return a mutable reference to STORE
STORE.assume_init_mut()
};
let store = STORE.init_with(|| NetStorageStatic {
socket_storage: [SocketStorage::EMPTY; 8],
});

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

Expand Down
73 changes: 29 additions & 44 deletions examples/ethernet-rtic-stm32h735g-dk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
#[allow(unused)]
mod utilities;

use core::mem::MaybeUninit;
use core::ptr::addr_of_mut;
use core::sync::atomic::AtomicU32;

use smoltcp::iface::{Config, Interface, SocketSet, SocketStorage};
use smoltcp::time::Instant;
use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr};

use static_cell::StaticCell;

use stm32h7xx_hal::{ethernet, rcc::CoreClocks, stm32};

/// Configure SYSTICK for 1ms timebase
Expand All @@ -45,16 +45,16 @@ const MAC_ADDRESS: [u8; 6] = [0x02, 0x00, 0x11, 0x22, 0x33, 0x44];

/// Ethernet descriptor rings are a global singleton
#[link_section = ".axisram.eth"]
static mut DES_RING: MaybeUninit<ethernet::DesRing<4, 4>> =
MaybeUninit::uninit();
static DES_RING: StaticCell<ethernet::DesRing<4, 4>> = StaticCell::new();

// This data will be held by Net through a mutable reference
pub struct NetStorageStatic<'a> {
socket_storage: [SocketStorage<'a>; 8],
}
// MaybeUninit allows us write code that is correct even if STORE is not

// StaticCell allows us write code that is correct even if STORE is not
// initialised by the runtime
static mut STORE: MaybeUninit<NetStorageStatic> = MaybeUninit::uninit();
static STORE: StaticCell<NetStorageStatic> = StaticCell::new();

pub struct Net<'a> {
iface: Interface,
Expand Down Expand Up @@ -157,30 +157,26 @@ mod app {
assert_eq!(ccdr.clocks.pclk4().raw(), 100_000_000); // PCLK 100MHz

let mac_addr = smoltcp::wire::EthernetAddress::from_bytes(&MAC_ADDRESS);
let (eth_dma, eth_mac) = unsafe {
DES_RING.write(ethernet::DesRing::new());

ethernet::new(
ctx.device.ETHERNET_MAC,
ctx.device.ETHERNET_MTL,
ctx.device.ETHERNET_DMA,
(
rmii_ref_clk,
rmii_mdio,
rmii_mdc,
rmii_crs_dv,
rmii_rxd0,
rmii_rxd1,
rmii_tx_en,
rmii_txd0,
rmii_txd1,
),
DES_RING.assume_init_mut(),
mac_addr,
ccdr.peripheral.ETH1MAC,
&ccdr.clocks,
)
};
let (eth_dma, eth_mac) = ethernet::new(
ctx.device.ETHERNET_MAC,
ctx.device.ETHERNET_MTL,
ctx.device.ETHERNET_DMA,
(
rmii_ref_clk,
rmii_mdio,
rmii_mdc,
rmii_crs_dv,
rmii_rxd0,
rmii_rxd1,
rmii_tx_en,
rmii_txd0,
rmii_txd1,
),
DES_RING.init_with(ethernet::DesRing::new),
mac_addr,
ccdr.peripheral.ETH1MAC,
&ccdr.clocks,
);

// Initialise ethernet PHY...
let mut lan8742a = ethernet::phy::LAN8742A::new(eth_mac);
Expand All @@ -190,20 +186,9 @@ mod app {

unsafe { ethernet::enable_interrupt() };

// unsafe: mutable reference to static storage, we only do this once
let store = unsafe {
let store_ptr = STORE.as_mut_ptr();

// Initialise the socket_storage field. Using `write` instead of
// assignment via `=` to not call `drop` on the old, uninitialised
// value
addr_of_mut!((*store_ptr).socket_storage)
.write([SocketStorage::EMPTY; 8]);

// Now that all fields are initialised we can safely use
// assume_init_mut to return a mutable reference to STORE
STORE.assume_init_mut()
};
let store = STORE.init_with(|| NetStorageStatic {
socket_storage: [SocketStorage::EMPTY; 8],
});

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

Expand Down
Loading
Loading