Enable Arduino Nano 33 BLE (#55)

* Add upload target for Arduino Nano 33 BLE, fix linker script preprocessing, add option for USB serial by default

* astyle error

* Use HINTS instead of PATHS so that the Arduino dir is searched first

* Enable OpenOCD and PyOCD for Nano 33 BLE in SWD mode

* Fix missing dependency for USB tests on Windows

* Add RAM defines for nrf52840

* Fix mbed-storage-kv-config depending on SD card library even if said library was not enabled

* Update dsrdtr value

* No longer need to modify linker script now that we aren't using whole-archive!

* Add OPENOCD_ADAPTER_SERIAL

* Add handling for cmsis dap

* Fix typo

* Fix weak symbol issue causing Bluetooth to not work.  In this case, the weak implementation can simply be removed, because there's no legitimate case where it is used.
pull/15339/head
Jamie Smith 2022-10-16 10:32:38 -07:00 committed by GitHub
parent ce093f1785
commit 32a9080c7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 269 additions and 72 deletions

View File

@ -273,7 +273,7 @@ if(NOT MBED_IS_NATIVE_BUILD)
mbed_create_distro(mbed-os ${MBED_TARGET_CMAKE_NAME} mbed-core-flags mbed-core-sources mbed-rtos-flags mbed-rtos-sources)
# Set up the linker script and hook it up to the top-level OS targets
mbed_setup_linker_script(mbed-baremetal mbed-os)
mbed_setup_linker_script(mbed-baremetal mbed-os ${CMAKE_CURRENT_BINARY_DIR}/mbed-target-config.h)
# Make sure that things linking mbed-core-flags can also get the target-specific include dirs and flags.
mbed_extract_flags(${MBED_TARGET_CMAKE_NAME}-flags ${MBED_TARGET_CMAKE_NAME})

View File

@ -70,17 +70,10 @@ uint8_t *SystemHeapStart;
uint32_t SystemHeapSize;
/**
* Weak definition of ble_cordio_get_hci_driver.
* A runtime error is generated if the user does not define any
* ble_cordio_get_hci_driver.
* Function to get the device's default driver implementation.
* Defined by whichever driver library is used.
*/
MBED_WEAK ble::CordioHCIDriver &ble_cordio_get_hci_driver()
{
MBED_ASSERT("No HCI driver");
printf("Please provide an implementation for the HCI driver");
ble::CordioHCIDriver *bad_instance = nullptr;
return *bad_instance;
}
ble::CordioHCIDriver &ble_cordio_get_hci_driver();
/**
* Low level HCI interface between Cordio stack and the port.

View File

@ -261,7 +261,7 @@ class USBSerialTest(mbed_host_tests.BaseHostTest):
New line coding params are read from the device serial data.
"""
mbed_serial = serial.Serial(timeout=0.5, dsrdtr=False)
mbed_serial = serial.Serial(timeout=0.5, dsrdtr=True)
mbed_serial.dtr = False
try:
mbed_serial.port = retry_fun_call(

View File

@ -56,3 +56,8 @@ if(MBED_TOOLCHAIN STREQUAL "GCC_ARM" AND MBED_C_LIB STREQUAL "small")
newlib_nano_malloc_workaround.c
)
endif()
if("MBED_CONF_TARGET_CONSOLE_USB=1" IN_LIST MBED_CONFIG_DEFINITIONS)
# If the stdio console uses USB, we need to link mbed-usb into the default OS build
target_link_libraries(mbed-core-flags INTERFACE mbed-usb)
endif()

View File

@ -21,6 +21,7 @@
#endif
#include <mstd_mutex>
#include <mstd_atomic>
#include <time.h>
#include "platform/platform.h"
#include "platform/FilePath.h"
@ -49,6 +50,11 @@
#include <errno.h>
#include "platform/mbed_retarget.h"
// Need to use the USBSerial class for this config option
#if MBED_CONF_TARGET_CONSOLE_USB
#include "USBSerial.h"
#endif
static SingletonPtr<rtos::Mutex> _mutex;
/* DIR is typedeffed to struct DIR_impl in header */
@ -355,6 +361,22 @@ static FileHandle *default_console()
static const serial_pinmap_t console_pinmap = get_uart_pinmap(CONSOLE_TX, CONSOLE_RX);
static DirectSerial console(console_pinmap, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
# endif
#elif MBED_CONF_TARGET_CONSOLE_USB
// Sanity check that we have USB
#if !defined(DEVICE_USBDEVICE)
#error "target.console_usb enabled on device without USB! Something is wrong here."
#endif
static mstd::atomic<bool> consoleInitialized(false);
static USBSerial console(false); // Do not connect in blocking mode, otherwise the code won't start until USB is connected
bool uninitializedVal = false;
if (consoleInitialized.compare_exchange_strong(uninitializedVal, true)) {
console.connect();
}
#else // MBED_CONF_TARGET_CONSOLE_UART && DEVICE_SERIAL
static Sink console;
#endif

View File

@ -24,6 +24,4 @@ target_link_libraries(mbed-storage-kv-config
mbed-storage-securestore
mbed-storage-littlefs
mbed-storage-fat
mbed-storage-flashiap
mbed-storage-sd
)

View File

@ -72,3 +72,6 @@ target_link_libraries(mbed-arduino-nano33ble INTERFACE mbed-mcu-nrf52840)
target_link_libraries(mbed-ep-agora INTERFACE mbed-mcu-nrf52840)
target_link_libraries(mbed-ep-atlas INTERFACE mbed-mcu-nrf52840)
target_link_libraries(mbed-nrf52840-dk INTERFACE mbed-mcu-nrf52840)
# ARDUINO_NANO33BLE_SWD is the same as the non-SWD one, just with different defines in the linker script.
add_library(mbed-arduino-nano33ble-swd ALIAS mbed-arduino-nano33ble)

View File

@ -35,6 +35,20 @@
#define NVIC_NUM_VECTORS (16 + 48) // CORE + MCU Peripherals
#define NVIC_USER_IRQ_OFFSET 16
// RAM size defines, same as in the linker script
#if !defined(MBED_APP_START)
#define MBED_APP_START 0x0
#endif
#if !defined(MBED_APP_SIZE)
#define MBED_APP_SIZE 0x100000
#endif
#if !defined(MBED_RAM_START)
#define MBED_RAM_START 0x20000000
#define MBED_RAM_SIZE 0x40000
#endif
#include "nrf.h"
#include "cmsis.h"

View File

@ -34,9 +34,13 @@
],
"config": {
"console-uart": {
"help": "Target has UART console on pins CONSOLE_TX, CONSOLE_RX. Value is only significant if target has SERIAL device.",
"help": "Target has UART console on pins CONSOLE_TX, CONSOLE_RX. Value is only significant if target has SERIAL device. Mutually exclusive with target.console-usb.",
"value": true
},
"console-usb": {
"help": "Target has USB console on the default USB pins. Mutually exclusive with target.console-uart.",
"value": false
},
"console-uart-flow-control": {
"help": "Console hardware flow control. Options: null, RTS, CTS, RTSCTS.",
"value": null
@ -6935,7 +6939,6 @@
"5"
],
"device_name": "nRF52840_xxAA",
"OUTPUT_EXT": "hex",
"is_disk_virtual": true,
"supported_toolchains": [
"GCC_ARM",
@ -6997,10 +7000,34 @@
"ITM"
],
"macros_add": [
"CONFIG_GPIO_AS_PINRESET"
"CONFIG_GPIO_AS_PINRESET",
"MBED_APP_START=0x10000",
"MBED_APP_SIZE=0xf0000"
],
"overrides": {
"console-usb": true,
"console-uart": false
},
"OUTPUT_EXT": "bin"
},
"ARDUINO_NANO33BLE_SWD": {
"inherits": [
"MCU_NRF52840"
],
"features_add": [
"STORAGE"
],
"components_remove": [
"QSPIF"
],
"device_has_remove": [
"QSPI",
"ITM"
],
"macros_add": [
"CONFIG_GPIO_AS_PINRESET"
]
},
"NUMAKER_PFM_NUC472": {
"core": "Cortex-M4F",
"components_add": [

View File

@ -0,0 +1,11 @@
# Mbed OS upload method configuration file for target ARDUINO_NANO33BLE.
# To change any of these parameters from their default values, set them in your build script between where you
# include app.cmake and where you add mbed os as a subdirectory.
# General config parameters
# -------------------------------------------------------------
set(UPLOAD_METHOD_DEFAULT ARDUINO_BOSSAC)
# Config options for ARDUINO_BOSSAC
# -------------------------------------------------------------
set(ARDUINO_BOSSAC_UPLOAD_ENABLED TRUE)

View File

@ -0,0 +1,27 @@
# Mbed OS upload method configuration file for target ARDUINO_NANO33BLE_SWD.
# To change any of these parameters from their default values, set them in your build script between where you
# include app.cmake and where you add mbed os as a subdirectory.
# Notes:
# 1. Using pyocd with this device requires installing a pack: `pyocd pack install nrf52`.
# General config parameters
# -------------------------------------------------------------
set(UPLOAD_METHOD_DEFAULT OPENOCD)
# Config options for PYOCD
# -------------------------------------------------------------
set(PYOCD_UPLOAD_ENABLED TRUE)
set(PYOCD_TARGET_NAME nrf52840)
set(PYOCD_CLOCK_SPEED 4000k)
# Config options for OPENOCD
# -------------------------------------------------------------
set(OPENOCD_UPLOAD_ENABLED TRUE)
set(OPENOCD_CHIP_CONFIG_COMMANDS
-f ${OpenOCD_SCRIPT_DIR}/interface/cmsis-dap.cfg
-c "transport select swd"
-f ${OpenOCD_SCRIPT_DIR}/target/nrf52.cfg)

View File

@ -21,7 +21,11 @@ endfunction(mbed_set_linker_script)
# Set up the linker script for the top-level Mbed OS targets.
# If needed, this also creates another target to preprocess the linker script.
#
function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target)
# mbed_os_target: CMake target for Mbed OS
# mbed_baremetal_target: CMake target for Mbed Baremetal
# target_defines_header: the full path to the header containing all of the Mbed target defines
#
function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target target_defines_header)
# Find the path to the desired linker script
# (the property should be set on both the OS and baremetal targets in a sane world)
@ -45,53 +49,42 @@ function(mbed_setup_linker_script mbed_os_target mbed_baremetal_target)
# global property. We need this solely to pass the compile definitions to GCC's preprocessor,
# so it can expand any macro definitions in the linker script.
get_property(linker_defs_response_file GLOBAL PROPERTY COMPILE_DEFS_RESPONSE_FILE)
if(MBED_TOOLCHAIN STREQUAL "GCC_ARM")
get_filename_component(RAW_LINKER_SCRIPT_NAME ${RAW_LINKER_SCRIPT_PATHS} NAME)
get_filename_component(LINKER_SCRIPT_NAME ${LINKER_SCRIPT_PATH} NAME)
add_custom_command(
OUTPUT
${LINKER_SCRIPT_PATH}
PRE_LINK
COMMAND
${CMAKE_C_COMPILER} @${linker_defs_response_file}
-E -x assembler-with-cpp
-P ${RAW_LINKER_SCRIPT_PATHS}
-o ${LINKER_SCRIPT_PATH}
DEPENDS
${RAW_LINKER_SCRIPT_PATHS}
${linker_defs_response_file}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
COMMENT
"Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
VERBATIM
get_filename_component(RAW_LINKER_SCRIPT_NAME ${RAW_LINKER_SCRIPT_PATHS} NAME)
get_filename_component(LINKER_SCRIPT_NAME ${LINKER_SCRIPT_PATH} NAME)
add_custom_command(
OUTPUT
${LINKER_SCRIPT_PATH}
PRE_LINK
COMMAND
${CMAKE_C_COMPILER} @${linker_defs_response_file}
-E -x assembler-with-cpp
-include ${target_defines_header}
-P ${RAW_LINKER_SCRIPT_PATHS}
-o ${LINKER_SCRIPT_PATH}
DEPENDS
${RAW_LINKER_SCRIPT_PATHS}
${linker_defs_response_file}
${target_defines_header}
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
COMMENT
"Preprocess linker script: ${RAW_LINKER_SCRIPT_NAME} -> ${LINKER_SCRIPT_NAME}"
VERBATIM
)
# The job to create the linker script gets attached to the mbed-linker-script target,
# which is then added as a dependency of the MCU target. This ensures the linker script will exist
# by the time we need it.
add_custom_target(mbed-linker-script DEPENDS ${LINKER_SCRIPT_PATH} VERBATIM)
foreach(TARGET ${mbed_baremetal_target} ${mbed_os_target})
add_dependencies(${TARGET} mbed-linker-script)
# Add linker flags to the MCU target to pick up the preprocessed linker script
target_link_options(${TARGET}
INTERFACE
"-T" "${LINKER_SCRIPT_PATH}"
)
endforeach()
# The job to create the linker script gets attached to the mbed-linker-script target,
# which is then added as a dependency of the MCU target. This ensures the linker script will exist
# by the time we need it.
add_custom_target(mbed-linker-script DEPENDS ${LINKER_SCRIPT_PATH} VERBATIM)
foreach(TARGET ${mbed_baremetal_target} ${mbed_os_target})
add_dependencies(${TARGET} mbed-linker-script)
# Add linker flags to the MCU target to pick up the preprocessed linker script
target_link_options(${TARGET}
INTERFACE
"-T" "${LINKER_SCRIPT_PATH}"
)
endforeach()
elseif(MBED_TOOLCHAIN STREQUAL "ARM")
foreach(TARGET ${mbed_baremetal_target} ${mbed_os_target})
target_link_options(${TARGET}
INTERFACE
"--scatter=${raw_linker_script_path}"
"--predefine=${_linker_preprocess_definitions}"
"--map"
)
endforeach()
endif()
endfunction(mbed_setup_linker_script)

View File

@ -0,0 +1,38 @@
# Copyright (c) 2020 ARM Limited. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# ----------------------------------------------
# CMake finder for the Arduino variant of bossac
#
#
# This module defines:
# ArduinoBossac - full path to bossac executable
# ArduinoBossac_FOUND - whether or not the ArduinoBossac executable was found
set(ArduinoBossac_PATHS "")
# try to figure out where ArduinoBossac may be installed.
if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
# on Windows, assume that the user extracted the binaries to Program Files
# On my computer the path is C:\Users\jamie\AppData\Local\Arduino15\packages\arduino\tools\bossac\1.9.1-arduino2\bossac.exe
file(GLOB ArduinoBossac_PATHS "$ENV{LocalAppData}/Arduino*/packages/arduino/tools/bossac/1.9.1-arduino2")
else()
# Linux / Mac
# Per here: https://docs.zephyrproject.org/2.7.0/boards/arm/arduino_nano_33_ble/doc/index.html
# a possible path would be $HOME/.arduino15/packages/arduino/tools/bossac/1.9.1-arduino2/bossac
file(GLOB ArduinoBossac_PATHS "$ENV{HOME}/.arduino*/packages/arduino/tools/bossac/1.9.1-arduino2")
endif()
# if we found multiple paths, check the one with the highest version number first
list(SORT ArduinoBossac_PATHS)
list(REVERSE ArduinoBossac_PATHS)
find_program(ArduinoBossac NAMES bossac HINTS ${ArduinoBossac_PATHS} DOC "Path to the Arduino variant of bossac")
find_package_handle_standard_args(ArduinoBossac REQUIRED_VARS ArduinoBossac)

View File

@ -0,0 +1,33 @@
### Arduino Bossac upload method
### This method can be used for boards with Arduino bootloaders that talk to the bossac flash program.
# This method creates the following options:
# ARDUINO_BOSSAC_SERIAL_PORT - Serial port to talk to the device bootloader on, e.g. "COM7"
set(UPLOAD_SUPPORTS_DEBUG FALSE)
### Check if upload method can be enabled on this machine
find_package(ArduinoBossac)
set(UPLOAD_ARDUINO_BOSSAC_FOUND ${ArduinoBossac_FOUND})
### Set up options
set(ARDUINO_BOSSAC_SERIAL_PORT "" CACHE STRING "Serial port to talk to the device bootloader on, e.g. 'COM7'")
if("${ARDUINO_BOSSAC_SERIAL_PORT}" STREQUAL "")
message(WARNING "Please set ARDUINO_BOSSAC_SERIAL_PORT to the serial port to communicate with the target bootloader on. Until this is set, flashing will not work.")
endif()
### Function to generate upload target
function(gen_upload_target TARGET_NAME BIN_FILE)
add_custom_target(flash-${TARGET_NAME}
COMMAND ${ArduinoBossac}
--debug
--port=${ARDUINO_BOSSAC_SERIAL_PORT}
--usb-port=1
--info
--erase
--write ${BIN_FILE}
--reset)
add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME})
endfunction(gen_upload_target)

