summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrcitach <[email protected]>2026-08-25 07:26:17 +0000
committerRbb666 <[email protected]>2026-08-25 22:04:44 +0800
commit45679c79de6d60f2e8345928c49671936f6ff008 (patch)
treecb08a1bff25a2c01777de217d231a4939eb7e43f
parent5d19f815807fd6fb8fdb4247f831562b3de17b4e (diff)
Improve BLE OTA image generation to avoid executing OPEN every time a flash erase and write operation occurs.
-rw-r--r--bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c34
-rw-r--r--bsp/renesas/ra6w1-ek/scripts/gen_rrq61_flash_image.py100
2 files changed, 87 insertions, 47 deletions
diff --git a/bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c b/bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c
index 91698fc6df..881a7f1587 100644
--- a/bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c
+++ b/bsp/renesas/ra6w1-ek/board/ports/ra6w1_ospi_flash.c
@@ -10,11 +10,33 @@
#include "hal_data.h"
#include "bsp_sflash_map_ra6w1.h"
-static int ra6w1_ospi_flash_init(void)
+static rt_bool_t s_ospi_flash_opened;
+
+static int ra6w1_ospi_flash_open(void)
{
+ fsp_err_t err;
+
+ if (s_ospi_flash_opened)
+ {
+ return RT_EOK;
+ }
+
+ err = R_OSPI_W_Open((spi_flash_ctrl_t *)&g_ospi_flash_ctrl,
+ &g_ospi_flash_cfg);
+ if (err != FSP_SUCCESS)
+ {
+ return -RT_ERROR;
+ }
+
+ s_ospi_flash_opened = RT_TRUE;
return RT_EOK;
}
+static int ra6w1_ospi_flash_init(void)
+{
+ return ra6w1_ospi_flash_open();
+}
+
static int ra6w1_ospi_flash_read(long offset, rt_uint8_t *buf, rt_size_t size)
{
rt_memcpy((void *) buf, (void *) ((uint32_t)offset | OSPI_W_AUTOMODE_BASE_ADD), size);
@@ -29,7 +51,10 @@ static int ra6w1_ospi_flash_write(long offset, const rt_uint8_t *buf, rt_size_t
uint32_t write_len;
fsp_err_t err;
- R_OSPI_W_Open((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, &g_ospi_flash_cfg);
+ if (ra6w1_ospi_flash_open() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
while (remaining > 0)
{
@@ -99,7 +124,10 @@ static int ra6w1_ospi_flash_erase(long offset, rt_size_t size)
uint32_t erase_len;
fsp_err_t err;
- R_OSPI_W_Open((spi_flash_ctrl_t *)&g_ospi_flash_ctrl, &g_ospi_flash_cfg);
+ if (ra6w1_ospi_flash_open() != RT_EOK)
+ {
+ return -RT_ERROR;
+ }
while (remaining > 0)
{
diff --git a/bsp/renesas/ra6w1-ek/scripts/gen_rrq61_flash_image.py b/bsp/renesas/ra6w1-ek/scripts/gen_rrq61_flash_image.py
index 695dcf5e72..027c097ce7 100644
--- a/bsp/renesas/ra6w1-ek/scripts/gen_rrq61_flash_image.py
+++ b/bsp/renesas/ra6w1-ek/scripts/gen_rrq61_flash_image.py
@@ -92,6 +92,8 @@ def get_image_header(header):
data = bytearray()
if header.is_corrupt:
raise ValueError('image_header_corrupt is not supported')
+ if len(header.version) > 64:
+ raise ValueError('image header version is longer than 64 bytes')
data.extend(b'DA16')
data.extend(to_bytes(header.timestamp, 4))
data.extend(header.version)
@@ -116,6 +118,19 @@ def get_image_header(header):
data.extend(b'\xFF' * num_bytes_uninitialized)
return data
+
+def get_image_header_for_data(in_file_data, header_fw_version):
+ """Build the Renesas image header for a raw application binary."""
+ ih_values = ImageHeaderValues(
+ is_corrupt=False,
+ security=False,
+ version=header_fw_version.encode(),
+ timestamp=0x5939110D,
+ image_size=len(in_file_data),
+ image_crc=binascii.crc32(in_file_data) & 0xFFFFFFFF,
+ )
+ return get_image_header(ih_values)
+
def get_firmware_version_e2s(fw_version_file):
"""
Reads the firmware version from fw_version.h.
@@ -132,6 +147,25 @@ def get_firmware_version_e2s(fw_version_file):
return "1.0.0" # Default version
+
+def get_header_fw_version(ra6w_grp, out_file_name):
+ """Return the firmware version stored in an image header."""
+ fw_version = get_fw_version()
+ if not fw_version:
+ # This condition will be true when we are building project
+ # using e2studio and project is prepared outside the repo.
+ script_dir = os.path.dirname(os.path.abspath(__file__))
+ fw_version_file = os.path.abspath(os.path.join(script_dir, "../ra/fsp/src/rm_wifi/fw_version.h"))
+ if not os.path.isfile(fw_version_file):
+ fw_version_file = os.path.abspath(os.path.join(script_dir, "../ra/fsp/inc/fw_version.h"))
+ fw_version = get_firmware_version_e2s(fw_version_file)
+ elif 'rm_wifi_test_app' in out_file_name or 'vndm_wlan' in out_file_name:
+ fw_version = fw_version + "-e2studio"
+ else:
+ fw_version = fw_version + "-cmake"
+
+ return ra6w_grp + '-' + fw_version
+
def gen_flash_image(in_file, out_file, ra6w_grp):
"""Generate output flash image."""
in_file_data = in_file.read()
@@ -156,38 +190,9 @@ def gen_flash_image(in_file, out_file, ra6w_grp):
# non_secure_cfg.xml.AT25SL641-8MB, hence:
headers_data.extend(headers_data)
- # Set f/w version info
- fw_version = get_fw_version()
- if not fw_version:
- # This condition will be true when we are building project
- # using e2studio and project is prepared outside the repo
- # In this case fetch the value from fw_version.h which is generated
- # when packs are created.
- script_dir = os.path.dirname(os.path.abspath(__file__)) # Get script directory
- fw_version_file = os.path.abspath(os.path.join(script_dir, "../ra/fsp/src/rm_wifi/fw_version.h"))
- if not os.path.isfile(fw_version_file):
- # Try another location
- fw_version_file = os.path.abspath(os.path.join(script_dir, "../ra/fsp/inc/fw_version.h"))
- fw_version = get_firmware_version_e2s(fw_version_file)
-
- else:
- # Check if out_file_name contains 'rm_wifi_test_app.img'
- if 'rm_wifi_test_app' in out_file_name or 'vndm_wlan' in out_file_name:
- fw_version = fw_version+"-e2studio"
- else:
- # If not, append "-cmake"
- fw_version = fw_version+"-cmake"
- header_fw_version = ra6w_grp + '-' + fw_version
- # From non_secure_cfg.xml.AT25SL641-8MB (image header):
- ih_values = ImageHeaderValues(
- is_corrupt=False,
- security=False,
- version=header_fw_version.encode(),
- timestamp=0x5939110D,
- image_size=len(in_file_data),
- image_crc=binascii.crc32(in_file_data),
- )
- img_header=get_image_header(ih_values)
+ header_fw_version = get_header_fw_version(ra6w_grp, out_file_name)
+ fw_version = header_fw_version[len(ra6w_grp) + 1:]
+ img_header = get_image_header_for_data(in_file_data, header_fw_version)
headers_data.extend(img_header)
out_file.write(headers_data)
out_file.write(in_file_data)
@@ -261,21 +266,12 @@ def gen_flash_image(in_file, out_file, ra6w_grp):
gen_ota_flash_images(in_file_data, fw_version, prefix_file_name, ra6w_grp)
except FileNotFoundError:
- print("configuration.xml file not found, skipping OTA image generation.")
+ print("configuration.xml file not found, skipping optional OTA test image generation.")
def gen_ota_flash_image(in_file_data, header_fw_version, ota_file_name):
"""Generate ota flash image."""
# From non_secure_cfg.xml.AT25SL641-8MB (image header):
- ih_values = ImageHeaderValues(
- is_corrupt=False,
- security=False,
- version=header_fw_version.encode(),
- timestamp=0x5939110D,
- image_size=len(in_file_data),
- image_crc=binascii.crc32(in_file_data),
- )
-
- img_header=get_image_header(ih_values)
+ img_header = get_image_header_for_data(in_file_data, header_fw_version)
headers_data = bytearray()
headers_data.extend(img_header)
ota_out_file=open('./'+ota_file_name+'.img', 'wb')
@@ -283,6 +279,17 @@ def gen_ota_flash_image(in_file_data, header_fw_version, ota_file_name):
ota_out_file.write(in_file_data)
ota_out_file.close()
+
+def gen_ota_image(in_file, out_file, ra6w_grp):
+ """Generate a single OTA image: image header followed by raw firmware."""
+ in_file_data = in_file.read()
+ in_file.close()
+
+ header_fw_version = get_header_fw_version(ra6w_grp, out_file.name)
+ out_file.write(get_image_header_for_data(in_file_data, header_fw_version))
+ out_file.write(in_file_data)
+ out_file.close()
+
def gen_ota_flash_images(in_file_data, fw_version, prefix_file_name, ra6w_grp):
# Same version ex) RA6W1-0000000000-00000
test_fw_version = ra6w_grp + '-' + fw_version
@@ -316,6 +323,8 @@ def gen_ota_flash_images(in_file_data, fw_version, prefix_file_name, ra6w_grp):
def _main():
parser = argparse.ArgumentParser(
description='Generate flash image for EK-RRQ61000 board.')
+ parser.add_argument('--ota', '--ota-image', dest='ota_image', action='store_true',
+ help='generate a single OTA image (DA16 image header + raw firmware)')
parser.add_argument('in_file', metavar='IN', type=argparse.FileType('rb'),
help='input file (.bin produced by objcopy)')
parser.add_argument('out_file', metavar='OUT',
@@ -327,7 +336,10 @@ def _main():
nargs="?",
default="RA6W1-RRQ61001")
args = parser.parse_args()
- gen_flash_image(args.in_file, args.out_file, args.ra6w_grp)
+ if args.ota_image:
+ gen_ota_image(args.in_file, args.out_file, args.ra6w_grp)
+ else:
+ gen_flash_image(args.in_file, args.out_file, args.ra6w_grp)
if __name__ == '__main__':