[beken-72xx] Implement SDK binary building
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"build": {
|
||||
"bkcrypt_coeffs": "510fb093a3cbeadc5993a17ec7adeb03",
|
||||
"bkboot_version": "1.0.5-bk7231s"
|
||||
"bkboot_version": "1.0.5-bk7231s",
|
||||
"bkrbl_size_app": "0x107800"
|
||||
},
|
||||
"flash": {
|
||||
"bootloader": "0x000000+0x11000",
|
||||
|
||||
551
builder/frameworks/beken-72xx-sdk.py
Normal file
551
builder/frameworks/beken-72xx-sdk.py
Normal file
@@ -0,0 +1,551 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-06-13.
|
||||
|
||||
from os.path import join
|
||||
|
||||
from SCons.Script import Builder, DefaultEnvironment
|
||||
|
||||
env = DefaultEnvironment()
|
||||
board = env.BoardConfig()
|
||||
|
||||
ROOT_DIR = join("$SDK_DIR", "beken378")
|
||||
APP_DIR = join(ROOT_DIR, "app")
|
||||
DRIVER_DIR = join(ROOT_DIR, "driver")
|
||||
FUNC_DIR = join(ROOT_DIR, "func")
|
||||
|
||||
# Load sys_config.h into env
|
||||
env.LoadConfig(join("$FAMILY_DIR", "fixups", "sys_config.h"))
|
||||
|
||||
# Define vars used during build
|
||||
SOC_BK7231 = 1
|
||||
SOC_BK7231U = 2
|
||||
SOC_BK7221U = 3
|
||||
SOC_BK7251 = 3
|
||||
SOC_BK7271 = 4
|
||||
SOC_BK7231N = 5
|
||||
SOC_BK7236 = 6
|
||||
SOC_NAMES = {
|
||||
SOC_BK7231: "bk7231",
|
||||
SOC_BK7231U: "bk7231u",
|
||||
SOC_BK7221U: "bk7221u",
|
||||
SOC_BK7271: "bk7271",
|
||||
SOC_BK7231N: "bk7231n",
|
||||
SOC_BK7236: "bk7236",
|
||||
}
|
||||
SOC = env.Cfg("CFG_SOC_NAME")
|
||||
WPA_VERSION = "wpa_supplicant_2_9" if env.Cfg("CFG_USE_WPA_29") else "hostapd-2.5"
|
||||
|
||||
# Flags
|
||||
env.Append(
|
||||
CCFLAGS=[
|
||||
"-mcpu=arm968e-s",
|
||||
"-march=armv5te",
|
||||
"-mthumb",
|
||||
"-mthumb-interwork",
|
||||
"-g",
|
||||
"-O2",
|
||||
"-fdata-sections",
|
||||
"-ffunction-sections",
|
||||
"-fno-strict-aliasing",
|
||||
"-fsigned-char",
|
||||
"-Wno-comment",
|
||||
],
|
||||
CFLAGS=[
|
||||
"-std=c99",
|
||||
"-nostdlib",
|
||||
"-Wall",
|
||||
"-Wno-format",
|
||||
"-Wno-unknown-pragmas",
|
||||
],
|
||||
CPPDEFINES=[
|
||||
# LibreTuya configuration
|
||||
# (reserved)
|
||||
# SDK options
|
||||
("CFG_OS_FREERTOS", "1"),
|
||||
("MBEDTLS_CONFIG_FILE", "<tls_config.h>"),
|
||||
("WIFI_BLE_COEXIST", "1"),
|
||||
("WOLFSSL_BEKEN", env.Cfg("CFG_WPA3")),
|
||||
],
|
||||
ASFLAGS=[
|
||||
"-mcpu=arm968e-s",
|
||||
"-march=armv5te",
|
||||
"-marm",
|
||||
"-mthumb-interwork",
|
||||
"-g",
|
||||
"-x",
|
||||
"assembler-with-cpp",
|
||||
],
|
||||
LINKFLAGS=[
|
||||
"-mcpu=arm968e-s",
|
||||
"-marm",
|
||||
"-mthumb-interwork",
|
||||
"-g",
|
||||
"-nostdlib",
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,-wrap,_free_r",
|
||||
"-Wl,-wrap,_malloc_r",
|
||||
"-Wl,-wrap,calloc",
|
||||
"-Wl,-wrap,free",
|
||||
"-Wl,-wrap,malloc",
|
||||
"-Wl,-wrap,realloc",
|
||||
"-Wl,-wrap,zalloc",
|
||||
"-Wl,-wrap,_realloc_r",
|
||||
"-Wl,-wrap,printf",
|
||||
"-Wl,-wrap,puts",
|
||||
"-Wl,-wrap,snprintf",
|
||||
"-Wl,-wrap,sprintf",
|
||||
"-Wl,-wrap,vsnprintf",
|
||||
],
|
||||
)
|
||||
|
||||
# Sources - from framework-beken-bdk/beken378/beken_src.mk
|
||||
env.AddLibrary(
|
||||
name="bdk_core",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
"+<app/app.c>",
|
||||
"+<app/ate_app.c>",
|
||||
"+<app/config/param_config.c>",
|
||||
"+<demo/*.c>",
|
||||
"+<driver/driver.c>",
|
||||
"+<driver/entry/arch_main.c>",
|
||||
"+<driver/entry/boot_handlers.S>",
|
||||
"+<driver/entry/boot_vectors.S>",
|
||||
"+<driver/intc/intc.c>",
|
||||
"+<func/func.c>",
|
||||
"+<func/wlan_ui/bk_peripheral_test.c>",
|
||||
"+<func/wlan_ui/wlan_cli.c>",
|
||||
"+<func/wlan_ui/wlan_ui.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<app>",
|
||||
"+<app/config>",
|
||||
"+<common>",
|
||||
"+<demo>",
|
||||
"+<driver/entry>",
|
||||
"+<driver/intc>",
|
||||
"+<release>",
|
||||
"+<../release>",
|
||||
],
|
||||
)
|
||||
|
||||
# Sources - app module
|
||||
env.AddLibrary(
|
||||
name="bdk_app",
|
||||
base_dir=APP_DIR,
|
||||
srcs=[
|
||||
"+<http/*.c>",
|
||||
"+<net_work/*.c>",
|
||||
"+<standalone-ap/*.c>",
|
||||
"+<standalone-station/*.c>",
|
||||
"+<video_work/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<http>",
|
||||
"+<net_work>",
|
||||
"+<standalone-ap>",
|
||||
"+<standalone-station>",
|
||||
"+<video_work>",
|
||||
],
|
||||
)
|
||||
|
||||
# Sources - drivers
|
||||
env.AddLibrary(
|
||||
name="bdk_driver",
|
||||
base_dir=DRIVER_DIR,
|
||||
srcs=[
|
||||
"+<calendar/*.c>",
|
||||
"+<common/*.c>",
|
||||
"+<dma/*.c>",
|
||||
"+<fft/*.c>",
|
||||
"+<flash/*.c>",
|
||||
"+<general_dma/*.c>",
|
||||
"+<gpio/*.c>",
|
||||
"+<i2c/*.c>",
|
||||
"+<i2s/*.c>",
|
||||
"+<icu/*.c>",
|
||||
"+<irda/*.c>",
|
||||
"+<jpeg/*.c>",
|
||||
"+<macphy_bypass/*.c>",
|
||||
"+<phy/*.c>",
|
||||
"+<pwm/*.c>",
|
||||
"-<pwm/pwm_bk7271.c>",
|
||||
"-<pwm/pwm_new.c>",
|
||||
"+<qspi/*.c>",
|
||||
"+<rw_pub/*.c>",
|
||||
"+<saradc/*.c>",
|
||||
"+<security/*.c>",
|
||||
"+<spidma/*.c>",
|
||||
"+<sys_ctrl/*.c>",
|
||||
"+<uart/*.c>",
|
||||
"+<wdt/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<common>",
|
||||
"+<common/reg>",
|
||||
"+<dma>",
|
||||
"+<flash>",
|
||||
"+<general_dma>",
|
||||
"+<gpio>",
|
||||
"+<i2c>",
|
||||
"+<icu>",
|
||||
"+<include>",
|
||||
"+<jpeg>",
|
||||
"+<phy>",
|
||||
"+<pwm>",
|
||||
"+<rc_beken>",
|
||||
"+<rw_pub>",
|
||||
"+<spi>",
|
||||
"+<spidma>",
|
||||
"+<sys_ctrl>",
|
||||
"+<uart>",
|
||||
"+<usb>",
|
||||
"+<../ip/**>",
|
||||
],
|
||||
)
|
||||
|
||||
# Sources - functional components
|
||||
env.AddLibrary(
|
||||
name="bdk_func",
|
||||
base_dir=FUNC_DIR,
|
||||
srcs=[
|
||||
"+<airkiss/*.c>",
|
||||
"+<base64/*.c>",
|
||||
"+<ble_wifi_exchange/*.c>",
|
||||
"+<camera_intf/*.c>",
|
||||
"+<hostapd_intf/*.c>",
|
||||
"+<joint_up/*.c>",
|
||||
"+<misc/*.c>",
|
||||
"+<net_param_intf/*.c>",
|
||||
"+<power_save/*.c>",
|
||||
"+<rwnx_intf/*.c>",
|
||||
"+<saradc_intf/*.c>",
|
||||
"+<security/*.c>",
|
||||
"+<sim_uart/*.c>",
|
||||
"+<spidma_intf/*.c>",
|
||||
"+<temp_detect/*.c>",
|
||||
"+<usb_plug/*.c>",
|
||||
"+<user_driver/*.c>",
|
||||
"-<user_driver/BkDriverQspi.c>",
|
||||
"+<utf8/*.c>",
|
||||
"+<video_transfer/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<base64>",
|
||||
"+<ble_wifi_exchange>",
|
||||
"+<camera_intf>",
|
||||
"+<easy_flash>",
|
||||
"+<easy_flash/inc>",
|
||||
"+<easy_flash/port>",
|
||||
"+<ethernet_intf>",
|
||||
"+<include>",
|
||||
"+<joint_up>",
|
||||
"+<power_save>",
|
||||
"+<rf_test>",
|
||||
"+<rf_use>",
|
||||
"+<rwnx_intf>",
|
||||
"+<saradc_intf>",
|
||||
"+<sensor>",
|
||||
"+<spidma_intf>",
|
||||
"+<temp_detect>",
|
||||
"+<uart_debug>",
|
||||
"+<usb>",
|
||||
"+<user_driver>",
|
||||
"+<utf8>",
|
||||
"+<video_transfer>",
|
||||
f"+<{WPA_VERSION}/bk_patch>",
|
||||
f"+<{WPA_VERSION}/hostapd>",
|
||||
f"+<{WPA_VERSION}/src>",
|
||||
f"+<{WPA_VERSION}/src/ap>",
|
||||
f"+<{WPA_VERSION}/src/common>",
|
||||
f"+<{WPA_VERSION}/src/drivers>",
|
||||
f"+<{WPA_VERSION}/src/utils>",
|
||||
f"+<{WPA_VERSION}/wpa_supplicant>",
|
||||
],
|
||||
)
|
||||
|
||||
# Sources - FreeRTOS
|
||||
env.AddLibrary(
|
||||
name="bdk_freertos_thumb",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
"+<os/**/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<os/*>",
|
||||
],
|
||||
)
|
||||
env.AddLibrary(
|
||||
name="bdk_freertos_arm",
|
||||
base_dir="$SDK_DIR",
|
||||
srcs=[
|
||||
"+<FreeRTOSv9.0.0/FreeRTOS/Source/**/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<FreeRTOSv9.0.0/FreeRTOS/Source/include>",
|
||||
"+<FreeRTOSv9.0.0/FreeRTOS/Source/portable/Keil/ARM968es>",
|
||||
],
|
||||
options=dict(
|
||||
CCFLAGS=[
|
||||
# build FreeRTOS port in ARM mode
|
||||
"+<-marm>",
|
||||
"-<-mthumb>",
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
# Sources - lwIP 2.0.2
|
||||
env.AddLibrary(
|
||||
name="bdk_lwip",
|
||||
base_dir=join(FUNC_DIR, "lwip_intf"),
|
||||
srcs=[
|
||||
"+<lwip-2.0.2/port/*.c>",
|
||||
"+<lwip-2.0.2/src/api/*.c>",
|
||||
"+<lwip-2.0.2/src/apps/ping/*.c>",
|
||||
"+<lwip-2.0.2/src/core/*.c>",
|
||||
"+<lwip-2.0.2/src/core/ipv4/*.c>",
|
||||
"+<lwip-2.0.2/src/core/ipv6/*.c>",
|
||||
"+<lwip-2.0.2/src/netif/ethernet.c>",
|
||||
"+<dhcpd/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<lwip-2.0.2/port>",
|
||||
"+<lwip-2.0.2/src/include>",
|
||||
"+<lwip-2.0.2/src/include/netif>",
|
||||
],
|
||||
options=dict(CCFLAGS=["-Wno-missing-braces"]),
|
||||
)
|
||||
|
||||
# Sources - mbedTLS 2.6.0
|
||||
env.AddLibrary(
|
||||
name="bdk_mbedtls",
|
||||
base_dir=join(FUNC_DIR, "mbedtls"),
|
||||
srcs=[
|
||||
"+<mbedtls/library/*.c>",
|
||||
"+<mbedtls_ui/*.c>",
|
||||
"+<mbedtls-port/src/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<mbedtls/include>",
|
||||
"+<mbedtls_ui>",
|
||||
"+<mbedtls-port/inc>",
|
||||
],
|
||||
options=dict(
|
||||
CCFLAGS=["-Wno-unused-variable"],
|
||||
CFLAGS=["-<-Wall>"],
|
||||
),
|
||||
)
|
||||
|
||||
# Sources - demos TODO remove this
|
||||
env.AddLibrary(
|
||||
name="bdk_demos",
|
||||
base_dir="$SDK_DIR",
|
||||
srcs=[
|
||||
"+<demos/**/*.c>",
|
||||
"-<demos/components/**/*.c>",
|
||||
"-<demos/net/mqtt/*>",
|
||||
"-<demos/wifi/bk_aware/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<demos>",
|
||||
"+<demos/**>",
|
||||
],
|
||||
)
|
||||
|
||||
# Sources - chip-specific drivers
|
||||
if SOC in [SOC_BK7231U, SOC_BK7251]:
|
||||
env.AddLibrary(
|
||||
name="bdk_driver_spi",
|
||||
base_dir=join(DRIVER_DIR, "spi"),
|
||||
srcs=[
|
||||
"+<spi.c>",
|
||||
"+<spi_master.c>",
|
||||
"+<spi_slave.c>",
|
||||
],
|
||||
)
|
||||
if SOC in [SOC_BK7231N]:
|
||||
env.AddLibrary(
|
||||
name="bdk_driver_spi",
|
||||
base_dir=join(DRIVER_DIR, "spi"),
|
||||
srcs=[
|
||||
"+<spi_bk7231n.c>",
|
||||
"+<spi_master_bk7231n.c>",
|
||||
"+<spi_slave_bk7231n.c>",
|
||||
],
|
||||
)
|
||||
if SOC in [SOC_BK7251]:
|
||||
env.AddLibrary(
|
||||
name="bdk_bk7251",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
"+<driver/audio/*.c>",
|
||||
"+<driver/sdcard/*.c>",
|
||||
"+<func/audio/*.c>",
|
||||
"+<func/sd_music/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<driver/audio>",
|
||||
"+<driver/sdcard>",
|
||||
],
|
||||
)
|
||||
|
||||
# Sources - enabled through config
|
||||
if env.Cfg("CFG_SDIO"):
|
||||
env.AddLibrary(
|
||||
name="bdk_driver_sdio",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
"+<driver/sdio/*.c>",
|
||||
"+<func/sdio_intf/*.c>",
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_BK_AWARE"):
|
||||
env.AddLibrary(
|
||||
name="bdk_driver_sdio",
|
||||
base_dir="$SDK_DIR",
|
||||
srcs=[
|
||||
"+<beken378/func/bk_aware/*.c>",
|
||||
"+<demos/wifi/bk_aware/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<beken378/func/bk_aware>",
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_USE_SDCARD_HOST"):
|
||||
env.AddLibrary(
|
||||
name="bdk_func_fatfs",
|
||||
base_dir=join(FUNC_DIR, "fatfs"),
|
||||
srcs=[
|
||||
"+<*.c>",
|
||||
"-<test_fatfs.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<.>",
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_WPA3"):
|
||||
env.AddLibrary(
|
||||
name="bdk_wolfssl",
|
||||
base_dir=join(FUNC_DIR, "wolfssl"),
|
||||
srcs=[
|
||||
"+<wolfcrypt/src/ecc.c>",
|
||||
"+<wolfcrypt/src/memory.c>",
|
||||
"+<wolfcrypt/src/random.c>",
|
||||
"+<wolfcrypt/src/sha256.c>",
|
||||
"+<wolfcrypt/src/tfm.c>",
|
||||
"+<wolfcrypt/src/wolfmath.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<.>",
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_SUPPORT_BLE") and env.Cfg("CFG_BLE_VERSION") == env.Cfg(
|
||||
"BLE_VERSION_4_2"
|
||||
):
|
||||
env.AddLibrary(
|
||||
name="bdk_ble_4_2",
|
||||
base_dir=join(DRIVER_DIR, "ble"),
|
||||
srcs=[
|
||||
"+<**/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<.>",
|
||||
"+<**/include>",
|
||||
"+<beken_ble_sdk/mesh/src/dbg>",
|
||||
"+<config>",
|
||||
"+<modules/**>",
|
||||
"+<plactform/arch>",
|
||||
"+<plactform/driver/*>",
|
||||
"+<profiles/*/api>",
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_SUPPORT_BLE") and env.Cfg("CFG_BLE_VERSION") == env.Cfg(
|
||||
"BLE_VERSION_5_x"
|
||||
):
|
||||
env.AddLibrary(
|
||||
name="bdk_ble_5_x",
|
||||
base_dir=join(DRIVER_DIR, "ble_5_x_rw"),
|
||||
srcs=[
|
||||
"+<**/*.c>",
|
||||
"-<ble_pub/app/src/app_ble_task.c>",
|
||||
"-<platform/7231n/nvds/src/nvds.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<**/api>",
|
||||
"+<arch/**>",
|
||||
"+<ble_lib/ip/ble/**>",
|
||||
"+<ble_lib/ip/hci/src>",
|
||||
"+<ble_lib/ip/sch/import>",
|
||||
"+<ble_lib/modules/*/src>",
|
||||
"+<ble_pub/prf>",
|
||||
"+<ble_pub/ui>",
|
||||
"+<platform/7231n/**>",
|
||||
"-<platform/7231n/nvds/**>",
|
||||
],
|
||||
)
|
||||
if env.Cfg("ATSVR_CFG"):
|
||||
env.AddLibrary(
|
||||
name="bdk_atsvr",
|
||||
base_dir=join(FUNC_DIR, "at_server"),
|
||||
srcs=[
|
||||
"+<**/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<.>",
|
||||
"+<*>",
|
||||
],
|
||||
)
|
||||
if env.Cfg("CFG_USB"):
|
||||
env.AddLibrary(
|
||||
name="bdk_driver_usb",
|
||||
base_dir=ROOT_DIR,
|
||||
srcs=[
|
||||
"+<driver/usb/*.c>",
|
||||
"+<func/usb/*.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<driver/usb/**>",
|
||||
],
|
||||
)
|
||||
|
||||
# Libs & linker config
|
||||
env.Append(
|
||||
LIBPATH=[
|
||||
join("$SDK_DIR", "beken378", "lib"),
|
||||
join("$SDK_DIR", "beken378", "func", "airkiss"),
|
||||
],
|
||||
LIBS=[
|
||||
"airkiss",
|
||||
"sensor",
|
||||
"usb",
|
||||
# "wpa", # this is compiled from func/hostapd_intf/hostapd_intf.c
|
||||
f"ble_{SOC_NAMES[SOC]}",
|
||||
f"cal_{SOC_NAMES[SOC]}",
|
||||
f"rf_test_{SOC_NAMES[SOC]}",
|
||||
f"rf_use_{SOC_NAMES[SOC]}",
|
||||
f"rwnx_{SOC_NAMES[SOC]}",
|
||||
f"supplicant_{SOC_NAMES[SOC]}",
|
||||
f"uart_debug_{SOC_NAMES[SOC]}",
|
||||
"gcc",
|
||||
"g",
|
||||
"c",
|
||||
"m",
|
||||
"nosys",
|
||||
],
|
||||
)
|
||||
|
||||
# Misc options
|
||||
env.Replace(
|
||||
SIZEPROGREGEXP=r"^(?:\.vectors|\.text|\.rodata|\.data|\.ARM\.exidx)\s+([0-9]+).*",
|
||||
SIZEDATAREGEXP=r"^(?:\.vectors|\.data|\.bss)\s+([0-9]+).*",
|
||||
SIZECHECKCMD="$SIZETOOL -A -d $SOURCES",
|
||||
SIZEPRINTCMD="$SIZETOOL -B -d $SOURCES",
|
||||
)
|
||||
|
||||
# Build all libraries
|
||||
env.BuildLibraries()
|
||||
|
||||
# Main firmware outputs and actions
|
||||
env.Replace(
|
||||
# linker command (encryption + packaging)
|
||||
LINK="${LINK2BIN} ${VARIANT} '' ''",
|
||||
)
|
||||
@@ -9,8 +9,7 @@ board = env.BoardConfig()
|
||||
|
||||
# Flags
|
||||
env.Append(
|
||||
CFLAGS=[
|
||||
"-std=gnu99",
|
||||
CCFLAGS=[
|
||||
"-mcpu=cortex-m4",
|
||||
"-mthumb",
|
||||
"-mfloat-abi=hard",
|
||||
@@ -18,7 +17,6 @@ env.Append(
|
||||
"-g2",
|
||||
"-w",
|
||||
"-O2",
|
||||
"-Wno-pointer-sign",
|
||||
"-fdata-sections",
|
||||
"-ffunction-sections",
|
||||
"-fmessage-length=0",
|
||||
@@ -27,26 +25,16 @@ env.Append(
|
||||
"-fomit-frame-pointer",
|
||||
"-fsigned-char",
|
||||
],
|
||||
CFLAGS=[
|
||||
"-std=gnu99",
|
||||
"-Wno-pointer-sign",
|
||||
],
|
||||
CXXFLAGS=[
|
||||
# borrowed from RtlDuino/development/rtl87xx/platform.txt
|
||||
"-std=c++11",
|
||||
"-mcpu=cortex-m4",
|
||||
"-mthumb",
|
||||
"-mfloat-abi=hard",
|
||||
"-mfpu=fpv4-sp-d16",
|
||||
"-g2",
|
||||
"-w",
|
||||
"-O2",
|
||||
"-MMD",
|
||||
"-fdata-sections",
|
||||
"-ffunction-sections",
|
||||
"-fmessage-length=0",
|
||||
"-fno-common",
|
||||
"-fno-exceptions",
|
||||
"-fno-rtti",
|
||||
"-fno-short-enums",
|
||||
"-fomit-frame-pointer",
|
||||
"-fsigned-char",
|
||||
],
|
||||
CPPDEFINES=[
|
||||
# LibreTuya configuration
|
||||
@@ -316,7 +304,7 @@ env.BuildLibraries()
|
||||
# Main firmware outputs and actions
|
||||
env.Replace(
|
||||
# linker command (dual .bin outputs)
|
||||
LINK="${LINK2BIN} AMBZ xip1 xip2",
|
||||
LINK="${LINK2BIN} ${VARIANT} xip1 xip2",
|
||||
# default output .bin name
|
||||
IMG_FW="image_${FLASH_OTA1_OFFSET}.ota1.bin",
|
||||
# UF2OTA input list
|
||||
|
||||
@@ -12,6 +12,7 @@ board = env.BoardConfig()
|
||||
sys.path.insert(0, platform.get_dir())
|
||||
|
||||
# Utilities
|
||||
env.SConscript("utils/config.py", exports="env")
|
||||
env.SConscript("utils/env.py", exports="env")
|
||||
env.SConscript("utils/flash.py", exports="env")
|
||||
env.SConscript("utils/libs.py", exports="env")
|
||||
@@ -72,6 +73,8 @@ elif "IMG_FW" in env:
|
||||
target_fw = env.subst("$IMG_FW")
|
||||
env.AddPlatformTarget("upload", target_fw, env["UPLOAD_ACTIONS"], "Upload")
|
||||
else:
|
||||
sys.stderr.write("Warning! Firmware outputs not specified.\n")
|
||||
sys.stderr.write(
|
||||
"Warning! Firmware outputs not specified. Uploading is not possible.\n"
|
||||
)
|
||||
|
||||
Default(targets)
|
||||
|
||||
50
builder/utils/config.py
Normal file
50
builder/utils/config.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-06-13.
|
||||
|
||||
from os.path import isfile
|
||||
|
||||
from SCons.Script import DefaultEnvironment
|
||||
|
||||
env = DefaultEnvironment()
|
||||
|
||||
|
||||
def env_load_config(env, path):
|
||||
path = env.subst(path)
|
||||
if not isfile(path):
|
||||
raise FileNotFoundError("Config file not found")
|
||||
STRIP_CHARS = "\t "
|
||||
config = {}
|
||||
f = open(path, "r", encoding="utf-8")
|
||||
for line in f:
|
||||
line: str
|
||||
if not line.startswith("#define"):
|
||||
continue
|
||||
line = line[7:].strip(STRIP_CHARS)
|
||||
(key, value) = line.split(None, 2)
|
||||
value = value.strip(STRIP_CHARS)
|
||||
if value.isnumeric():
|
||||
value = int(value, 0)
|
||||
elif value.startswith('"') and value.endswith('"'):
|
||||
value = value[1:-1]
|
||||
else:
|
||||
# store defines as bytes
|
||||
value = value.encode()
|
||||
config[key] = value
|
||||
env.Append(
|
||||
CONFIG=config,
|
||||
)
|
||||
f.close()
|
||||
|
||||
|
||||
def env_get_config(env, key):
|
||||
config: dict = env["CONFIG"]
|
||||
if not config:
|
||||
return None
|
||||
value = config.get(key, None)
|
||||
while isinstance(value, bytes):
|
||||
value = config.get(value.decode(), None)
|
||||
return value
|
||||
|
||||
|
||||
env.AddMethod(env_load_config, "LoadConfig")
|
||||
env.AddMethod(env_get_config, "Cfg")
|
||||
env.AddMethod(env_get_config, "GetConfig")
|
||||
@@ -1,6 +1,6 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-05-04.
|
||||
|
||||
from os.path import isdir, join
|
||||
from os.path import join
|
||||
|
||||
from SCons.Script import DefaultEnvironment
|
||||
|
||||
@@ -43,13 +43,10 @@ def env_add_defaults(env, platform, board):
|
||||
env.Replace(**vars)
|
||||
# Store family parameters as environment variables
|
||||
env.Replace(**dict(family))
|
||||
# Check directories for validity
|
||||
for k, v in vars.items():
|
||||
if k.endswith("_DIR"):
|
||||
assert isdir(env.subst(v)), f"{env.subst(v)} is not a directory"
|
||||
# Default build options
|
||||
env.Prepend(
|
||||
CPPPATH=[
|
||||
"$LT_DIR/platform/common/fixups",
|
||||
"$BOARD_DIR",
|
||||
"$FAMILY_DIR/fixups",
|
||||
"$PARENT_DIR/fixups",
|
||||
|
||||
@@ -3,56 +3,66 @@
|
||||
import fnmatch
|
||||
from glob import glob
|
||||
from os.path import isdir, join
|
||||
from typing import List
|
||||
from typing import Dict, Generator, List, Tuple
|
||||
|
||||
from SCons.Script import DefaultEnvironment
|
||||
|
||||
env = DefaultEnvironment()
|
||||
|
||||
|
||||
def add_base_dir(env, base_dir: str, expressions: List[str], subst: bool = False):
|
||||
out = []
|
||||
for expr in expressions:
|
||||
if expr[1] != "<" or expr[-1] != ">":
|
||||
raise ValueError(f"Not a valid glob: {expr}")
|
||||
if expr[2] == "$":
|
||||
# do not append base path
|
||||
path = expr[2:-1]
|
||||
else:
|
||||
path = join(base_dir, expr[2:-1])
|
||||
if subst:
|
||||
path = env.subst(path)
|
||||
out.append(expr[0] + "<" + path + ">")
|
||||
return out
|
||||
|
||||
|
||||
def iter_expressions(expressions: List[str]) -> Generator[Tuple[str, str], None, None]:
|
||||
for expr in expressions:
|
||||
if expr[1] != "<" or expr[-1] != ">":
|
||||
yield ("+", expr)
|
||||
continue
|
||||
yield (expr[0], expr[2:-1])
|
||||
|
||||
|
||||
def env_add_library(
|
||||
env,
|
||||
name: str,
|
||||
base_dir: str,
|
||||
srcs: List[str],
|
||||
includes: List[str] = [],
|
||||
options: Dict[str, List[str]] = {},
|
||||
):
|
||||
name = env.subst(name)
|
||||
# add base dir to all source globs
|
||||
sources = []
|
||||
for src in srcs:
|
||||
if src[1] != "<" or src[-1] != ">":
|
||||
raise ValueError(f"Not a source glob: {src}")
|
||||
|
||||
if src[2] == "$": # do not append base path
|
||||
expr = src[2:-1]
|
||||
else:
|
||||
expr = join(base_dir, src[2:-1])
|
||||
|
||||
sources.append(src[0] + "<" + expr + ">")
|
||||
# add base dir to all globs
|
||||
srcs = add_base_dir(env, base_dir, srcs)
|
||||
includes = add_base_dir(env, base_dir, includes, subst=True)
|
||||
|
||||
# allow removing sources from parent builders
|
||||
key = f"LIB_{name.upper()}_SKIP"
|
||||
if key in env:
|
||||
for expr in env[key]:
|
||||
sources.append("-<" + expr + ">")
|
||||
srcs.append("-<" + expr + ">")
|
||||
|
||||
# queue library for further env clone and build
|
||||
env.Prepend(LIBQUEUE=[[join("$BUILD_DIR", name), base_dir, sources]])
|
||||
env.Prepend(
|
||||
LIBQUEUE=[
|
||||
(join("$BUILD_DIR", name), base_dir, srcs, options),
|
||||
]
|
||||
)
|
||||
|
||||
base_dir = env.subst(base_dir) # expand base_dir for includes
|
||||
for dir in includes:
|
||||
if dir[1] != "<" or dir[-1] != ">":
|
||||
env.Append(CPPPATH=[dir])
|
||||
continue
|
||||
|
||||
if dir[2] == "$": # do not append base path
|
||||
expr = dir[2:-1]
|
||||
else:
|
||||
expr = join(base_dir, dir[2:-1])
|
||||
expr = env.subst(expr)
|
||||
|
||||
if dir[0] == "-":
|
||||
# search all include paths
|
||||
for dir, expr in iter_expressions(includes):
|
||||
if dir == "-":
|
||||
for item in fnmatch.filter(env["CPPPATH"], expr):
|
||||
if item in env["CPPPATH"]:
|
||||
env["CPPPATH"].remove(item)
|
||||
@@ -60,7 +70,7 @@ def env_add_library(
|
||||
for item in glob(expr, recursive=True):
|
||||
if not isdir(item):
|
||||
continue
|
||||
if dir[0] == "!":
|
||||
if dir == "!":
|
||||
env.Prepend(CPPPATH=[item])
|
||||
else:
|
||||
env.Append(CPPPATH=[item])
|
||||
@@ -72,9 +82,23 @@ def env_build_libraries(env, safe: bool = True):
|
||||
return
|
||||
queue = env["LIBQUEUE"]
|
||||
env["LIBQUEUE"] = []
|
||||
envsafe = env.Clone() if safe else env
|
||||
for lib in queue:
|
||||
target = envsafe.BuildLibrary(*lib)
|
||||
envsafe = env.Clone() if safe else env
|
||||
# get env options to add/remove
|
||||
options: Dict[str, List[str]] = lib[3]
|
||||
# change only safe env options
|
||||
for key, values in options.items():
|
||||
for dir, value in iter_expressions(values):
|
||||
if dir == "+":
|
||||
envsafe.Append(**{key: [value]})
|
||||
elif dir == "!":
|
||||
envsafe.Prepend(**{key: [value]})
|
||||
elif dir == "-":
|
||||
if value not in envsafe[key]:
|
||||
raise ValueError(f"Invalid option; {value} is not in {key}")
|
||||
envsafe[key].remove(value)
|
||||
# build library with (name, base_dir, sources) options
|
||||
target = envsafe.BuildLibrary(*lib[0:3])
|
||||
env.Prepend(LIBS=[target])
|
||||
|
||||
|
||||
|
||||
5
platform/beken-7231t/fixups/inc/certs.h
Normal file
5
platform/beken-7231t/fixups/inc/certs.h
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-13. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mbedtls/certs.h>
|
||||
5
platform/beken-7231t/fixups/inc/netdb.h
Normal file
5
platform/beken-7231t/fixups/inc/netdb.h
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-13. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <lwip/netdb.h>
|
||||
5
platform/beken-7231t/fixups/inc/sockets.h
Normal file
5
platform/beken-7231t/fixups/inc/sockets.h
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-05-23. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <lwip/sockets.h>
|
||||
116
platform/beken-7231t/fixups/sys_config.h
Normal file
116
platform/beken-7231t/fixups/sys_config.h
Normal file
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
|
||||
#define BLE_DEFAULT_WIFI_REQUEST 2
|
||||
#define BLE_VERSION_4_2 1
|
||||
#define BLE_VERSION_5_x 2
|
||||
#define BLE_WIFI_CO_REQUEST 3
|
||||
#define CFG_AIRKISS_TEST 0
|
||||
#define CFG_AP_MONITOR_COEXIST 0
|
||||
#define CFG_AP_SUPPORT_HT_IE 0
|
||||
#define CFG_BACKGROUND_PRINT 0
|
||||
#define CFG_BK_AWARE 0
|
||||
#define CFG_BK_AWARE_OUI "\xC8\x47\x8C"
|
||||
#define CFG_BLE_VERSION BLE_VERSION_4_2
|
||||
#define CFG_EASY_FLASH 1
|
||||
#define CFG_ENABLE_BUTTON 0
|
||||
#define CFG_ENABLE_DEMO_TEST 0
|
||||
#define CFG_ENABLE_WPA_LOG 0
|
||||
#define CFG_GENERAL_DMA 1
|
||||
#define CFG_IEEE80211N 1
|
||||
#define CFG_IEEE80211W 0
|
||||
#define CFG_INT_WDG_ENABLED 1
|
||||
#define CFG_INT_WDG_PERIOD_MS 10000
|
||||
#define CFG_IPERF_TEST 0
|
||||
#define CFG_JTAG_ENABLE 0
|
||||
#define CFG_LESS_MEMERY_IN_RWNX 0
|
||||
#define CFG_MAC_PHY_BAPASS 1
|
||||
#define CFG_MSDU_RESV_HEAD_LEN 96
|
||||
#define CFG_MSDU_RESV_TAIL_LEN 16
|
||||
#define CFG_REAL_SDIO 0
|
||||
#define CFG_RELEASE_FIRMWARE 0
|
||||
#define CFG_RF_OTA_TEST 0
|
||||
#define CFG_ROLE_LAUNCH 0
|
||||
#define CFG_RUNNING_PLATFORM SOC_PLATFORM
|
||||
#define CFG_RWNX_QOS_MSDU 1
|
||||
#define CFG_RX_SENSITIVITY_TEST 1
|
||||
#define CFG_SARADC_CALIBRATE 0
|
||||
#define CFG_SDIO 0
|
||||
#define CFG_SDIO_TRANS 0
|
||||
#define CFG_SOC_NAME SOC_BK7231U
|
||||
#define CFG_SUPPORT_BKREG 1
|
||||
#define CFG_SUPPORT_BLE 1
|
||||
#define CFG_SUPPORT_BLE_MESH 0
|
||||
#define CFG_SUPPORT_BOOTLOADER 1
|
||||
#define CFG_SUPPORT_BSSID_CONNECT 0
|
||||
#define CFG_SUPPORT_CALIBRATION 1
|
||||
#define CFG_SUPPORT_MANUAL_CALI 1
|
||||
#define CFG_SUPPORT_OTA_HTTP 1
|
||||
#define CFG_SUPPORT_OTA_TFTP 0
|
||||
#define CFG_SUPPORT_TPC_PA_MAP 1
|
||||
#define CFG_SYS_REDUCE_NORMAL_POWER 0
|
||||
#define CFG_TASK_WDG_ENABLED 1
|
||||
#define CFG_TASK_WDG_PERIOD_MS 60000
|
||||
#define CFG_TCP_SERVER_TEST 0
|
||||
#define CFG_TX_EVM_TEST 1
|
||||
#define CFG_UART_DEBUG 0
|
||||
#define CFG_UART_DEBUG_COMMAND_LINE 1
|
||||
#define CFG_UDISK_MP3 0
|
||||
#define CFG_USB 0
|
||||
#define CFG_USE_AP_IDLE 0
|
||||
#define CFG_USE_AP_PS 0
|
||||
#define CFG_USE_APP_DEMO_VIDEO_TRANSFER 0
|
||||
#define CFG_USE_AUD_ADC 0
|
||||
#define CFG_USE_AUD_DAC 0
|
||||
#define CFG_USE_AUDIO 0
|
||||
#define CFG_USE_BLE_PS 1
|
||||
#define CFG_USE_CAMERA_INTF 0
|
||||
#define CFG_USE_DEEP_PS 1
|
||||
#define CFG_USE_DHCP 1
|
||||
#define CFG_USE_FAKERTC_PS 0
|
||||
#define CFG_USE_FTPD_UPGRADE 0
|
||||
#define CFG_USE_HSLAVE_SPI 0
|
||||
#define CFG_USE_LWIP_NETSTACK 1
|
||||
#define CFG_USE_MCU_PS 1
|
||||
#define CFG_USE_PTA 0
|
||||
#define CFG_USE_SDCARD_HOST 0
|
||||
#define CFG_USE_SPIDMA 0
|
||||
#define CFG_USE_STA_PS 1
|
||||
#define CFG_USE_TEMPERATURE_DETECT 0
|
||||
#define CFG_USE_TICK_CAL 1
|
||||
#define CFG_USE_UART1 0
|
||||
#define CFG_USE_USB_CHARGE 0
|
||||
#define CFG_USE_USB_DEVICE 1
|
||||
#define CFG_USE_USB_DEVICE_CARD_READER 1
|
||||
#define CFG_USE_USB_HOST 0
|
||||
#define CFG_USE_WPA_29 1
|
||||
#define CFG_WFA_CERT 0
|
||||
#define CFG_WIFI_RAW_TX_CMD 0
|
||||
#define CFG_WIFI_SENSOR 0
|
||||
#define CFG_WLAN_FAST_CONNECT 0
|
||||
#define CFG_WPA_CTRL_IFACE 1
|
||||
#define CFG_WPA3 0
|
||||
#define CFG_XTAL_FREQUENCE CFG_XTAL_FREQUENCE_26M
|
||||
#define CFG_XTAL_FREQUENCE_26M 26000000
|
||||
#define CFG_XTAL_FREQUENCE_40M 40000000
|
||||
#define CONFIG_APP_MP3PLAYER 0
|
||||
#define FPGA_PLATFORM 0
|
||||
#define OSMALLOC_STATISTICAL 0
|
||||
#define RF_USE_POLICY WIFI_DEFAULT_BLE_REQUEST
|
||||
#define SOC_BK7221U 3
|
||||
#define SOC_BK7231 1
|
||||
#define SOC_BK7231N 5
|
||||
#define SOC_BK7231U 2
|
||||
#define SOC_PLATFORM 1
|
||||
#define THD_APPLICATION_PRIORITY 3
|
||||
#define THD_CORE_PRIORITY 2
|
||||
#define THD_EXTENDED_APP_PRIORITY 5
|
||||
#define THD_HOSTAPD_PRIORITY 5
|
||||
#define THD_INIT_PRIORITY 4
|
||||
#define THD_LWIP_PRIORITY 4
|
||||
#define THD_MEDIA_PRIORITY 4
|
||||
#define THD_RECONNECT_PRIORITY 4
|
||||
#define THD_UBG_PRIORITY 5
|
||||
#define THD_UMP3_PRIORITY 4
|
||||
#define THD_WPAS_PRIORITY 5
|
||||
#define THDD_KEY_SCAN_PRIORITY 7
|
||||
#define WIFI_DEFAULT_BLE_REQUEST 1
|
||||
18
platform/common/fixups/errno.h
Normal file
18
platform/common/fixups/errno.h
Normal file
@@ -0,0 +1,18 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-13. */
|
||||
|
||||
#pragma once
|
||||
|
||||
// This is an attempt to bring at least some order to <errno.h>, as
|
||||
// it's generally a source of problems everywhere.
|
||||
// The idea is that all units will try to import this errno.h first,
|
||||
// which means it won't use lwIP's error codes.
|
||||
// The code below was moved from realtek-ambz/fixups during
|
||||
// porting of BK72XX SDK, when the errno stroke again.
|
||||
|
||||
// There are two different errno's:
|
||||
// - first is just an int
|
||||
// - second is a macro that calls __errno()
|
||||
// Here the first option is ensured in the entire project.
|
||||
#include <sys/errno.h> // use system __errno() & error codes
|
||||
#undef errno // undefine __errno() macro
|
||||
extern int errno; // use a global errno variable
|
||||
5
platform/common/fixups/lwip/errno.h
Normal file
5
platform/common/fixups/lwip/errno.h
Normal file
@@ -0,0 +1,5 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-13. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../errno.h"
|
||||
@@ -2,6 +2,7 @@
|
||||
// - 2022-05-08 change CONFIG_USE_POLARSSL to CONFIG_USE_MBEDTLS
|
||||
// - 2022-05-08 use static int errno
|
||||
// - 2022-05-18 include lwip/init.h
|
||||
// - 2022-06-13 extract errno to common/fixups/errno.h
|
||||
|
||||
|
||||
/**
|
||||
@@ -15,14 +16,6 @@
|
||||
|
||||
#include "platform_autoconf.h"
|
||||
|
||||
// There are two different errno's:
|
||||
// - first is just an int
|
||||
// - second is a macro that calls __errno()
|
||||
// Here the first option is ensured in the entire project.
|
||||
#include <errno.h> // use system __errno() & error codes
|
||||
#undef errno // undefine __errno() macro
|
||||
extern int errno; // use a static errno
|
||||
|
||||
#include <lwip/init.h>
|
||||
|
||||
/*For MP mode setting*/
|
||||
|
||||
@@ -13,28 +13,62 @@ from shutil import copyfile
|
||||
from subprocess import PIPE, Popen
|
||||
from typing import IO, Dict, List, Tuple
|
||||
|
||||
from tools.util.fileio import chext, chname, isnewer, readbin
|
||||
from tools.util.intbin import inttole32
|
||||
from tools.util.fileio import chext, isnewer
|
||||
from tools.util.models import Family
|
||||
from tools.util.obj import get
|
||||
from tools.util.platform import get_board_manifest, get_family
|
||||
|
||||
|
||||
class SocType(Enum):
|
||||
UNSET = ()
|
||||
AMBZ = (1, "arm-none-eabi-", True)
|
||||
# (index, toolchain prefix, has dual-OTA, argument count)
|
||||
AMBZ = (1, "arm-none-eabi-", True, 0)
|
||||
BK72XX = (2, "arm-none-eabi-", False, 0)
|
||||
|
||||
def cmd(self, cmd: str) -> IO[bytes]:
|
||||
try:
|
||||
process = Popen(self.value[1] + cmd, stdout=PIPE)
|
||||
process = Popen(self.prefix + cmd, stdout=PIPE)
|
||||
except FileNotFoundError:
|
||||
print(f"Toolchain not found while running: '{self.value[1] + cmd}'")
|
||||
print(f"Toolchain not found while running: '{self.prefix + cmd}'")
|
||||
exit(1)
|
||||
return process.stdout
|
||||
|
||||
@property
|
||||
def dual_ota(self):
|
||||
def prefix(self) -> str:
|
||||
return self.value[1]
|
||||
|
||||
@property
|
||||
def dual_ota(self) -> bool:
|
||||
return self.value[2]
|
||||
|
||||
@property
|
||||
def soc_argc(self) -> int:
|
||||
return self.value[3]
|
||||
|
||||
def nm(self, input: str) -> Dict[str, int]:
|
||||
out = {}
|
||||
stdout = self.cmd(f"gcc-nm {input}")
|
||||
for line in stdout.readlines():
|
||||
line = line.decode().strip().split(" ")
|
||||
if len(line) != 3:
|
||||
continue
|
||||
out[line[2]] = int(line[0], 16)
|
||||
return out
|
||||
|
||||
def objcopy(
|
||||
self,
|
||||
input: str,
|
||||
output: str,
|
||||
sections: List[str] = [],
|
||||
fmt: str = "binary",
|
||||
) -> str:
|
||||
# print graph element
|
||||
print(f"| | |-- {basename(output)}")
|
||||
if isnewer(input, output):
|
||||
sections = " ".join(f"-j {section}" for section in sections)
|
||||
self.cmd(f"objcopy {sections} -O {fmt} {input} {output}").read()
|
||||
return output
|
||||
|
||||
soc: "SocType" = SocType.UNSET
|
||||
|
||||
# _ _ _ _ _ _ _ _
|
||||
# | | | | | (_) (_) | (_)
|
||||
@@ -47,102 +81,34 @@ def checkfile(path: str):
|
||||
exit(1)
|
||||
|
||||
|
||||
# ____ _ _ _ _
|
||||
# | _ \(_) | | (_) |
|
||||
# | |_) |_ _ __ _ _| |_ _| |___
|
||||
# | _ <| | '_ \| | | | __| | / __|
|
||||
# | |_) | | | | | |_| | |_| | \__ \
|
||||
# |____/|_|_| |_|\__,_|\__|_|_|___/
|
||||
def nm(input: str) -> Dict[str, int]:
|
||||
out = {}
|
||||
stdout = soc.cmd(f"gcc-nm {input}")
|
||||
for line in stdout.readlines():
|
||||
line = line.decode().strip().split(" ")
|
||||
if len(line) != 3:
|
||||
continue
|
||||
out[line[2]] = int(line[0], 16)
|
||||
return out
|
||||
|
||||
|
||||
def objcopy(
|
||||
input: str,
|
||||
output: str,
|
||||
sections: List[str],
|
||||
fmt: str = "binary",
|
||||
) -> str:
|
||||
# print graph element
|
||||
print(f"| | |-- {basename(output)}")
|
||||
if isnewer(input, output):
|
||||
sections = " ".join(f"-j {section}" for section in sections)
|
||||
soc.cmd(f"objcopy {sections} -O {fmt} {input} {output}").read()
|
||||
return output
|
||||
|
||||
|
||||
# ______ _ ______ _ ____ _____ _ _
|
||||
# | ____| | | ____| | | | _ \_ _| \ | |
|
||||
# | |__ | | | |__ | |_ ___ | |_) || | | \| |
|
||||
# | __| | | | __| | __/ _ \ | _ < | | | . ` |
|
||||
# | |____| |____| | | || (_) | | |_) || |_| |\ |
|
||||
# |______|______|_| \__\___/ |____/_____|_| \_|
|
||||
def elf2bin_ambz(input: str, ota_idx: int = 1) -> Tuple[int, str]:
|
||||
def write_header(f: IO[bytes], start: int, end: int):
|
||||
f.write(b"81958711")
|
||||
f.write(inttole32(end - start))
|
||||
f.write(inttole32(start))
|
||||
f.write(b"\xff" * 16)
|
||||
|
||||
sections_ram = [
|
||||
".ram_image2.entry",
|
||||
".ram_image2.data",
|
||||
".ram_image2.bss",
|
||||
".ram_image2.skb.bss",
|
||||
".ram_heap.data",
|
||||
]
|
||||
sections_xip = [".xip_image2.text"]
|
||||
sections_rdp = [".ram_rdp.text"]
|
||||
nmap = nm(input)
|
||||
ram_start = nmap["__ram_image2_text_start__"]
|
||||
ram_end = nmap["__ram_image2_text_end__"]
|
||||
xip_start = nmap["__flash_text_start__"] - 0x8000020
|
||||
# build output name
|
||||
output = chname(input, f"image_0x{xip_start:06X}.ota{ota_idx}.bin")
|
||||
out_ram = chname(input, f"ota{ota_idx}.ram_2.r.bin")
|
||||
out_xip = chname(input, f"ota{ota_idx}.xip_image2.bin")
|
||||
out_rdp = chname(input, f"ota{ota_idx}.rdp.bin")
|
||||
# print graph element
|
||||
print(f"| |-- {basename(output)}")
|
||||
# objcopy required images
|
||||
ram = objcopy(input, out_ram, sections_ram)
|
||||
xip = objcopy(input, out_xip, sections_xip)
|
||||
objcopy(input, out_rdp, sections_rdp)
|
||||
# return if images are up to date
|
||||
if not isnewer(ram, output) and not isnewer(xip, output):
|
||||
return (xip_start, output)
|
||||
|
||||
# read and trim RAM image
|
||||
ram = readbin(ram).rstrip(b"\x00")
|
||||
# read XIP image
|
||||
xip = readbin(xip)
|
||||
# align images to 4 bytes
|
||||
ram += b"\x00" * (((((len(ram) - 1) // 4) + 1) * 4) - len(ram))
|
||||
xip += b"\x00" * (((((len(xip) - 1) // 4) + 1) * 4) - len(xip))
|
||||
# write output file
|
||||
with open(output, "wb") as f:
|
||||
# write XIP header
|
||||
write_header(f, 0, len(xip))
|
||||
# write XIP image
|
||||
f.write(xip)
|
||||
# write RAM header
|
||||
write_header(f, ram_start, ram_end)
|
||||
# write RAM image
|
||||
f.write(ram)
|
||||
return (xip_start, output)
|
||||
|
||||
|
||||
def elf2bin(input: str, ota_idx: int = 1) -> Tuple[int, str]:
|
||||
def elf2bin(
|
||||
soc: SocType,
|
||||
family: Family,
|
||||
board: dict,
|
||||
input: str,
|
||||
ota_idx: int = 1,
|
||||
args: List[str] = [],
|
||||
) -> Tuple[int, str]:
|
||||
checkfile(input)
|
||||
func = None
|
||||
|
||||
if soc == SocType.AMBZ:
|
||||
return elf2bin_ambz(input, ota_idx)
|
||||
from tools.soc.link2bin_ambz import elf2bin_ambz
|
||||
|
||||
func = elf2bin_ambz
|
||||
elif soc == SocType.BK72XX:
|
||||
from tools.soc.link2bin_bk72xx import elf2bin_bk72xx
|
||||
|
||||
func = elf2bin_bk72xx
|
||||
|
||||
if func:
|
||||
return func(soc, family, board, input, ota_idx, *args)
|
||||
raise NotImplementedError(f"SoC ELF->BIN not implemented: {soc}")
|
||||
|
||||
|
||||
@@ -181,17 +147,21 @@ def ldargs_parse(
|
||||
|
||||
|
||||
def link2bin(
|
||||
args: List[str],
|
||||
soc: SocType,
|
||||
family: Family,
|
||||
board: dict,
|
||||
ld_args: List[str],
|
||||
ld_ota1: str = None,
|
||||
ld_ota2: str = None,
|
||||
soc_args: List[str] = [],
|
||||
) -> List[str]:
|
||||
elfs = []
|
||||
if soc.dual_ota:
|
||||
# process linker arguments for dual-OTA chips
|
||||
elfs = ldargs_parse(args, ld_ota1, ld_ota2)
|
||||
elfs = ldargs_parse(ld_args, ld_ota1, ld_ota2)
|
||||
else:
|
||||
# just get .elf output name for single-OTA chips
|
||||
elfs = ldargs_parse(args, None, None)
|
||||
elfs = ldargs_parse(ld_args, None, None)
|
||||
|
||||
if not elfs:
|
||||
return None
|
||||
@@ -206,12 +176,12 @@ def link2bin(
|
||||
soc.cmd(f"gcc {ldargs}").read()
|
||||
checkfile(elf)
|
||||
# generate a set of binaries for the SoC
|
||||
elf2bin(elf, ota_idx)
|
||||
elf2bin(soc, family, board, elf, ota_idx, soc_args)
|
||||
ota_idx += 1
|
||||
|
||||
if soc.dual_ota:
|
||||
# copy OTA1 file as firmware.elf to make PIO understand it
|
||||
elf, _ = ldargs_parse(args, None, None)[0]
|
||||
elf, _ = ldargs_parse(ld_args, None, None)[0]
|
||||
copyfile(elfs[0][0], elf)
|
||||
|
||||
|
||||
@@ -221,17 +191,34 @@ if __name__ == "__main__":
|
||||
description="Link to BIN format",
|
||||
prefix_chars="@",
|
||||
)
|
||||
parser.add_argument("soc", type=str, help="SoC name/family short name")
|
||||
parser.add_argument("board", type=str, help="Target board name")
|
||||
parser.add_argument("ota1", type=str, help=".LD file OTA1 pattern")
|
||||
parser.add_argument("ota2", type=str, help=".LD file OTA2 pattern")
|
||||
parser.add_argument("args", type=str, nargs="*", help="Linker arguments")
|
||||
parser.add_argument("args", type=str, nargs="*", help="SoC+linker arguments")
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
soc = next(soc for soc in SocType if soc.name == args.soc)
|
||||
except StopIteration:
|
||||
print(f"Not a valid SoC: {args.soc}")
|
||||
board = get_board_manifest(args.board)
|
||||
except FileNotFoundError:
|
||||
print(f"Board not found: {args.board}")
|
||||
exit(1)
|
||||
|
||||
family = get_family(short_name=get(board, "build.family"))
|
||||
soc_types = {soc.name.lower(): soc for soc in SocType}
|
||||
soc = soc_types.get(family.code, soc_types.get(family.parent_code, None))
|
||||
if not soc:
|
||||
print(f"SoC type not found. Tried {family.code}, {family.parent_code}")
|
||||
exit(1)
|
||||
|
||||
if not args.args:
|
||||
print(f"Linker arguments must not be empty")
|
||||
exit(1)
|
||||
link2bin(args.args, args.ota1, args.ota2)
|
||||
link2bin(
|
||||
soc,
|
||||
family,
|
||||
board,
|
||||
args.args[soc.soc_argc :],
|
||||
args.ota1,
|
||||
args.ota2,
|
||||
args.args[: soc.soc_argc],
|
||||
)
|
||||
|
||||
69
tools/soc/link2bin_ambz.py
Normal file
69
tools/soc/link2bin_ambz.py
Normal file
@@ -0,0 +1,69 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-06-14.
|
||||
|
||||
from os.path import basename
|
||||
from typing import IO, Tuple
|
||||
|
||||
from tools.util.fileio import chname, isnewer, readbin
|
||||
from tools.util.intbin import inttole32
|
||||
from tools.util.models import Family
|
||||
|
||||
|
||||
def elf2bin_ambz(
|
||||
soc,
|
||||
family: Family,
|
||||
board: dict,
|
||||
input: str,
|
||||
ota_idx: int = 1,
|
||||
) -> Tuple[int, str]:
|
||||
def write_header(f: IO[bytes], start: int, end: int):
|
||||
f.write(b"81958711")
|
||||
f.write(inttole32(end - start))
|
||||
f.write(inttole32(start))
|
||||
f.write(b"\xff" * 16)
|
||||
|
||||
sections_ram = [
|
||||
".ram_image2.entry",
|
||||
".ram_image2.data",
|
||||
".ram_image2.bss",
|
||||
".ram_image2.skb.bss",
|
||||
".ram_heap.data",
|
||||
]
|
||||
sections_xip = [".xip_image2.text"]
|
||||
sections_rdp = [".ram_rdp.text"]
|
||||
nmap = soc.nm(input)
|
||||
ram_start = nmap["__ram_image2_text_start__"]
|
||||
ram_end = nmap["__ram_image2_text_end__"]
|
||||
xip_start = nmap["__flash_text_start__"] - 0x8000020
|
||||
# build output name
|
||||
output = chname(input, f"image_0x{xip_start:06X}.ota{ota_idx}.bin")
|
||||
out_ram = chname(input, f"ota{ota_idx}.ram_2.r.bin")
|
||||
out_xip = chname(input, f"ota{ota_idx}.xip_image2.bin")
|
||||
out_rdp = chname(input, f"ota{ota_idx}.rdp.bin")
|
||||
# print graph element
|
||||
print(f"| |-- {basename(output)}")
|
||||
# objcopy required images
|
||||
ram = soc.objcopy(input, out_ram, sections_ram)
|
||||
xip = soc.objcopy(input, out_xip, sections_xip)
|
||||
soc.objcopy(input, out_rdp, sections_rdp)
|
||||
# return if images are up to date
|
||||
if not isnewer(ram, output) and not isnewer(xip, output):
|
||||
return (xip_start, output)
|
||||
|
||||
# read and trim RAM image
|
||||
ram = readbin(ram).rstrip(b"\x00")
|
||||
# read XIP image
|
||||
xip = readbin(xip)
|
||||
# align images to 4 bytes
|
||||
ram += b"\x00" * (((((len(ram) - 1) // 4) + 1) * 4) - len(ram))
|
||||
xip += b"\x00" * (((((len(xip) - 1) // 4) + 1) * 4) - len(xip))
|
||||
# write output file
|
||||
with open(output, "wb") as f:
|
||||
# write XIP header
|
||||
write_header(f, 0, len(xip))
|
||||
# write XIP image
|
||||
f.write(xip)
|
||||
# write RAM header
|
||||
write_header(f, ram_start, ram_end)
|
||||
# write RAM image
|
||||
f.write(ram)
|
||||
return (xip_start, output)
|
||||
57
tools/soc/link2bin_bk72xx.py
Normal file
57
tools/soc/link2bin_bk72xx.py
Normal file
@@ -0,0 +1,57 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-06-14.
|
||||
|
||||
from datetime import datetime
|
||||
from os import stat
|
||||
from os.path import basename
|
||||
from typing import Tuple
|
||||
|
||||
from tools.util.bkutil import RBL, BekenBinary
|
||||
from tools.util.fileio import chext, chname, isnewer, writebin, writejson
|
||||
from tools.util.models import Family
|
||||
from tools.util.obj import get
|
||||
|
||||
|
||||
def calc_offset(addr: int) -> int:
|
||||
return int(addr + (addr // 32) * 2)
|
||||
|
||||
|
||||
def elf2bin_bk72xx(
|
||||
soc,
|
||||
family: Family,
|
||||
board: dict,
|
||||
input: str,
|
||||
ota_idx: int = 1,
|
||||
) -> Tuple[int, str]:
|
||||
mcu = get(board, "build.mcu")
|
||||
coeffs = get(board, "build.bkcrypt_coeffs") or ("0" * 32)
|
||||
rbl_size = get(board, "build.bkrbl_size_app")
|
||||
version = datetime.now().strftime("%y.%m.%d")
|
||||
|
||||
nmap = soc.nm(input)
|
||||
app_addr = nmap["_vector_start"]
|
||||
app_offs = calc_offset(app_addr)
|
||||
app_size = int(rbl_size, 16)
|
||||
|
||||
# build output name
|
||||
output = chname(input, f"{mcu}_app_0x{app_offs:06X}.bin")
|
||||
fw_bin = chext(input, "bin")
|
||||
# objcopy ELF -> raw BIN
|
||||
soc.objcopy(input, fw_bin)
|
||||
# print graph element
|
||||
print(f"| |-- {basename(output)}")
|
||||
# return if images are up to date
|
||||
if not isnewer(fw_bin, output):
|
||||
return (app_offs, output)
|
||||
|
||||
bk = BekenBinary(coeffs)
|
||||
rbl = RBL(
|
||||
name="app",
|
||||
version=f"{version}-{mcu}",
|
||||
container_size=app_size,
|
||||
)
|
||||
|
||||
fw_size = stat(fw_bin).st_size
|
||||
raw = open(fw_bin, "rb")
|
||||
out = open(output, "wb")
|
||||
for data in bk.package(raw, app_addr, fw_size, rbl):
|
||||
out.write(data)
|
||||
@@ -51,3 +51,9 @@ def readjson(file: str) -> Union[dict, list]:
|
||||
"""Read a JSON file into a dict or list."""
|
||||
with open(file, "r", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
|
||||
def writejson(file: str, data: Union[dict, list]):
|
||||
"""Write a dict or list to a JSON file."""
|
||||
with open(file, "w", encoding="utf-8") as f:
|
||||
json.dump(data, f)
|
||||
|
||||
Reference in New Issue
Block a user