View File

@ -4,6 +4,8 @@
### OpenOCD Upload Method
# This method needs the following parameters:
# OPENOCD_CHIP_CONFIG_COMMANDS - Specifies all OpenOCD commands needed to configure openocd for your target processor.
# This method creates the following options:
# OPENOCD_ADAPTER_SERIAL - Serial number of the debug adapter to select for OpenOCD. Set to empty to detect any matching adapter.
set(UPLOAD_SUPPORTS_DEBUG TRUE)
@ -11,7 +13,32 @@ set(UPLOAD_SUPPORTS_DEBUG TRUE)
find_package(OpenOCD)
set(UPLOAD_OPENOCD_FOUND ${OpenOCD_FOUND})
### Setup options
set(OPENOCD_ADAPTER_SERIAL "" CACHE STRING "Serial number of the debug adapter to select for OpenOCD. Set to empty to detect any matching adapter.")
### Function to generate upload target
set(OPENOCD_ADAPTER_SERIAL_COMMAND "")
if(NOT "${OPENOCD_ADAPTER_SERIAL}" STREQUAL "")
# Generate script file that tells OpenOCD how to find the correct debug adapter.
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/openocd_adapter_config.cfg CONTENT
"# Script to select the correct debug adapter with OpenOCD.
# This file is generated by UploadMethodOPENOCD.cmake. Your edits will be overwritten.
# There's supposed to be a standard command to select the adapter serial ('adapter serial'), but it seems
# like not all adapters support this yet so extra work is needed.
set adapter_serial \"${OPENOCD_ADAPTER_SERIAL}\"
if { [adapter name] == \"hla\" } {
hla_serial $adapter_serial
} elseif { [adapter name] == \"cmsis-dap\" } {
cmsis_dap_serial $adapter_serial
} else {
adapter serial $adapter_serial
}")
set(OPENOCD_ADAPTER_SERIAL_COMMAND -f ${CMAKE_BINARY_DIR}/openocd_adapter_config.cfg)
endif()
function(gen_upload_target TARGET_NAME BIN_FILE)
# unlike other upload methods, OpenOCD uses the elf file
@ -19,7 +46,9 @@ function(gen_upload_target TARGET_NAME BIN_FILE)
COMMENT "Flashing ${TARGET_NAME} with OpenOCD..."
COMMAND ${OpenOCD}
${OPENOCD_CHIP_CONFIG_COMMANDS}
-c "program $<TARGET_FILE:${TARGET_NAME}> reset exit")
${OPENOCD_ADAPTER_SERIAL_COMMAND}
-c "program $<TARGET_FILE:${TARGET_NAME}> reset exit"
VERBATIM)
add_dependencies(flash-${TARGET_NAME} ${TARGET_NAME})
endfunction(gen_upload_target)
@ -30,5 +59,7 @@ add_custom_target(gdbserver
COMMAND
${OpenOCD}
${OPENOCD_CHIP_CONFIG_COMMANDS}
${OPENOCD_ADAPTER_SERIAL_COMMAND}
-c "gdb_port ${GDB_PORT}"
USES_TERMINAL)
USES_TERMINAL
VERBATIM)

