Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LPC1768: Update linker script, support split heap #430

Merged
merged 8 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ cmake_install.cmake
CMakeFiles/
cmake_build/
Testing/
cmake-variants.yaml
CMakeUserPresets.json

# CLion
cmake-build-*/
2 changes: 1 addition & 1 deletion connectivity/lwipstack/lwip-sys/arch/lwip_sys_arch.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# elif defined(TOOLCHAIN_GCC_CR)
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
# else
# define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned))
# define ETHMEM_SECTION __attribute__((section("AHBSRAM"),aligned))
# endif
#elif defined(TARGET_STM32H7)
# if defined (__ICCARM__)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void rcv_n_chk_against_rfc864_pattern(TCPSocket &sock)
recvd_size += rd;
}
timer.stop();
tr_info("MBED: Time taken: %fs", timer.read());
tr_info("MBED: Time taken: %" PRIi64 "ms", std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count());
}

void TCPSOCKET_RECV_100K()
Expand Down Expand Up @@ -172,7 +172,7 @@ void rcv_n_chk_against_rfc864_pattern_nonblock(TCPSocket &sock)
}
}
timer.stop();
tr_info("MBED: Time taken: %fs", timer.read());
tr_info("MBED: Time taken: %" PRIi64 "ms", std::chrono::duration_cast<std::chrono::milliseconds>(timer.elapsed_time()).count());
}

static void _sigio_handler(osThreadId id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ char s_trace_buffer[100] = MEM_MNGR_TRACE;
# elif defined(TOOLCHAIN_GCC_CR)
# define ETHMEM_SECTION __attribute__((section(".data.$RamPeriph32")))
# else
# define ETHMEM_SECTION __attribute__((section("AHBSRAM0"),aligned))
# define ETHMEM_SECTION __attribute__((section("AHBSRAM"),aligned))
# endif
#endif
#endif
Expand Down
27 changes: 16 additions & 11 deletions drivers/tests/TESTS/mbed_drivers/flashiap/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,11 @@ void flashiap_timing_test()
std::chrono::microseconds curr_time{};
std::chrono::microseconds avg_erase_time{};
unsigned int num_write_sizes;
unsigned int byte_usec_ratio;
float byte_sec_ratio;
std::chrono::microseconds max_erase_time(0), min_erase_time(-1);
const unsigned int max_writes = 128;
const unsigned int max_write_sizes = 6;
const unsigned int max_byte_usec_ratio = 200;
const unsigned int max_byte_sec_ratio = 200000000;

uint32_t page_size = flash_device.get_page_size();
uint32_t write_size = page_size;
Expand Down Expand Up @@ -294,28 +294,33 @@ void flashiap_timing_test()
}
timer.reset();
ret = flash_device.program(buf, address, write_size);

if (ret) {
printf("Failed programming %" PRIu32 " bytes at address 0x%" PRIx32 "\n!", write_size, address);
TEST_FAIL();
}

curr_time = timer.elapsed_time();
avg_write_time += curr_time;
TEST_ASSERT_EQUAL_INT32(0, ret);
max_write_time = us_max(max_write_time, curr_time);
min_write_time = us_min(min_write_time, curr_time);
address += write_size;
}
delete[] buf;
avg_write_time /= num_writes;
byte_usec_ratio = write_size / avg_write_time.count();
utest_printf("Write size %6u bytes: avg %10" PRIi64 ", min %10" PRIi64 ", max %10" PRIi64 " (usec), rate %10u bytes/usec\n",
write_size, avg_write_time.count(), min_write_time.count(), max_write_time.count(), byte_usec_ratio);
TEST_ASSERT(byte_usec_ratio < max_byte_usec_ratio);
byte_sec_ratio = write_size / std::chrono::duration_cast<std::chrono::duration<float>>(avg_write_time).count();
utest_printf("Write size %6u bytes: avg %10" PRIi64 ", min %10" PRIi64 ", max %10" PRIi64 " (usec), rate %.01f bytes/sec\n",
write_size, avg_write_time.count(), min_write_time.count(), max_write_time.count(), byte_sec_ratio);
TEST_ASSERT(byte_sec_ratio < max_byte_sec_ratio);
write_size *= 4;
}

