flash: setup flash memory for ip/mac/name setup

This commit is contained in:
occheung 2020-10-05 15:20:54 +08:00
parent 28046a8740
commit 3fb8114df1
3 changed files with 147 additions and 66 deletions

View File

@ -9,44 +9,47 @@ Start nix shell before anything.
nix-shell nix-shell
``` ```
Flash firmware onto STM32 NUCLEO-H743ZI2 using OpenOCD. **(For users who had completed the [networking setup](##networking-setup-for-first-time-user))** Flash firmware onto STM32 NUCLEO-H743ZI2 using OpenOCD.
```shell ```shell
openocd -f openocd/openocd.cfg -f openocd/main.cfg openocd -f openocd/openocd.cfg -f openocd/main.cfg
``` ```
Alternatively, an equivalent Nix command can also do the work **(For users who had completed the [networking setup](##networking-setup-for-first-time-user))** Alternatively, an equivalent Nix command can also do the work.
```shell ```shell
openocd-flash main openocd-flash
``` ```
## Networking Setup ## Networking Setup for First-time User
At the moment, both IP addresses of the STM32 board and MQTT broker are hardcoded. Provide them to setup Humpback-DDS:
MAC address of the STM32 board is also hardcoded. - IP Address of Humpback-DDS
- Address block of the local area network
- MAC Address of Humpback-DDS
- IP Address of MQTT broker
- Device name of Humpback-DDS
### STM32 IP Address Note:
IP address is hardcoded in the file `src/main.rs`, line 171. - IP/MAC address of Humpback-DDS should be unique inside a local area network.
```rust - Device name should be unique among all Humpback-DDS connected to the same MQTT broker.
store.ip_addrs[0] = net::wire::IpCidr::new(net::wire::IpAddress::v4(192, 168, 1, 200), 24); - The MQTT broker must accept TCP connection at port `1883`.
```
The IP address shown above corresponds to `192.168.1.200`, in a `/24` address block.
Modify this line to the change the IP address of STM32 board.
### STM32 MAC Address Use the following Nix command.
IP address is hardcoded in the file `src/main.rs`, line 156. ```shell
```rust openocd-flash-customised <client_cidr_ip_addr> <mac_addr> <broker_addr> "<name>"
let mac_addr = net::wire::EthernetAddress([0xAC, 0x6F, 0x7A, 0xDE, 0xD6, 0xC8]);
``` ```
The MAC address shown above corresponds to `AC::6F::7A::DE::D6::C8`. Parameters:
Modify this line to the change the MAC address of STM32 board. - client_cidr_ip_addr: IP address for the Humpback-DDS device, in CIDR notation
- mac_addr: MAC address for the Humpback-DDS device
- broker_addr: IP address for the MQTT broker
- name: Device name of the Humpback-DDS
### Broker IP Address ### Example
IP address is hardcoded in the file `src/main.rs`, line 241. ```shell
```rust openocd-flash-customised 192.168.1.200/24 AC:6F:7A:DE:D6:C8 192.168.1.125 "Urukul"
IpAddr::V4(Ipv4Addr::new(192, 168, 1, 125)),
``` ```
This program will try attempt to connect to `192.168.1.125:1883`. The device will be named `Urukul`.
Modify this line to the change the IP address of MQTT broker. It has `192.168.1.200` as IPv4 Address, inside a `\24` network, with `AC:6F:7A:DE:D6:C8` as MAC address.
Note that the broker must accept TCP connection at `port 1883`. It will connect to a MQTT broker at `192.168.1.125:1883`.
## MQTT Broker ## MQTT Broker
Mosquitto is within the Nix package. Mosquitto is within the Nix package.

View File

@ -1,41 +1,66 @@
let let
mozillaOverlay = import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz); mozillaOverlay = import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz);
pkgs = import <nixpkgs> {overlays = [mozillaOverlay];}; pkgs = import <nixpkgs> {overlays = [mozillaOverlay];};
in with pkgs; in with pkgs;
let let
migen = callPackage ./nix/migen.nix {}; migen = callPackage ./nix/migen.nix {};
openocd = callPackage ./nix/openocd.nix {}; openocd = callPackage ./nix/openocd.nix {};
rustPlatform = callPackage ./nix/rustPlatform.nix {}; rustPlatform = callPackage ./nix/rustPlatform.nix {};
itm = callPackage ./nix/itm.nix {inherit rustPlatform;}; itm = callPackage ./nix/itm.nix {inherit rustPlatform;};
runOpenOcdBlock = writeShellScriptBin "run-openocd-block" '' runOpenOcdBlock = writeShellScriptBin "run-openocd-block" ''
openocd -f openocd/openocd.cfg openocd -f openocd/openocd.cfg
''; '';
openocdFlash = writeShellScriptBin "openocd-flash" '' openocdFlash = writeShellScriptBin "openocd-flash" ''
openocd -f openocd/openocd.cfg -f openocd/$1.cfg openocd -f openocd/openocd.cfg -f openocd/main.cfg
''; '';
publishMqtt = writeShellScriptBin "publish-mqtt" '' publishMqtt = writeShellScriptBin "publish-mqtt" ''
mosquitto_pub -h localhost -t $1 -m "$2" -d mosquitto_pub -h localhost -t $1 -m "$2" -d
''; '';
openOCDFlashCustomised = writeShellScriptBin "openocd-flash-customised" ''
IFS='.|/' read -r a b c d e <<< $1
((ip = (a << 32) + (b << 24) + (c << 16) + (d << 8) + e))
IFS=':' read -r a b c d e f <<< $2
((mac = (16#$a << 40) + (16#$b << 32) + (16#$c << 24) + (16#$d << 16) + (16#$e << 8) + 16#$f))
IFS='.' read -r a b c d <<< $3
((broker_ip = (a << 24) + (b << 16) + (c << 8) + d))
touch temp_name
printf "%s\x04" "$4" > temp_name
openocd -f openocd/openocd.cfg \
-c "init
reset init
halt
stm32h7x mass_erase 1
flash write_image erase target/thumbv7em-none-eabihf/release/humpback-dds
flash filld 0x08100000 $ip 1
flash filld 0x08100020 $mac 1
flash fillw 0x08100040 $broker_ip 1
flash write_image temp_name 0x08100060 bin
reset run
shutdown"
rm temp_name
'';
in in
stdenv.mkDerivation { stdenv.mkDerivation {
name = "Humpback-DDS"; name = "Humpback-DDS";
buildInputs = with rustPlatform.rust; [ buildInputs = with rustPlatform.rust; [
(pkgs.python3.withPackages(ps: [ migen ])) (pkgs.python3.withPackages(ps: [ migen ]))
pkgs.yosys pkgs.yosys
pkgs.nextpnr pkgs.nextpnr
pkgs.icestorm pkgs.icestorm
pkgs.gdb pkgs.gdb
pkgs.mosquitto pkgs.mosquitto
openocd openocd
rustc rustc
cargo cargo
itm itm
runOpenOcdBlock runOpenOcdBlock
openocdFlash openocdFlash
publishMqtt publishMqtt
]; openOCDFlashCustomised
} ];
}

View File

@ -20,6 +20,8 @@ use rtic::cyccnt::{Instant, U32Ext};
use heapless::{ String, consts, consts::* }; use heapless::{ String, consts, consts::* };
use core::convert::TryInto;
#[macro_use] #[macro_use]
pub mod bitmask_macro; pub mod bitmask_macro;
pub mod spi_slave; pub mod spi_slave;
@ -110,6 +112,58 @@ fn main() -> ! {
let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF); let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF);
let gpiog = dp.GPIOG.split(ccdr.peripheral.GPIOG); let gpiog = dp.GPIOG.split(ccdr.peripheral.GPIOG);
// Acquire client/broker IP Address, client MAC address from flash memory
let ipv4_addr_cidr = unsafe {
let ipv4_bits = core::ptr::read(0x08100000 as *const u64);
net::wire::IpCidr::new(
net::wire::IpAddress::v4(
((ipv4_bits >> 32) & 0xFF).try_into().unwrap(),
((ipv4_bits >> 24) & 0xFF).try_into().unwrap(),
((ipv4_bits >> 16) & 0xFF).try_into().unwrap(),
((ipv4_bits >> 8) & 0xFF).try_into().unwrap()
),
((ipv4_bits >> 0) & 0xFF).try_into().unwrap()
)
};
let mac_addr = unsafe {
let mac_bits = core::ptr::read(0x08100020 as *const u64);
net::wire::EthernetAddress([
((mac_bits >> 40) & 0xFF).try_into().unwrap(),
((mac_bits >> 32) & 0xFF).try_into().unwrap(),
((mac_bits >> 24) & 0xFF).try_into().unwrap(),
((mac_bits >> 16) & 0xFF).try_into().unwrap(),
((mac_bits >> 8) & 0xFF).try_into().unwrap(),
(mac_bits & 0xFF).try_into().unwrap(),
])
};
let broker_ipv4_addr = unsafe {
let ipv4_bits = core::ptr::read(0x08100040 as *const u64);
Ipv4Addr::new(
((ipv4_bits >> 24) & 0xFF).try_into().unwrap(),
((ipv4_bits >> 16) & 0xFF).try_into().unwrap(),
((ipv4_bits >> 8) & 0xFF).try_into().unwrap(),
((ipv4_bits >> 0) & 0xFF).try_into().unwrap()
)
};
let device_name: String<U32> = unsafe {
let mut name = String::new();
let mut addr = 0x08100060;
loop {
let c = core::ptr::read(addr as *const u8);
if c == 4 {
break;
} else {
name.push(c as char).unwrap();
addr += 1;
}
}
name
};
// Note: ITM doesn't work beyond this, due to a pin conflict between: // Note: ITM doesn't work beyond this, due to a pin conflict between:
// - FPGA_SPI: SCK (af5) // - FPGA_SPI: SCK (af5)
// - ST_LINK SWO (af0) // - ST_LINK SWO (af0)
@ -153,7 +207,7 @@ fn main() -> ! {
} }
// Configure ethernet // Configure ethernet
let mac_addr = net::wire::EthernetAddress([0xAC, 0x6F, 0x7A, 0xDE, 0xD6, 0xC8]); // let mac_addr = net::wire::EthernetAddress([0xAC, 0x6F, 0x7A, 0xDE, 0xD6, 0xC8]);
let (eth_dma, mut eth_mac) = unsafe { let (eth_dma, mut eth_mac) = unsafe {
ethernet::new_unchecked( ethernet::new_unchecked(
dp.ETHERNET_MAC, dp.ETHERNET_MAC,
@ -168,7 +222,7 @@ fn main() -> ! {
let store = unsafe { &mut NET_STORE }; let store = unsafe { &mut NET_STORE };
store.ip_addrs[0] = net::wire::IpCidr::new(net::wire::IpAddress::v4(192, 168, 1, 200), 24); store.ip_addrs[0] = ipv4_addr_cidr;
let neighbor_cache = net::iface::NeighborCache::new(&mut store.neighbor_cache[..]); let neighbor_cache = net::iface::NeighborCache::new(&mut store.neighbor_cache[..]);
@ -220,8 +274,7 @@ fn main() -> ! {
); );
urukul.reset().unwrap(); urukul.reset().unwrap();
let device_name = "Urukul"; let mut mqtt_mux = MqttMux::new(urukul, device_name.as_str());
let mut mqtt_mux = MqttMux::new(urukul, device_name);
// Time unit in ms // Time unit in ms
let mut time: u32 = 0; let mut time: u32 = 0;
@ -238,8 +291,8 @@ fn main() -> ! {
let tcp_stack = NetworkStack::new(&mut net_interface, sockets); let tcp_stack = NetworkStack::new(&mut net_interface, sockets);
let mut client = MqttClient::<consts::U256, _>::new( let mut client = MqttClient::<consts::U256, _>::new(
IpAddr::V4(Ipv4Addr::new(192, 168, 1, 125)), IpAddr::V4(broker_ipv4_addr),
device_name, device_name.as_str(),
tcp_stack, tcp_stack,
) )
.unwrap(); .unwrap();
@ -286,7 +339,7 @@ fn main() -> ! {
} }
if connection && !has_subscribed && tick { if connection && !has_subscribed && tick {
let mut str_builder: String<U128> = String::from(device_name); let mut str_builder: String<U128> = String::from(device_name.as_str());
str_builder.push_str("/Control/#").unwrap(); str_builder.push_str("/Control/#").unwrap();
match client.subscribe(str_builder.as_str(), &[]) { match client.subscribe(str_builder.as_str(), &[]) {
Ok(()) => has_subscribed = true, Ok(()) => has_subscribed = true,