embassy icon indicating copy to clipboard operation
embassy copied to clipboard

embassy-boot-nrf with softdevice

Open AliMoal opened this issue 11 months ago • 2 comments

I need an example to have bootloader with using softdevice together due to update both application and softdevice. I checked the example, but it does not work for me. One thing that I should mention is that I need defmt for debug both bootloader and applications. Thanks.

AliMoal avatar Mar 04 '24 14:03 AliMoal

What is it that does not work with the example? For what it's worth, I've got a more advanced example here https://github.com/lulf/watchful/tree/main/firmware, maybe you can copy from that.

lulf avatar Mar 04 '24 15:03 lulf

Thank you for your quick response. I checked your example, but you did not use any debug message. Because I think it has problem with using probe-rs runner debug in both bootloader and application example. I see weird behavior for debug messages. First I program softdevice, then program bootloader and after that the main program but it does not work as desired.

AliMoal avatar Mar 04 '24 15:03 AliMoal

Did you get this working eventually, can we close the issue?

lulf avatar Mar 21 '24 07:03 lulf

Did you get this working eventually, can we close the issue?

Yes, Thank you

AliMoal avatar Apr 13 '24 09:04 AliMoal

Hi @AliMoal , may I ask you some infos on how you solved? I have a strange issue too. I have sofdevice, app and bootloader at the end of flash. Bootloader is custom, just rewrites actual one ( no double image ). When I jumo to app ( using load function og embassy boot in sd flavour ) app starts but crash when i turn on sd and send some commands from uart. When i just flash sd and app it works like a charm. If you can give me some hints on how you solved would be great!

arkanoider avatar Jun 29 '24 14:06 arkanoider

Thank you @arkanoider My case was different from yours, but if you explain more, I can help. Could you describe how to understand app starts? Do you have UART connection from board? Did you implement any debug method?

AliMoal avatar Jun 30 '24 07:06 AliMoal

Thanks @AliMoal !

I try to summarize my system: I have an nrf52 chip connected with a bigger MCU via UART, bigger MCU can send and receive messages to and from BT via nrf chip ( a sort of passthrough let me say ) basically my small app just do this. Bootloader inside nrf chip can update this passthrough app in case.

As premise, i confirm that application is working correctly with no bootloader flashed, with boot onbooard basically I have a reset after i send a command with BT on.

Could you describe how to understand app starts? I see welcome message and I can also send BT activation command and it works because I can see advertise starting.

I have a UART message sent out at start

Do you have UART connection from board?

Yes. Real system has the two microcontrollers speakin via UART , i am using a sw terminal to simulate from PC during tests.

Did you implement any debug method?

If you mean Rust impl...no...i am using just defmt for printing info.

I can drop my memory.x files here: Bootloader side:

MEMORY
{
    /* NOTE 1 K = 1 KiBi = 1024 bytes */
  /* These values correspond to the NRF52805 with SoftDevices S112 7.2.0 */
  FLASH (rx) : ORIGIN = 0x2A000, LENGTH = 24K
  RAM : ORIGIN = 0x20000008, LENGTH = 24K - 8
  mbr_params_page (r) : ORIGIN = 0x0002E000, LENGTH = 4K
  bootloader_settings_page (r) : ORIGIN = 0x0002F000, LENGTH = 4K
  uicr_bootloader_start_address (r) : ORIGIN = 0x10001014, LENGTH = 0x4
}

SECTIONS {
     .uicr_bootloader_start_address :  {
       KEEP(*(.uicr_bootloader_start_address))
       . = ALIGN(4);
     } > uicr_bootloader_start_address
};

App side

MEMORY
{
  /* NOTE 1 K = 1 KiBi = 1024 bytes */
  /* These values correspond to the NRF52805 with SoftDevices S112 7.2.0 */
  FLASH (rx) : ORIGIN = 0x19000, LENGTH = 64K
  RAM : ORIGIN = 0x20000000 + 9440, LENGTH = 24K - 9440
}

So basically bootloader is placed at 0x2A000 and app starts after SD at 0x19000. Jump to app is done via this copy and paste function from embassy boot:

/// Boots the application assuming softdevice is present.
///
/// # Safety
///
/// This modifies the stack pointer and reset vector and will run code placed in the active partition.
pub unsafe fn jump_to_app() -> ! {
    use nrf_softdevice_mbr as mbr;

    // Address of softdevice which we'll forward interrupts to
    let addr = 0x1000;
    let mut cmd = mbr::sd_mbr_command_t {
        command: mbr::NRF_MBR_COMMANDS_SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
        params: mbr::sd_mbr_command_t__bindgen_ty_1 {
            irq_forward_address_set: mbr::sd_mbr_command_irq_forward_address_set_t {
                address: addr,
            },
        },
    };
    let ret = mbr::sd_mbr_command(&mut cmd);
    info!("ret val {}", ret);

    let msp = *(addr as *const u32);
    let rv = *((addr + 4) as *const u32);

    trace!("msp = {=u32:x}, rv = {=u32:x}", msp, rv);

    // These instructions perform the following operations:
    //
    // * Modify control register to use MSP as stack pointer (clear spsel bit)
    // * Synchronize instruction barrier
    // * Initialize stack pointer (0x1000)
    // * Set link register to not return (0xFF)
    // * Jump to softdevice reset vector
    core::arch::asm!(
        "mrs {tmp}, CONTROL",
        "bics {tmp}, {spsel}",
        "msr CONTROL, {tmp}",
        "isb",
        "msr MSP, {msp}",
        "mov lr, {new_lr}",
        "bx {rv}",
        // `out(reg) _` is not permitted in a `noreturn` asm! call,
        // so instead use `in(reg) 0` and don't restore it afterwards.
        tmp = in(reg) 0,
        spsel = in(reg) 2,
        new_lr = in(reg) 0xFFFFFFFFu32,
        msp = in(reg) msp,
        rv = in(reg) rv,
        options(noreturn),
    );
}

arkanoider avatar Jun 30 '24 07:06 arkanoider

Solved! Thanks anyway...

arkanoider avatar Jul 02 '24 16:07 arkanoider