forked from M-Labs/humpback-dds
flash: setup flash memory for ip/mac/name setup
This commit is contained in:
parent
28046a8740
commit
3fb8114df1
55
README.md
55
README.md
|
@ -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.
|
||||||
|
|
91
shell.nix
91
shell.nix
|
@ -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
|
||||||
}
|
];
|
||||||
|
}
|
||||||
|
|
67
src/main.rs
67
src/main.rs
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue