Skip to content

Commit 9673509

Browse files
aidangarskedanielinux
authored andcommitted
Clean up NXP LPC54S018M port and align with LPC55S69 patterns
- HAL: Remove debug spifi_test_mode_switch(), use wolfBoot_printf instead of raw uart_write, add printf.h include - Test app: Use check_parts() (was defined but unused), replace custom print_str/print_hex32 with wolfBoot_printf, fix LED logic to show LED1 for v1 and LED2 for v2+ (was always LED1) - Docs: Remove incorrect MCUXpresso SDK section (port is bare-metal), fix typo, add swap timing note, add flash script references - Build: Add --no-warn-rwx-segments to arch.mk, improve Makefile comments - Add tools/scripts/nxp-lpc54s018m-flash.sh following the nxp-s32k142-flash.sh pattern (build, sign, flash via pyocd) Tested: full boot + firmware update cycle (v1 -> v2 swap) verified on LPC54S018M-EVK hardware.
1 parent 943d4fd commit 9673509

6 files changed

Lines changed: 329 additions & 110 deletions

File tree

arch.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,6 +1191,7 @@ endif
11911191

11921192
ifeq ($(TARGET),nxp_lpc54s018m)
11931193
ARCH_FLASH_OFFSET=0x10000000
1194+
LDFLAGS+=-Wl,--no-warn-rwx-segments
11941195
# Bare-metal HAL — no NXP SDK dependencies
11951196
endif
11961197

docs/Targets.md

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,33 +2001,15 @@ sudo /usr/local/LinkServer/lpcscrypt/bin/lpcscrypt -d /dev/ttyACMx \
20012001
program /usr/local/LinkServer/lpcscrypt/probe_firmware/LPCLink2/LPC432x_CMSIS_DAP_V5_460.bin.hdr BankA
20022002
```
20032003

2004-
### LPC54S018M: MCUXpresso SDK setup
2004+
### LPC54S018M: Toolchain
20052005

2006-
This requires the NXP MCUXpresso SDK. We tested using
2007-
[mcuxsdk-manifests](https://github.com/nxp-mcuxpresso/mcuxsdk-manifests) and
2008-
[CMSIS_5](https://github.com/nxp-mcuxpresso/CMSIS_5) placed under "../NXP".
2006+
This port uses bare-metal register access and does not require the NXP
2007+
MCUXpresso SDK. Only an ARM GCC toolchain (`arm-none-eabi-gcc`) and
2008+
[pyocd](https://pyocd.io/) are needed.
20092009

20102010
```sh
2011-
cd ../NXP
2012-
2013-
# Install west
2014-
python -m venv west-venv
2015-
source west-venv/bin/activate
2016-
pip install west
2017-
2018-
# Set up the repository
2019-
west init -m https://github.com/nxp-mcuxpresso/mcuxsdk-manifests.git mcuxpresso-sdk
2020-
cd mcuxpresso-sdk
2021-
west update
2022-
2023-
deactivate
2024-
```
2025-
2026-
The CMSIS headers are also needed:
2027-
2028-
```sh
2029-
cd ../NXP
2030-
git clone https://github.com/nxp-mcuxpresso/CMSIS_5.git
2011+
pip install pyocd
2012+
pyocd pack install LPC54S018J4MET180
20312013
```
20322014

20332015
### LPC54S018M: Flash partition layout
@@ -2084,39 +2066,66 @@ instead of booting from SPIFI flash.
20842066

20852067
### LPC54S018M: Testing firmware update
20862068

2069+
A convenience script automates the full build, sign, and flash process:
2070+
2071+
```sh
2072+
# Build and flash v1 only
2073+
./tools/scripts/nxp-lpc54s018m-flash.sh
2074+
2075+
# Build, sign v2, and flash both (full update test)
2076+
./tools/scripts/nxp-lpc54s018m-flash.sh --test-update
2077+
2078+
# Flash existing images without rebuilding
2079+
./tools/scripts/nxp-lpc54s018m-flash.sh --test-update --skip-build
2080+
```
2081+
2082+
**Manual steps** (if not using the script):
2083+
20872084
1. Build and flash factory.bin (version 1). USR_LED1 (P3.14) lights up.
20882085

20892086
2. Sign a version 2 update image and load it to the update partition:
20902087

20912088
```sh
20922089
# Build update image (version 2)
2093-
make test-app/image_v2_signed.bin
2090+
./tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 2
20942091
```
20952092

2093+
**Using JLink:**
2094+
20962095
```
20972096
JLinkExe -device LPC54S018M -if SWD -speed 4000
20982097
loadbin test-app/image_v2_signed.bin 0x10100000
20992098
r
21002099
g
21012100
```
21022101

2102+
**Using pyocd:**
2103+
2104+
```sh
2105+
pyocd flash -t LPC54S018J4MET180 test-app/image_v2_signed.bin --base-address 0x10100000
2106+
```
2107+
21032108
3. The test application detects the update, triggers a swap via
2104-
`wolfBoot_update_trigger()`, and resets. After the swap, USR_LED2 (P3.3)
2105-
lights up indicating version 2 is running.
2109+
`wolfBoot_update_trigger()`, and resets. After the swap (~60 seconds),
2110+
USR_LED2 (P3.3) lights up indicating version 2 is running.
21062111

21072112
4. The application calls `wolfBoot_success()` to confirm the update and
21082113
prevent rollback.
21092114

21102115
### LPC54S018M: LED indicators
21112116

2112-
The test application uses three user LEDs (accent LEDs accent active low):
2117+
The test application uses three user LEDs (accent LEDs, active low):
21132118

21142119
| LED | GPIO | Meaning |
21152120
|-----------|--------|----------------------------|
21162121
| USR_LED1 | P3.14 | Version 1 running |
21172122
| USR_LED2 | P3.3 | Version 2+ running |
21182123
| USR_LED3 | P2.2 | Update activity in progress |
21192124

2125+
**Note:** The firmware swap takes approximately 60 seconds due to the SPIFI
2126+
controller mode-switch overhead for each of the 240 sector operations (960KB
2127+
partition with 4KB sectors).
2128+
21202129
### LPC54S018M: Debugging with JLink
21212130

21222131
```

