boards/arm/samv7: Move MCUboot to common folder

Move MCUboot bootloader implementation to samv7 common folder. This drop
all duplicated code and unify implementation.

Signed-off-by: Gerson Fernando Budke <nandojve@gmail.com>
This commit is contained in:
Gerson Fernando Budke 2021-12-04 11:51:12 -03:00 committed by Alan Carvalho de Assis
parent b5868aed6f
commit a6fc88740c
12 changed files with 104 additions and 503 deletions

View File

@ -0,0 +1,62 @@
/****************************************************************************
* boards/arm/samv7/common/include/sam_progmem_common.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
#ifndef __BOARDS_ARM_SAMV7_COMMON_INCLUDE_SAM_PROGMEM_COMMON_H
#define __BOARDS_ARM_SAMV7_COMMON_INCLUDE_SAM_PROGMEM_COMMON_H
/****************************************************************************
* Public Types
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/****************************************************************************
* Public Functions Definitions
****************************************************************************/
/****************************************************************************
* Name: sam_progmem_init
*
* Description:
* Initialize the FLASH and register MTD devices.
****************************************************************************/
int sam_progmem_common_initialize(void);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_SAMV7_COMMON_INCLUDE_SAM_PROGMEM_COMMON_H */

View File

@ -18,6 +18,16 @@
# #
############################################################################# #############################################################################
ifeq ($(CONFIG_BOARDCTL_BOOT_IMAGE),y)
CSRCS += sam_boot_image.c
endif
ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += sam_progmem_common.c
else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y)
CSRCS += sam_progmem_common.c
endif
DEPPATH += --dep-path src DEPPATH += --dep-path src
VPATH += :src VPATH += :src
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src) CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)src)

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* boards/arm/samv7/same70-qmtech/src/sam_boot_image.c * boards/arm/samv7/common/src/sam_boot_image.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* boards/arm/samv7/same70-qmtech/src/sam_progmem.c * boards/arm/samv7/common/src/sam_progmem_common.c
* *
* Licensed to the Apache Software Foundation (ASF) under one or more * Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
@ -40,41 +40,26 @@
#endif #endif
#include "sam_progmem.h" #include "sam_progmem.h"
#include "same70-qmtech.h" #include "sam_progmem_common.h"
#ifdef HAVE_PROGMEM_CHARDEV
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0])) #define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
#define PROGMEM_MTD_MINOR 0
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION) struct mcuboot_partition_s
struct ota_partition_s
{ {
uint32_t offset; /* Partition offset from the beginning of MTD */ uint32_t offset; /* Partition offset from the beginning of MTD */
uint32_t size; /* Partition size in bytes */ uint32_t size; /* Partition size in bytes */
const char *devpath; /* Partition device path */ const char *devpath; /* Partition device path */
}; };
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
static struct mtd_dev_s *sam_progmem_alloc_mtdpart(uint32_t mtd_offset,
uint32_t mtd_size);
static int init_ota_partitions(void);
#endif
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
@ -82,7 +67,7 @@ static int init_ota_partitions(void);
static FAR struct mtd_dev_s *g_samv7_progmem_mtd; static FAR struct mtd_dev_s *g_samv7_progmem_mtd;
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION) #if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
static const struct ota_partition_s g_ota_partition_table[] = static const struct mcuboot_partition_s g_mcuboot_partition_table[] =
{ {
{ {
.offset = CONFIG_SAMV7_OTA_PRIMARY_SLOT_OFFSET, .offset = CONFIG_SAMV7_OTA_PRIMARY_SLOT_OFFSET,
@ -100,14 +85,11 @@ static const struct ota_partition_s g_ota_partition_table[] =
.devpath = CONFIG_SAMV7_OTA_SCRATCH_DEVPATH .devpath = CONFIG_SAMV7_OTA_SCRATCH_DEVPATH
} }
}; };
#endif
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
/**************************************************************************** /****************************************************************************
* Name: sam_progmem_alloc_mtdpart * Name: sam_progmem_alloc_mtdpart
* *
@ -149,10 +131,10 @@ static struct mtd_dev_s *sam_progmem_alloc_mtdpart(uint32_t mtd_offset,
} }
/**************************************************************************** /****************************************************************************
* Name: init_ota_partitions * Name: init_mcuboot_partitions
* *
* Description: * Description:
* Initialize partitions that are dedicated to firmware OTA update. * Initialize partitions that are dedicated to firmware MCUBOOT update.
* *
* Input Parameters: * Input Parameters:
* None. * None.
@ -162,7 +144,7 @@ static struct mtd_dev_s *sam_progmem_alloc_mtdpart(uint32_t mtd_offset,
* *
****************************************************************************/ ****************************************************************************/
static int init_ota_partitions(void) static int init_mcuboot_partitions(void)
{ {
FAR struct mtd_dev_s *mtd; FAR struct mtd_dev_s *mtd;
#ifdef CONFIG_BCH #ifdef CONFIG_BCH
@ -170,11 +152,17 @@ static int init_ota_partitions(void)
#endif #endif
int ret = OK; int ret = OK;
for (int i = 0; i < ARRAYSIZE(g_ota_partition_table); ++i) for (int i = 0; i < ARRAYSIZE(g_mcuboot_partition_table); ++i)
{ {
const struct ota_partition_s *part = &g_ota_partition_table[i]; const struct mcuboot_partition_s *part = &g_mcuboot_partition_table[i];
mtd = sam_progmem_alloc_mtdpart(part->offset, part->size); mtd = sam_progmem_alloc_mtdpart(part->offset, part->size);
if (!mtd)
{
ferr("ERROR: create MTD OTA partition %s", part->devpath);
continue;
}
ret = ftl_initialize(i, mtd); ret = ftl_initialize(i, mtd);
if (ret < 0) if (ret < 0)
{ {
@ -196,7 +184,7 @@ static int init_ota_partitions(void)
return ret; return ret;
} }
#endif #endif /* CONFIG_SAMV7_PROGMEM_OTA_PARTITION */
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -209,15 +197,15 @@ static int init_ota_partitions(void)
* Initialize the FLASH and register the MTD device. * Initialize the FLASH and register the MTD device.
****************************************************************************/ ****************************************************************************/
int sam_progmem_init(void) int sam_progmem_common_initialize(void)
{ {
int ret = OK; int ret = OK;
/* Initialize the SAME70 FLASH programming memory library */ /* Initialize the SAMV7 FLASH programming memory library */
sam_progmem_initialize(); sam_progmem_initialize();
/* Create an instance of the SAME70 FLASH program memory device driver */ /* Create an instance of the SAMV7 FLASH program memory device driver */
g_samv7_progmem_mtd = progmem_initialize(); g_samv7_progmem_mtd = progmem_initialize();
if (g_samv7_progmem_mtd == NULL) if (g_samv7_progmem_mtd == NULL)
@ -226,7 +214,7 @@ int sam_progmem_init(void)
} }
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION) #if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
ret = init_ota_partitions(); ret = init_mcuboot_partitions();
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@ -265,4 +253,3 @@ int sam_progmem_init(void)
return ret; return ret;
} }
#endif /* HAVE_PROGMEM_CHARDEV */

View File

@ -814,5 +814,5 @@ Configuration sub-directories
CONFIG_BOOT_MCUBOOT=y CONFIG_BOOT_MCUBOOT=y
CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE=y CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE=y
CONFIG_SAME70QMTECH_FORMAT_MCUBOOT=y CONFIG_SAMV7_FORMAT_MCUBOOT=y
CONFIG_USER_ENTRYPOINT="mcuboot_confirm_main" CONFIG_USER_ENTRYPOINT="mcuboot_confirm_main"

View File

@ -23,15 +23,12 @@ include $(TOPDIR)/Make.defs
CSRCS = sam_boot.c CSRCS = sam_boot.c
ifeq ($(CONFIG_BOARDCTL),y) ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += sam_appinit.c sam_bringup.c sam_progmem.c CSRCS += sam_appinit.c sam_bringup.c
ifeq ($(CONFIG_BOARDCTL_RESET),y) ifeq ($(CONFIG_BOARDCTL_RESET),y)
CSRCS += sam_reset.c CSRCS += sam_reset.c
endif endif
ifeq ($(CONFIG_BOARDCTL_BOOT_IMAGE),y)
CSRCS += sam_boot_image.c
endif
else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y) else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y)
CSRCS += sam_bringup.c sam_progmem.c CSRCS += sam_bringup.c
endif endif
ifeq ($(CONFIG_ARCH_LEDS),y) ifeq ($(CONFIG_ARCH_LEDS),y)

