From 5a53b7167140e09b7c5ae9a627d55cae656f4f1e Mon Sep 17 00:00:00 2001 From: topquark12 Date: Tue, 12 Jan 2021 14:56:58 +0800 Subject: [PATCH] dfu: working software triggered dfu --- memory.x | 4 +++- src/command_parser.rs | 2 ++ src/main.rs | 52 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/memory.x b/memory.x index 213f9a1..5366550 100644 --- a/memory.x +++ b/memory.x @@ -3,7 +3,9 @@ MEMORY FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K /* reserved for config data */ CONFIG (rx) : ORIGIN = 0x8100000, LENGTH = 16K - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 112K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 111K + /* reserved for DFU trigger message */ + DFU_MSG (wrx) : ORIGIN = 0x2001BC00, LENGTH = 1K RAM2 (xrw) : ORIGIN = 0x2001C000, LENGTH = 16K RAM3 (xrw) : ORIGIN = 0x20020000, LENGTH = 64K CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K diff --git a/src/command_parser.rs b/src/command_parser.rs index db1ea8f..09fac7b 100644 --- a/src/command_parser.rs +++ b/src/command_parser.rs @@ -179,6 +179,7 @@ pub enum Command { channel: usize, rate: Option, }, + Dfu, } fn end(input: &[u8]) -> IResult<&[u8], ()> { @@ -535,6 +536,7 @@ fn command(input: &[u8]) -> IResult<&[u8], Result> { pid, steinhart_hart, postfilter, + value(Ok(Command::Dfu), tag("dfu")), ))(input) } diff --git a/src/main.rs b/src/main.rs index c745a8f..555673c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ #![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_main)] -#![feature(maybe_uninit_extra, maybe_uninit_ref)] +#![feature(maybe_uninit_extra, maybe_uninit_ref, asm)] #![cfg_attr(test, allow(unused))] // TODO: #![deny(warnings, unused)] @@ -13,7 +13,7 @@ use log::{error, info, warn}; use core::fmt::Write; use cortex_m::asm::wfi; -use cortex_m_rt::entry; +use cortex_m_rt::{entry, pre_init}; use stm32f4xx_hal::{ hal::watchdog::{WatchdogEnable, Watchdog}, rcc::RccExt, @@ -77,6 +77,8 @@ const CHANNEL_CONFIG_KEY: [&str; 2] = ["ch0", "ch1"]; const TCP_PORT: u16 = 23; +const DFU_MSG_ADDR: usize = 0x2001BC00; +const DFU_TRIG_MSG: usize = 0xDECAFBAD; fn send_line(socket: &mut TcpSocket, data: &[u8]) -> bool { let send_free = socket.send_capacity() - socket.send_queue(); @@ -422,6 +424,18 @@ fn main() -> ! { channels.power_down(i); } + SCB::sys_reset(); + } + Command::Dfu => { + for i in 0..CHANNELS { + channels.power_down(i); + } + + unsafe { + let dfu_msg_addr = DFU_MSG_ADDR as *mut usize; + *dfu_msg_addr = DFU_TRIG_MSG; + } + SCB::sys_reset(); } } @@ -473,3 +487,37 @@ fn main() -> ! { unreachable!() } + +#[pre_init] +#[no_mangle] +unsafe fn __pre_init() { + + let dfu_msg_addr = DFU_MSG_ADDR as *mut usize; + + if *dfu_msg_addr == DFU_TRIG_MSG{ + + *dfu_msg_addr = 0x00000000; + + const RCC_APB2ENR: *mut u32 = 0xE000_ED88 as *mut u32; + const RCC_APB2ENR_ENABLE_SYSCFG_CLOCK: u32 = 0x00004000; + + core::ptr::write_volatile( + RCC_APB2ENR, + *RCC_APB2ENR | RCC_APB2ENR_ENABLE_SYSCFG_CLOCK, + ); + + const SYSCFG_MEMRMP: *mut u32 = 0x40013800 as *mut u32; + const SYSCFG_MEMRMP_MAP_ROM: u32 = 0x00000001; + + core::ptr::write_volatile( + SYSCFG_MEMRMP, + *SYSCFG_MEMRMP | SYSCFG_MEMRMP_MAP_ROM, + ); + + asm!("LDR R0, =0x1FFF0000"); + asm!("LDR SP,[R0, #0]"); + asm!("LDR R0,[R0, #4]"); + asm!("BX R0"); + } + +} \ No newline at end of file