hal/nxp_lpc54s018m.c

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <string.h>
3333
#include <target.h>
3434
#include "image.h"
35+
#include "printf.h"
3536

3637
/* -------------------------------------------------------------------------- */
3738
/* SPIFI controller registers (base 0x40080000) */
@@ -289,8 +290,8 @@ void hal_init(void)
289290
*/
290291
#ifdef DEBUG_UART
291292
uart_init();
292-
uart_write("wolfBoot HAL init\n", 18);
293293
#endif
294+
wolfBoot_printf("wolfBoot HAL init\n");
294295
}
295296

296297
void hal_prepare_boot(void)
@@ -390,33 +391,6 @@ static void RAMFUNCTION spifi_wait_busy(void)
390391
SPIFI_CLIMIT = saved_climit; /* restore cache limit */
391392
}
392393

393-
/*
394-
* Minimal SPIFI mode-switch test: exit memory mode, immediately re-enter.
395-
* Used to verify the basic exit/enter cycle works before testing flash ops.
396-
*/
397-
void RAMFUNCTION spifi_test_mode_switch(void)
398-
{
399-
uint32_t ctrl = SPIFI_CTRL;
400-
uint32_t climit = SPIFI_CLIMIT;
401-
402-
/* Exit memory mode */
403-
SPIFI_STAT = SPIFI_STAT_RESET;
404-
while (SPIFI_STAT & SPIFI_STAT_RESET)
405-
;
406-
407-
/* Restore all config */
408-
SPIFI_CTRL = ctrl;
409-
SPIFI_CLIMIT = climit;
410-
411-
/* Re-enter memory mode */
412-
SPIFI_MCMD = MCMD_READ_QUAD;
413-
while (!(SPIFI_STAT & SPIFI_STAT_MCINIT))
414-
;
415-
416-
__asm__ volatile ("dsb");
417-
__asm__ volatile ("isb");
418-
}
419-
420394
/*
421395
* Flash write — 256-byte page program via SPIFI
422396
*

test-app/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ ifeq ($(TARGET),nxp_lpc54s018m)
703703
LSCRIPT_TEMPLATE=ARM-nxp_lpc54s018m.ld
704704
# Enable RAMFUNCTION for test app (flash ops must run from RAM)
705705
CFLAGS+=-DRAM_CODE -D__WOLFBOOT
706-
# SPIFI XIP: memcpy/memset must be in RAM for use during flash operations
706+
# string.o provides RAMFUNCTION memcpy; already added when DEBUG_UART=1 (line ~108)
707707
ifeq ($(DEBUG_UART),)
708708
APP_OBJS+=../src/string.o
709709
endif

test-app/app_nxp_lpc54s018m.c

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,7 @@
2424
#include <stdint.h>
2525
#include "target.h"
2626
#include "wolfboot/wolfboot.h"
27-
28-
#ifdef DEBUG_UART
29-
extern void uart_write(const char *buf, unsigned int sz);
30-
31-
static void print_str(const char *s)
32-
{
33-
unsigned int len = 0;
34-
while (s[len] != '\0')
35-
len++;
36-
uart_write(s, len);
37-
}
38-
39-
static void print_hex32(uint32_t val)
40-
{
41-
static const char hex[] = "0123456789abcdef";
42-
char buf[10];
43-
int i;
44-
buf[0] = '0';
45-
buf[1] = 'x';
46-
for (i = 0; i < 8; i++)
47-
buf[2 + i] = hex[(val >> (28 - i * 4)) & 0xF];
48-
uart_write(buf, 10);
49-
}
50-
#endif
27+
#include "printf.h"
5128

5229
/* LPC54S018M-EVK GPIO register definitions */
5330
/* GPIO base: 0x4008C000 */
@@ -108,17 +85,10 @@ static void check_parts(uint32_t *pboot_ver, uint32_t *pupdate_ver,
10885
if (wolfBoot_get_partition_state(PART_UPDATE, pupdate_state) != 0)
10986
*pupdate_state = IMG_STATE_NEW;
11087

111-
#ifdef DEBUG_UART
112-
print_str(" boot: ver=");
113-
print_hex32(*pboot_ver);
114-
print_str(" state=");
115-
print_hex32(*pboot_state);
116-
print_str("\n update: ver=");
117-
print_hex32(*pupdate_ver);
118-
print_str(" state=");
119-
print_hex32(*pupdate_state);
120-
print_str("\n");
121-
#endif
88+
wolfBoot_printf(" boot: ver=0x%lx state=0x%02x\n",
89+
*pboot_ver, *pboot_state);
90+
wolfBoot_printf(" update: ver=0x%lx state=0x%02x\n",
91+
*pupdate_ver, *pupdate_state);
12292
}
12393