View File

@ -39,6 +39,7 @@
#include <nuttx/i2c/i2c_master.h> #include <nuttx/i2c/i2c_master.h>
#include "sam_twihs.h" #include "sam_twihs.h"
#include "sam_progmem_common.h"
#include "same70-qmtech.h" #include "same70-qmtech.h"
#ifdef HAVE_ROMFS #ifdef HAVE_ROMFS
@ -151,7 +152,7 @@ int sam_bringup(void)
#ifdef HAVE_PROGMEM_CHARDEV #ifdef HAVE_PROGMEM_CHARDEV
/* Initialize the SAME70 FLASH programming memory library */ /* Initialize the SAME70 FLASH programming memory library */
ret = sam_progmem_init(); ret = sam_progmem_common_initialize();
if (ret < 0) if (ret < 0)
{ {
syslog(LOG_ERR, "ERROR: Failed to initialize progmem: %d\n", ret); syslog(LOG_ERR, "ERROR: Failed to initialize progmem: %d\n", ret);

View File

@ -1736,5 +1736,5 @@ Configuration sub-directories
CONFIG_BOOT_MCUBOOT=y CONFIG_BOOT_MCUBOOT=y
CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE=y CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE=y
CONFIG_SAME70XPLAINED_FORMAT_MCUBOOT=y CONFIG_SAMV7_FORMAT_MCUBOOT=y
CONFIG_USER_ENTRYPOINT="mcuboot_confirm_main" CONFIG_USER_ENTRYPOINT="mcuboot_confirm_main"

View File

@ -27,15 +27,12 @@ CSRCS += sam_sdram.c
endif endif
ifeq ($(CONFIG_BOARDCTL),y) ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += sam_appinit.c sam_bringup.c sam_progmem.c CSRCS += sam_appinit.c sam_bringup.c
ifeq ($(CONFIG_BOARDCTL_RESET),y) ifeq ($(CONFIG_BOARDCTL_RESET),y)
CSRCS += sam_reset.c CSRCS += sam_reset.c
endif endif
ifeq ($(CONFIG_BOARDCTL_BOOT_IMAGE),y)
CSRCS += sam_boot_image.c
endif
else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y) else ifeq ($(CONFIG_BOARD_LATE_INITIALIZE),y)
CSRCS += sam_bringup.c sam_progmem.c CSRCS += sam_bringup.c
endif endif
ifeq ($(CONFIG_ARCH_LEDS),y) ifeq ($(CONFIG_ARCH_LEDS),y)

View File

@ -1,186 +0,0 @@
/****************************************************************************
* boards/arm/samv7/same70-xplained/src/sam_boot_image.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/boardctl.h>
#include <nuttx/irq.h>
#include <nuttx/cache.h>
#include "nvic.h"
#include "arm_arch.h"
#include "barriers.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure represents the first two entries on NVIC vector table */
struct arm_vector_table
{
uint32_t spr; /* Stack pointer on reset */
uint32_t reset; /* Pointer to reset exception handler */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static void cleanup_arm_nvic(void);
#ifdef CONFIG_ARMV7M_SYSTICK
static void systick_disable(void);
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: cleanup_arm_nvic
*
* Description:
* Acknowledge and disable all interrupts in NVIC
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void cleanup_arm_nvic(void)
{
int i;
/* Allow any pending interrupts to be recognized */
ARM_ISB();
cpsid();
/* Disable all interrupts */
for (i = 0; i < SAM_IRQ_NIRQS; i += 32)
{
putreg32(0xffffffff, NVIC_IRQ_CLEAR(i));
}
/* Clear all pending interrupts */
for (i = 0; i < SAM_IRQ_NIRQS; i += 32)
{
putreg32(0xffffffff, NVIC_IRQ_CLRPEND(i));
}
}
#ifdef CONFIG_ARMV7M_SYSTICK
/****************************************************************************
* Name: systick_disable
*
* Description:
* Disable the SysTick system timer
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void systick_disable(void)
{
putreg32(0, NVIC_SYSTICK_CTRL);
putreg32(NVIC_SYSTICK_RELOAD_MASK, NVIC_SYSTICK_RELOAD);
putreg32(0, NVIC_SYSTICK_CURRENT);
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_boot_image
*
* Description:
* This entry point is called by bootloader to jump to application image.
*
****************************************************************************/
int board_boot_image(FAR const char *path, uint32_t hdr_size)
{
static struct arm_vector_table vt;
int fd;
ssize_t bytes;
fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0)
{
syslog(LOG_ERR, "Failed to open %s with: %d", path, fd);
return fd;
}
bytes = pread(fd, &vt, sizeof(vt), hdr_size);
if (bytes != sizeof(vt))
{
syslog(LOG_ERR, "Failed to read ARM vector table: %d", bytes);
return bytes < 0 ? bytes : -1;
}
#ifdef CONFIG_ARMV7M_SYSTICK
systick_disable();
#endif
cleanup_arm_nvic();
#ifdef CONFIG_ARMV7M_DCACHE
up_disable_dcache();
#endif
#ifdef CONFIG_ARMV7M_ICACHE
up_disable_icache();
#endif
#ifdef CONFIG_ARM_MPU
mpu_control(false, false, false);
#endif
/* Set main and process stack pointers */
__asm__ __volatile__("\tmsr msp, %0\n" : : "r" (vt.spr));
setcontrol(0x00);
ARM_ISB();
((void (*)(void))vt.reset)();
return 0;
}

View File

@ -43,6 +43,7 @@
#include <nuttx/i2c/i2c_master.h> #include <nuttx/i2c/i2c_master.h>
#include "sam_twihs.h" #include "sam_twihs.h"
#include "sam_progmem_common.h"
#include "same70-xplained.h" #include "same70-xplained.h"
#ifdef HAVE_ROMFS #ifdef HAVE_ROMFS
@ -240,7 +241,7 @@ int sam_bringup(void)
#ifdef HAVE_PROGMEM_CHARDEV #ifdef HAVE_PROGMEM_CHARDEV
/* Initialize the SAME70 FLASH programming memory library */ /* Initialize the SAME70 FLASH programming memory library */
ret = sam_progmem_init(); ret = sam_progmem_common_initialize();
if (ret < 0) if (ret < 0)
{ {
syslog(LOG_ERR, "ERROR: Failed to initialize progmem: %d\n", ret); syslog(LOG_ERR, "ERROR: Failed to initialize progmem: %d\n", ret);

View File

@ -1,268 +0,0 @@
/****************************************************************************
* boards/arm/samv7/same70-xplained/src/sam_progmem.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/mount.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/kmalloc.h>
#include <nuttx/mtd/mtd.h>
#ifdef CONFIG_BCH
#include <nuttx/drivers/drivers.h>
#endif
#include "sam_progmem.h"
#include "same70-xplained.h"
#ifdef HAVE_PROGMEM_CHARDEV
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
/****************************************************************************
* Private Types
****************************************************************************/
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
struct ota_partition_s
{
uint32_t offset; /* Partition offset from the beginning of MTD */
uint32_t size; /* Partition size in bytes */
const char *devpath; /* Partition device path */
};
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
static struct mtd_dev_s *sam_progmem_alloc_mtdpart(uint32_t mtd_offset,
uint32_t mtd_size);
static int init_ota_partitions(void);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static FAR struct mtd_dev_s *g_samv7_progmem_mtd;
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
static const struct ota_partition_s g_ota_partition_table[] =
{
{
.offset = CONFIG_SAMV7_OTA_PRIMARY_SLOT_OFFSET,
.size = CONFIG_SAMV7_OTA_SLOT_SIZE,
.devpath = CONFIG_SAMV7_OTA_PRIMARY_SLOT_DEVPATH
},
{
.offset = CONFIG_SAMV7_OTA_SECONDARY_SLOT_OFFSET,
.size = CONFIG_SAMV7_OTA_SLOT_SIZE,
.devpath = CONFIG_SAMV7_OTA_SECONDARY_SLOT_DEVPATH
},
{
.offset = CONFIG_SAMV7_OTA_SCRATCH_OFFSET,
.size = CONFIG_SAMV7_OTA_SCRATCH_SIZE,
.devpath = CONFIG_SAMV7_OTA_SCRATCH_DEVPATH
}
};
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
/****************************************************************************
* Name: sam_progmem_alloc_mtdpart
*
* Description:
* Allocate an MTD partition from FLASH.
*
* Input Parameters:
* mtd_offset - MTD Partition offset from the base address in FLASH.
* mtd_size - Size for the MTD partition.
*
* Returned Value:
* MTD partition data pointer on success, NULL on failure.
*
****************************************************************************/
static struct mtd_dev_s *sam_progmem_alloc_mtdpart(uint32_t mtd_offset,
uint32_t mtd_size)
{
uint32_t blocks;
uint32_t startblock;
ASSERT((mtd_offset + mtd_size) <= up_progmem_neraseblocks() *
up_progmem_pagesize(0));
ASSERT((mtd_offset % up_progmem_pagesize(0)) == 0);
ASSERT((mtd_size % up_progmem_pagesize(0)) == 0);
finfo("\tMTD offset = 0x%"PRIx32"\n", mtd_offset);
finfo("\tMTD size = 0x%"PRIx32"\n", mtd_size);
startblock = up_progmem_getpage(mtd_offset);
if (startblock < 0)
{
return NULL;
}
blocks = mtd_size / up_progmem_pagesize(0);
return mtd_partition(g_samv7_progmem_mtd, startblock, blocks);
}
/****************************************************************************
* Name: init_ota_partitions
*
* Description:
* Initialize partitions that are dedicated to firmware OTA update.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero on success; a negated errno value on failure.
*
****************************************************************************/
static int init_ota_partitions(void)
{
FAR struct mtd_dev_s *mtd;
#ifdef CONFIG_BCH
char blockdev[18];
#endif
int ret = OK;
for (int i = 0; i < ARRAYSIZE(g_ota_partition_table); ++i)
{
const struct ota_partition_s *part = &g_ota_partition_table[i];
mtd = sam_progmem_alloc_mtdpart(part->offset, part->size);
ret = ftl_initialize(i, mtd);
if (ret < 0)
{
ferr("ERROR: Failed to initialize the FTL layer: %d\n", ret);
return ret;
}
#ifdef CONFIG_BCH
snprintf(blockdev, 18, "/dev/mtdblock%d", i);
ret = bchdev_register(blockdev, part->devpath, false);
if (ret < 0)
{
ferr("ERROR: bchdev_register %s failed: %d\n", part->devpath, ret);
return ret;
}
#endif
}
return ret;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_progmem_init
*
* Description:
* Initialize the FLASH and register the MTD device.
****************************************************************************/
int sam_progmem_init(void)
{
int ret = OK;
/* Initialize the SAME70 FLASH programming memory library */
sam_progmem_initialize();
/* Create an instance of the SAME70 FLASH program memory device driver */
g_samv7_progmem_mtd = progmem_initialize();
if (g_samv7_progmem_mtd == NULL)
{
return -EFAULT;
}
#if defined(CONFIG_SAMV7_PROGMEM_OTA_PARTITION)
ret = init_ota_partitions();
if (ret < 0)
{
return ret;
}
#else
/* Use the FTL layer to wrap the MTD driver as a block driver */
ret = ftl_initialize(PROGMEM_MTD_MINOR, g_samv7_progmem_mtd);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to initialize the FTL layer: %d\n",
ret);
return ret;
}
#ifdef CONFIG_BCH
char blockdev[18];
char chardev[12];
/* Use the minor number to create device paths */
snprintf(blockdev, 18, "/dev/mtdblock%d", PROGMEM_MTD_MINOR);
snprintf(chardev, 12, "/dev/mtd%d", PROGMEM_MTD_MINOR);
/* Now create a character device on the block device */
ret = bchdev_register(blockdev, chardev, false);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: bchdev_register %s failed: %d\n",
chardev, ret);
return ret;
}
#endif /* CONFIG_BCH */
#endif
return ret;
}
#endif /* HAVE_PROGMEM_CHARDEV */