if (num_write_sizes) {
avg_erase_time /= num_write_sizes;
byte_usec_ratio = sector_size / avg_erase_time.count();
utest_printf("\nErase size %6u bytes: avg %10" PRIi64 ", min %10" PRIi64 ", max %10" PRIi64" (usec), rate %10u bytes/usec\n\n",
sector_size, avg_erase_time.count(), min_erase_time.count(), max_erase_time.count(), byte_usec_ratio);
TEST_ASSERT(byte_usec_ratio < max_byte_usec_ratio);
byte_sec_ratio = sector_size / std::chrono::duration_cast<std::chrono::duration<float>>(avg_erase_time).count();
utest_printf("\nErase size %6u bytes: avg %10" PRIi64 ", min %10" PRIi64 ", max %10" PRIi64" (usec), rate %.01f bytes/sec\n\n",
sector_size, avg_erase_time.count(), min_erase_time.count(), max_erase_time.count(), byte_sec_ratio);
TEST_ASSERT(byte_sec_ratio < max_byte_sec_ratio);
}

ret = flash_device.deinit();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
/* Linker script for mbed LPC1768 */
#if !defined(MBED_APP_START)
#define MBED_APP_START 0x00000000
#endif

#if !defined(MBED_APP_SIZE)
#define MBED_APP_SIZE 512K
#endif
/* mbed Microcontroller Library
* Copyright (c) 2025 Jamie Smith
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "../cmsis_nvic.h"

#if !defined(MBED_CONF_TARGET_BOOT_STACK_SIZE)
#define MBED_CONF_TARGET_BOOT_STACK_SIZE 0x400
#endif

STACK_SIZE = MBED_CONF_TARGET_BOOT_STACK_SIZE;

#define VTORS_NEEDED_SPACE NVIC_NUM_VECTORS * 4

/* Linker script to configure memory regions. */
MEMORY
{
FLASH (rx) : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8 - 32) /* topmost 32 bytes used by IAP functions */

USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K
FLASH (rx) : ORIGIN = MBED_CONFIGURED_ROM_BANK_IROM1_START, LENGTH = MBED_CONFIGURED_ROM_BANK_IROM1_SIZE
RAM (rwx) : ORIGIN = MBED_RAM_BANK_IRAM1_START + VTORS_NEEDED_SPACE, LENGTH = (MBED_RAM_BANK_IRAM1_SIZE - VTORS_NEEDED_SPACE - 32) /* topmost 32 bytes used by IAP functions */
AHBSRAM(rwx) : ORIGIN = MBED_RAM_BANK_IRAM2_START, LENGTH = MBED_RAM_BANK_IRAM2_SIZE
}

/* Linker script to place sections and symbol values. Should be used together
Expand Down Expand Up @@ -56,9 +66,13 @@ SECTIONS
.text :
{
KEEP(*(.isr_vector))
/* Code Read Protect data */

#if MBED_CONFIGURED_ROM_BANK_IROM1_START == MBED_ROM_BANK_IROM1_START
/* Code Read Protect data, if this is at the start of flash*/
. = 0x000002FC ;
KEEP(*(.CRPSection))
#endif

/* End of Code Read Protect */
*(.text*)

Expand Down Expand Up @@ -144,14 +158,13 @@ SECTIONS
Image$$RW_IRAM1$$ZI$$Limit = . ;
} > RAM


.heap (NOLOAD):
.heap_0 (NOLOAD): ALIGN(8)
{
__end__ = .;
end = __end__;
*(.heap*)
. = ORIGIN(RAM) + LENGTH(RAM) - STACK_SIZE;
__HeapLimit = .;
__mbed_sbrk_start_0 = .;
. = (ORIGIN(RAM) + LENGTH(RAM) - STACK_SIZE);
__mbed_krbs_start_0 = .;
} > RAM

/* .stack_dummy section doesn't contains any symbols. It is only
Expand All @@ -169,24 +182,23 @@ SECTIONS
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
ASSERT(__StackLimit >= __end__, "region RAM overflowed with stack")


/* Code can explicitly ask for data to be
placed in these higher RAM banks where
placed in this higher RAM bank where
they will be left uninitialized.
*/
.AHBSRAM0 (NOLOAD):
.AHBSRAM_bss (NOLOAD):
{
Image$$RW_IRAM2$$Base = . ;
*(AHBSRAM0)
Image$$RW_IRAM2$$ZI$$Limit = .;
} > USB_RAM
*(AHBSRAM)
} > AHBSRAM

