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
```
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
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
openocd-flash main
openocd-flash
```
## Networking Setup
At the moment, both IP addresses of the STM32 board and MQTT broker are hardcoded.
MAC address of the STM32 board is also hardcoded.
## Networking Setup for First-time User
Provide them to setup Humpback-DDS:
- 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
IP address is hardcoded in the file `src/main.rs`, line 171.
```rust
store.ip_addrs[0] = net::wire::IpCidr::new(net::wire::IpAddress::v4(192, 168, 1, 200), 24);
```
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.
Note:
- IP/MAC address of Humpback-DDS should be unique inside a local area network.
- Device name should be unique among all Humpback-DDS connected to the same MQTT broker.
- The MQTT broker must accept TCP connection at port `1883`.
### STM32 MAC Address
IP address is hardcoded in the file `src/main.rs`, line 156.
```rust
let mac_addr = net::wire::EthernetAddress([0xAC, 0x6F, 0x7A, 0xDE, 0xD6, 0xC8]);
Use the following Nix command.
```shell
openocd-flash-customised <client_cidr_ip_addr> <mac_addr> <broker_addr> "<name>"
```
The MAC address shown above corresponds to `AC::6F::7A::DE::D6::C8`.
Modify this line to the change the MAC address of STM32 board.
Parameters:
- 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
IP address is hardcoded in the file `src/main.rs`, line 241.
```rust
IpAddr::V4(Ipv4Addr::new(192, 168, 1, 125)),
### Example
```shell
openocd-flash-customised 192.168.1.200/24 AC:6F:7A:DE:D6:C8 192.168.1.125 "Urukul"
```
This program will try attempt to connect to `192.168.1.125:1883`.
Modify this line to the change the IP address of MQTT broker.
Note that the broker must accept TCP connection at `port 1883`.
The device will be named `Urukul`.
It has `192.168.1.200` as IPv4 Address, inside a `\24` network, with `AC:6F:7A:DE:D6:C8` as MAC address.
It will connect to a MQTT broker at `192.168.1.125:1883`.
## MQTT Broker
Mosquitto is within the Nix package.

View File

@ -1,41 +1,66 @@
let
mozillaOverlay = import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz);
pkgs = import <nixpkgs> {overlays = [mozillaOverlay];};
mozillaOverlay = import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz);
pkgs = import <nixpkgs> {overlays = [mozillaOverlay];};
in with pkgs;
let
migen = callPackage ./nix/migen.nix {};
openocd = callPackage ./nix/openocd.nix {};
rustPlatform = callPackage ./nix/rustPlatform.nix {};
itm = callPackage ./nix/itm.nix {inherit rustPlatform;};
migen = callPackage ./nix/migen.nix {};
openocd = callPackage ./nix/openocd.nix {};
rustPlatform = callPackage ./nix/rustPlatform.nix {};
itm = callPackage ./nix/itm.nix {inherit rustPlatform;};
runOpenOcdBlock = writeShellScriptBin "run-openocd-block" ''
openocd -f openocd/openocd.cfg
'';
runOpenOcdBlock = writeShellScriptBin "run-openocd-block" ''
openocd -f openocd/openocd.cfg
'';
openocdFlash = writeShellScriptBin "openocd-flash" ''
openocd -f openocd/openocd.cfg -f openocd/$1.cfg
'';
openocdFlash = writeShellScriptBin "openocd-flash" ''
openocd -f openocd/openocd.cfg -f openocd/main.cfg
'';
publishMqtt = writeShellScriptBin "publish-mqtt" ''
mosquitto_pub -h localhost -t $1 -m "$2" -d
'';
publishMqtt = writeShellScriptBin "publish-mqtt" ''
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
stdenv.mkDerivation {
name = "Humpback-DDS";
buildInputs = with rustPlatform.rust; [
(pkgs.python3.withPackages(ps: [ migen ]))
pkgs.yosys
pkgs.nextpnr
pkgs.icestorm
pkgs.gdb
pkgs.mosquitto
openocd
rustc
cargo
itm
runOpenOcdBlock
openocdFlash
publishMqtt
];
}
stdenv.mkDerivation {
name = "Humpback-DDS";
buildInputs = with rustPlatform.rust; [
(pkgs.python3.withPackages(ps: [ migen ]))
pkgs.yosys
pkgs.nextpnr
pkgs.icestorm
pkgs.gdb
pkgs.mosquitto
openocd
rustc
cargo
itm
runOpenOcdBlock
openocdFlash
publishMqtt
openOCDFlashCustomised
];
}

View File

@ -20,6 +20,8 @@ use rtic::cyccnt::{Instant, U32Ext};
use heapless::{ String, consts, consts::* };
use core::convert::TryInto;
#[macro_use]
pub mod bitmask_macro;
pub mod spi_slave;
@ -110,6 +112,58 @@ fn main() -> ! {
let gpiof = dp.GPIOF.split(ccdr.peripheral.GPIOF);
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:
// - FPGA_SPI: SCK (af5)
// - ST_LINK SWO (af0)
@ -153,7 +207,7 @@ fn main() -> ! {
}
// 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 {
ethernet::new_unchecked(
dp.ETHERNET_MAC,
@ -168,7 +222,7 @@ fn main() -> ! {
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[..]);
@ -220,8 +274,7 @@ fn main() -> ! {
);
urukul.reset().unwrap();
let device_name = "Urukul";
let mut mqtt_mux = MqttMux::new(urukul, device_name);
let mut mqtt_mux = MqttMux::new(urukul, device_name.as_str());
// Time unit in ms
let mut time: u32 = 0;
@ -238,8 +291,8 @@ fn main() -> ! {
let tcp_stack = NetworkStack::new(&mut net_interface, sockets);
let mut client = MqttClient::<consts::U256, _>::new(
IpAddr::V4(Ipv4Addr::new(192, 168, 1, 125)),
device_name,
IpAddr::V4(broker_ipv4_addr),
device_name.as_str(),
tcp_stack,
)
.unwrap();
@ -286,7 +339,7 @@ fn main() -> ! {
}
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();
match client.subscribe(str_builder.as_str(), &[]) {
Ok(()) => has_subscribed = true,