12494
void main(void)
@@ -127,37 +97,36 @@ void main(void)
12797
uint8_t boot_state, update_state;
12898

12999
leds_init();
130-
131-
boot_ver = wolfBoot_current_firmware_version();
132-
update_ver = wolfBoot_update_firmware_version();
133-
if (wolfBoot_get_partition_state(PART_BOOT, &boot_state) != 0)
134-
boot_state = IMG_STATE_NEW;
135-
if (wolfBoot_get_partition_state(PART_UPDATE, &update_state) != 0)
136-
update_state = IMG_STATE_NEW;
137-
138-
/* LED1 on immediately to show app is running */
139-
led_on(LED1_PORT, LED1_PIN);
100+
check_parts(&boot_ver, &update_ver, &boot_state, &update_state);
140101

141102
/* Confirm boot if state is TESTING or NEW */
142103
if (boot_ver != 0 &&
143104
(boot_state == IMG_STATE_TESTING || boot_state == IMG_STATE_NEW))
144105
{
106+
wolfBoot_printf("Calling wolfBoot_success()\n");
145107
wolfBoot_success();
108+
check_parts(&boot_ver, &update_ver, &boot_state, &update_state);
146109
}
147110

148-
if (boot_ver == 1 && update_ver != 0) {
149-
/* Update available: LED3 on, trigger update */
150-
led_on(LED3_PORT, LED3_PIN);
151-
wolfBoot_update_trigger();
111+
if (boot_ver == 1) {
112+
/* v1: LED1 on */
113+
led_on(LED1_PORT, LED1_PIN);
114+
115+
if (update_ver != 0) {
116+
wolfBoot_printf("Update detected, triggering update...\n");
117+
wolfBoot_update_trigger();
118+
check_parts(&boot_ver, &update_ver, &boot_state, &update_state);
119+
/* LED3 on to indicate update triggered */
120+
led_on(LED3_PORT, LED3_PIN);
121+
wolfBoot_printf("...done. Reboot to apply.\n");
122+
}
152123
}
153-
else if (boot_ver != 1) {
124+
else {
154125
/* v2+: LED2 on */
155126
led_on(LED2_PORT, LED2_PIN);
156127
}
157128

158-
#ifdef DEBUG_UART
159-
print_str("App running\n");
160-
#endif
129+
wolfBoot_printf("App running\n");
161130
while (1) {
162131
__asm__ volatile ("wfi");
163132
}

0 commit comments

Comments
 (0)