From 61d24ab857a971573ab5b6f3d06bbcd7dd2c209a Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 29 Mar 2024 11:10:30 -0700 Subject: [PATCH] Added test-app code to change LED color based on version. Improved documentation. Minor code cleanups. --- docs/Targets.md | 49 +++++++++++++++-- hal/mcxa.c | 37 ++++++------- test-app/ARM-mcxa.ld | 4 +- test-app/app_mcxa.c | 126 +++++++++++++++++++++++-------------------- 4 files changed, 134 insertions(+), 82 deletions(-) diff --git a/docs/Targets.md b/docs/Targets.md index d687d6c04..fb512113a 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -1714,8 +1714,10 @@ thread break: Stopped, 0x0, 0x0, cpuPowerPCBig, Connected (state, tid, pid, cpu ## NXP MCXA153 NXP MCXA153 is a Cortex-M33 microcontroller running at 96MHz. -The support has been tested using FRDM-MCXA153 with the onboard MCU-Link -configured in JLink mode. +The support has been tested using FRDM-MCXA153 with the onboard MCU-Link configured in JLink mode. + +This requires the MCXA SDK from the NXP MCUXpresso SDK Builder. We tested using `SDK_2.14.2_MCXA153` and placed into `../NXP/MCXA153` by default (see .config or set with `MCUXPRESSO`). +MCUXpresso SDK Builder ### Configuring and compiling @@ -1729,6 +1731,8 @@ Compile via: ### Loading the firmware +The NXP Freedom MCX A board debugger comes loaded with MCU Link, but it can be updated to JLink. See https://docs.nxp.com/bundle/UM12012/page/topics/Updating_MCU_Link_firmware.html + Use JLinkExe tool to upload the initial firmware: `JLinkExe -if swd -Device MCXA153` @@ -1736,9 +1740,48 @@ Use JLinkExe tool to upload the initial firmware: At the Jlink prompt, type: ``` -J-Link>loadbin factory.bin 0 +loadbin factory.bin 0 +'loadbin': Performing implicit reset & halt of MCU. +ResetTarget() start +Reset via SYSRESETREQ and reset pin + halt after bootloader +ResetTarget() end - Took 111ms +AfterResetTarget() start + SRAM_XEN set to RWX + FLASH and IFR set to RWX +AfterResetTarget() end - Took 7.40ms +Downloading file [factory.bin]... +J-Link: Flash download: Bank 0 @ 0x00000000: Skipped. Contents already match +O.K. +``` + +Reset or power cycle board. + +Once wolfBoot has performaed validation of the partition and booted the D15 Green LED on P3_13 will illuminate. + +### Testing firmware update + +1) Sign the test-app with version 2: + +``` +./tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 2 +``` + +2) Create a bin footer with wolfBoot trailer "BOOT" and "p" (ASCII for 0x70 == IMG_STATE_UPDATING): + +``` +echo -n "pBOOT" > trigger_magic.bin +``` + +3) Assembly new factory update.bin: + +```sh +./tools/bin-assemble/bin-assemble \ + update.bin \ + 0x0 test-app/image_v2_signed.bin \ + 0xAFFB trigger_magic.bin ``` +4) Flash update.bin to 0x13000 (`loadbin update.bin 0x13000`). The D15 GDB LED Blue P3_0 will show if version is > 1. ## TI Hercules TMS570LC435 diff --git a/hal/mcxa.c b/hal/mcxa.c index 22f117e01..ca2effd98 100644 --- a/hal/mcxa.c +++ b/hal/mcxa.c @@ -32,10 +32,10 @@ /* Flash driver */ #include "fsl_romapi.h" -#define BOARD_BOOTCLOCKFRO96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ +/*!< Core clock frequency: 96000000Hz */ +#define BOARD_BOOTCLOCKFRO96M_CORE_CLOCK 96000000UL static flash_config_t pflash; -//static ftfx_cache_config_t pcache; static int flash_init = 0; #ifdef __WOLFBOOT @@ -70,11 +70,11 @@ void BOARD_BootClockFRO96M(void) (void)SPC_SetSRAMOperateVoltage(SPC0, &sramOption); } - CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */ + CLOCK_SetupFROHFClocking(96000000U); /*!< Enable FRO HF(96MHz) output */ - CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ + CLOCK_SetupFRO12MClocking(); /*!< Setup FRO12M clock */ - CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ + CLOCK_AttachClk(kFRO_HF_to_MAIN_CLK); /* !< Switch MAIN_CLK to FRO_HF */ /* The flow of decreasing voltage and frequency */ if (coreFreq > BOARD_BOOTCLOCKFRO96M_CORE_CLOCK) { @@ -93,11 +93,10 @@ void BOARD_BootClockFRO96M(void) /*!< Set up clock selectors - Attach clocks to the peripheries */ /*!< Set up dividers */ - CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ - CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivAHBCLK, 1U); /* !< Set AHBCLKDIV divider to value 1 */ + CLOCK_SetClockDiv(kCLOCK_DivFRO_HF_DIV, 1U); /* !< Set FROHFDIV divider to value 1 */ } - void hal_init(void) { /* Clock setting */ @@ -113,15 +112,16 @@ void hal_prepare_boot(void) { } - -#endif +#endif /* __WOLFBOOT */ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) { - int w = 0; int ret; - const uint8_t empty_qword[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + int w = 0; + const uint8_t empty_qword[16] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; while (len > 0) { if ((len < 16) || address & 0x0F) { @@ -129,17 +129,20 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) uint32_t address_align = address - (address & 0x0F); uint32_t start_off = address - address_align; int i; + memcpy(aligned_qword, (void*)address_align, 16); - for (i = start_off; ((i < 16) && (i < len + (int)start_off)); i++) + for (i = start_off; ((i < 16) && (i < len + (int)start_off)); i++) { aligned_qword[i] = data[w++]; + } if (memcmp(aligned_qword, empty_qword, 16) != 0) { - ret = FLASH_ProgramPhrase(&pflash, address_align, aligned_qword, 16); + ret = FLASH_ProgramPhrase(&pflash, address_align, aligned_qword, 16); if (ret != kStatus_Success) return -1; } address += i; len -= i; - } else { + } + else { uint32_t len_align = len - (len & 0x0F); ret = FLASH_ProgramPhrase(&pflash, address, (uint8_t*)data + w, len_align); if (ret != kStatus_Success) @@ -168,5 +171,3 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len) return -1; return 0; } - - diff --git a/test-app/ARM-mcxa.ld b/test-app/ARM-mcxa.ld index a4911d2f9..ef58a695b 100644 --- a/test-app/ARM-mcxa.ld +++ b/test-app/ARM-mcxa.ld @@ -1,7 +1,7 @@ MEMORY { FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 24K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 24K } SECTIONS @@ -17,7 +17,7 @@ SECTIONS . = ALIGN(4); _end_text = .; } > FLASH - + .ARM : { __exidx_start = .; diff --git a/test-app/app_mcxa.c b/test-app/app_mcxa.c index 6509588b3..a5fc8752b 100644 --- a/test-app/app_mcxa.c +++ b/test-app/app_mcxa.c @@ -1,3 +1,27 @@ +/* app_mcxa.c + * + * Test bare-metal boot-led-on application + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + #include #include #include @@ -5,76 +29,60 @@ #include "fsl_port.h" #include "fsl_gpio.h" #include "fsl_clock.h" -#include "wolfboot/wolfboot.h" - - -#define BOARD_LED_GPIO_PORT PORT3 -#define BOARD_LED_GPIO GPIO3 -#define BOARD_LED_GPIO_PIN 12U +#include "wolfboot/wolfboot.h" -void gpio_init(void) +/* init gpio for port 3 */ +void gpio_port3_init(int pin) { - /* Write to GPIO3: Peripheral clock is enabled */ - CLOCK_EnableClock(kCLOCK_GateGPIO3); - /* Write to PORT3: Peripheral clock is enabled */ - CLOCK_EnableClock(kCLOCK_GatePORT3); - /* GPIO3 peripheral is released from reset */ - RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); - /* PORT3 peripheral is released from reset */ - RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); - - gpio_pin_config_t LED_RED_config = { + const port_pin_config_t GPIO_OUT_LED = { + kPORT_PullDisable, /* Internal pull-up/down resistor is disabled */ + kPORT_LowPullResistor, /* Low internal pull resistor value is selected. */ + kPORT_FastSlewRate, /* Fast slew rate is configured */ + kPORT_PassiveFilterDisable, /* Passive input filter is disabled */ + kPORT_OpenDrainDisable, /* Open drain output is disabled */ + kPORT_LowDriveStrength, /* Low drive strength is configured */ + kPORT_NormalDriveStrength, /* Normal drive strength is configured */ + kPORT_MuxAlt0, /* Configure as GPIO */ + kPORT_InputBufferEnable, /* Digital input enabled */ + kPORT_InputNormal, /* Digital input is not inverted */ + kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ + }; + const gpio_pin_config_t GPIO_OUT_LED_config = { .pinDirection = kGPIO_DigitalOutput, .outputLogic = 0U }; - /* Initialize GPIO functionality on pin PIO3_12 (pin 38) */ - GPIO_PinInit(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, &LED_RED_config); - const port_pin_config_t LED_RED = {/* Internal pull-up/down resistor is disabled */ - kPORT_PullDisable, - /* Low internal pull resistor value is selected. */ - kPORT_LowPullResistor, - /* Fast slew rate is configured */ - kPORT_FastSlewRate, - /* Passive input filter is disabled */ - kPORT_PassiveFilterDisable, - /* Open drain output is disabled */ - kPORT_OpenDrainDisable, - /* Low drive strength is configured */ - kPORT_LowDriveStrength, - /* Normal drive strength is configured */ - kPORT_NormalDriveStrength, - /* Pin is configured as P3_12 */ - kPORT_MuxAlt0, - /* Digital input enabled */ - kPORT_InputBufferEnable, - /* Digital input is not inverted */ - kPORT_InputNormal, - /* Pin Control Register fields [15:0] are not locked */ - kPORT_UnlockRegister}; - /* PORT3_12 (pin 38) is configured as P3_12 */ - PORT_SetPinConfig(BOARD_LED_GPIO_PORT, BOARD_LED_GPIO_PIN, &LED_RED); -} + /* Enable GPIO port 3 clocks */ + CLOCK_EnableClock(kCLOCK_GateGPIO3); /* Write to GPIO3: Peripheral clock is enabled */ + CLOCK_EnableClock(kCLOCK_GatePORT3); /* Write to PORT3: Peripheral clock is enabled */ + RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); /* GPIO3 peripheral is released from reset */ + RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); /* PORT3 peripheral is released from reset */ + /* Initialize GPIO functionality on pin */ + GPIO_PinInit(GPIO3, pin, &GPIO_OUT_LED_config); + PORT_SetPinConfig(PORT3, pin, &GPIO_OUT_LED); +} -void main(void) { +void main(void) +{ int i = 0; - gpio_pin_config_t led_config = { - kGPIO_DigitalOutput, 0, - }; - /* Write to GPIO3: Peripheral clock is enabled */ - CLOCK_EnableClock(kCLOCK_GateGPIO3); - /* Write to PORT3: Peripheral clock is enabled */ - CLOCK_EnableClock(kCLOCK_GatePORT3); - /* GPIO3 peripheral is released from reset */ - RESET_ReleasePeripheralReset(kGPIO3_RST_SHIFT_RSTn); - /* PORT3 peripheral is released from reset */ - RESET_ReleasePeripheralReset(kPORT3_RST_SHIFT_RSTn); - gpio_init(); + uint8_t* bootPart = (uint8_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS; + uint32_t bootVer = wolfBoot_get_blob_version(bootPart); - GPIO_PinWrite(BOARD_LED_GPIO, BOARD_LED_GPIO_PIN, 0); + /* If application version 1 then GREEN, else BLUE */ + /* RGB LED D15 (RED=P3_12, GREEN=P3_13, BLUE=P3_0) */ + if (bootVer == 1) { + gpio_port3_init(13); + GPIO_PinWrite(GPIO3, 13, 0); + } + else { + gpio_port3_init(0); + GPIO_PinWrite(GPIO3, 0, 0); + } - while(1) + /* busy wait */ + while (1) { __WFI(); + } }