View File

@ -6,7 +6,7 @@
# PYOCD_TARGET_NAME - Name of your processor as passed to the -t option of pyOCD. This is usually the full or partial model number.
# PYOCD_CLOCK_SPEED - Clock speed of the JTAG or SWD connection. Default is in Hz, but can use k and M suffixes for MHz and GHz
# This method creates the following options:
# PYOCD_PROBE_UID - Probe UID to pass to pyOCD commands. You can get the UIDs from `python -m pyocd list`.
# PYOCD_PROBE_UID - Probe UID to pass to pyOCD commands. You can get the UIDs from `python -m pyocd list`. Set to empty to detect any probe.
set(UPLOAD_SUPPORTS_DEBUG TRUE)
@ -15,12 +15,13 @@ include(CheckPythonPackage)
check_python_package(pyocd HAVE_PYOCD)
set(UPLOAD_PYOCD_FOUND ${HAVE_PYOCD})
### Setup options
set(PYOCD_PROBE_UID "" CACHE STRING "Probe UID to pass to pyOCD commands. You can get the UIDs from `python -m pyocd list`. Set to empty to detect any probe.")
### Function to generate upload target
set(PYOCD_PROBE_ARGS "")
if(DEFINED PYOCD_PROBE_UID)
if(NOT "${PYOCD_PROBE_UID}" STREQUAL "")
set(PYOCD_PROBE_ARGS --probe ${PYOCD_PROBE_UID})
endif()
if(NOT "${PYOCD_PROBE_UID}" STREQUAL "")
set(PYOCD_PROBE_ARGS --probe ${PYOCD_PROBE_UID})
endif()
function(gen_upload_target TARGET_NAME BIN_FILE)

View File

@ -6,4 +6,5 @@ mbed-ls
# For USB Device host tests
hidapi>=0.7.99
pyusb>=1.2.0
pyusb>=1.2.0
wmi>=1.5; platform_system == "Windows"