.AHBSRAM1 (NOLOAD):
/* Fill remaining space in AHBSRAM with additional heap */
.heap (NOLOAD): ALIGN(8)
{
Image$$RW_IRAM3$$Base = . ;
*(AHBSRAM1)
Image$$RW_IRAM3$$ZI$$Limit = .;
} > ETH_RAM
__mbed_sbrk_start = .;
. = ORIGIN(AHBSRAM) + LENGTH(AHBSRAM);
__mbed_krbs_start = .;
} > AHBSRAM
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,6 @@
aborting compilation, it is not the run time limit:
Heap_Size + Stack_Size = 0x80 + 0x80 = 0x100
*/

.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0x800
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.space Heap_Size
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit

.section .isr_vector
.align 2
Expand Down
2 changes: 1 addition & 1 deletion targets/TARGET_NXP/TARGET_LPC176X/device/cmsis_nvic.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#ifndef MBED_CMSIS_NVIC_H
#define MBED_CMSIS_NVIC_H

#define NVIC_NUM_VECTORS (16 + 33)
#define NVIC_NUM_VECTORS (16 + 35)
#define NVIC_RAM_VECTOR_ADDRESS 0x10000000 // Location of vectors in RAM

#endif
17 changes: 14 additions & 3 deletions targets/TARGET_NXP/TARGET_LPC176X/device/flash_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "cmsis.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <inttypes.h>

#define MEMMAP (*((volatile unsigned long *) 0x400FC040))

Expand Down Expand Up @@ -122,10 +124,18 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
// On LPC1768, the first RAM bank starts at 0x1000000, so anywhere below that has to be flash.
// The IAP firmware does not support flash to flash copies, so if the source data is in flash
// it must be buffered in RAM.
bool isFlashToFlashCopy = (ptrdiff_t)(data) < 0x10000000;
// Additionally, there seems to be an issue where the IAP ROM won't operate if a source page to be copied
// crosses the boundary between AHBSRAM0 and AHBSRAM1
const bool startsInAHBSRAM1 = ((uint32_t)data) >= MBED_CONFIGURED_RAM_BANK_IRAM2_START && ((uint32_t)data) < (MBED_CONFIGURED_RAM_BANK_IRAM2_START + 16384);
const bool endsInAHBSRAM2 = startsInAHBSRAM1 && ((((uint32_t)data) + size) >= MBED_CONFIGURED_RAM_BANK_IRAM2_START + 16384);
const bool sourceAddressPageAligned = (((uint32_t)data) % pageSize) == 0;
bool mustBuffer = ((ptrdiff_t)(data) < MBED_CONFIGURED_RAM_BANK_IRAM1_START) || (startsInAHBSRAM1 && endsInAHBSRAM2 && !sourceAddressPageAligned);

// printf("Flash program: flash address = 0x%" PRIx32 ", source data = 0x%" PRIx32 ", size = 0x%" PRIx32 ", startsInAHBSRAM1 = %d, endsInAHBSRAM2=%d, mustBuffer=%d\n",
// address, (ptrdiff_t)data, size, !!startsInAHBSRAM1, !!endsInAHBSRAM2, !!mustBuffer);

// check word boundary
if (isFlashToFlashCopy) {
if (mustBuffer) {
// always malloc outside critical section
tempBuffer = malloc(pageSize);
if (tempBuffer == 0) {
Expand All @@ -140,7 +150,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
for(size_t pageIdx = 0; pageIdx < (size / pageSize); ++pageIdx)
{
uint8_t * pageSourceAddr = source + (pageIdx * pageSize);
if (isFlashToFlashCopy) {
if (mustBuffer) {
memcpy(tempBuffer, pageSourceAddr, pageSize);
pageSourceAddr = tempBuffer;
}
Expand All @@ -166,6 +176,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address,
IAP_Call (&IAP.cmd, &IAP.stat); // Call IAP Command
if (IAP.stat) {
core_util_critical_section_exit();
//printf("IAP copy failed, address=0x%lx, pageSourceAddr=0x%lx, pageSize=%u\n", address, pageSourceAddr, pageSize);
return -1; // Command Failed
}

Expand Down
3 changes: 3 additions & 0 deletions targets/targets.json5
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,9 @@ mode is recommended for target MCUs with small amounts of flash and RAM.",
"supported_toolchains": [
"GCC_ARM"
],
"macros": [
"MBED_SPLIT_HEAP"
],
"device_has": [
"RTC",
"USTICKER",
Expand Down
Loading