This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx-apps.git

commit d0ad047f81d58fe7ca918559c9a95ab96e2e4fd5
Author: anjiahao <[email protected]>
AuthorDate: Thu Apr 6 15:42:57 2023 +0800

    support openflashloader for nuttx
    
    wiki:https://wiki.segger.com/SEGGER_Flash_Loader
    
    Signed-off-by: anjiahao <[email protected]>
    Signed-off-by: chao an <[email protected]>
---
 system/ofloader/Kconfig    |  44 ++++++
 system/ofloader/Make.defs  |  23 +++
 system/ofloader/Makefile   |  30 ++++
 system/ofloader/ofloader.c | 371 +++++++++++++++++++++++++++++++++++++++++++++
 system/ofloader/ofloader.h |  68 +++++++++
 system/ofloader/segger.c   | 244 +++++++++++++++++++++++++++++
 6 files changed, 780 insertions(+)

diff --git a/system/ofloader/Kconfig b/system/ofloader/Kconfig
new file mode 100644
index 000000000..74333238c
--- /dev/null
+++ b/system/ofloader/Kconfig
@@ -0,0 +1,44 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config SYSTEM_OFLOADER
+       tristate "Open flash loader"
+       default n
+       select DISABLE_IDLE_LOOP
+       ---help---
+               Enable support for flashloader.
+
+if SYSTEM_OFLOADER
+
+config SYSTEM_OFLOADER_PROGNAME
+       string "Program name"
+       default "ofloader"
+       ---help---
+               This is the name of the program that will be used when the NSH 
ELF
+               program is installed.
+
+config SYSTEM_OFLOADER_PRIORITY
+       int "ofloader task priority"
+       default 100
+
+config SYSTEM_OFLOADER_STACKSIZE
+       int "ofloader stack size"
+       default DEFAULT_TASK_STACKSIZE
+
+config SYSTEM_OFLOADER_BUFFERSIZE
+       int "ofloader transfer buffer size"
+       default 32768
+
+config SYSTEM_OFLOADER_DEBUG
+       bool "Open flashloader debug option"
+       default n
+
+config SYSTEM_OFLOADER_TABLE
+       string "open flashloder table"
+       ---help---
+               devname[,addr[,size]][;devname2[,addr[,size]]]
+               can enter multiple device nodes separated by semicolon
+
+endif
diff --git a/system/ofloader/Make.defs b/system/ofloader/Make.defs
new file mode 100644
index 000000000..e7b79a4fa
--- /dev/null
+++ b/system/ofloader/Make.defs
@@ -0,0 +1,23 @@
+############################################################################
+# apps/system/ofloader/Make.defs
+#
+# 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.
+#
+############################################################################
+
+ifneq ($(CONFIG_SYSTEM_OFLOADER),)
+CONFIGURED_APPS += $(APPDIR)/system/ofloader
+endif
diff --git a/system/ofloader/Makefile b/system/ofloader/Makefile
new file mode 100644
index 000000000..8145e53c6
--- /dev/null
+++ b/system/ofloader/Makefile
@@ -0,0 +1,30 @@
+############################################################################
+# apps/system/ofloader/Makefile
+#
+# 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.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+PROGNAME  = $(CONFIG_SYSTEM_OFLOADER_PROGNAME)
+PRIORITY  = $(CONFIG_SYSTEM_OFLOADER_PRIORITY)
+STACKSIZE = $(CONFIG_SYSTEM_OFLOADER_STACKSIZE)
+
+CSRCS  = segger.c
+MAINSRC = ofloader.c
+
+include $(APPDIR)/Application.mk
diff --git a/system/ofloader/ofloader.c b/system/ofloader/ofloader.c
new file mode 100644
index 000000000..bbd6801d1
--- /dev/null
+++ b/system/ofloader/ofloader.c
@@ -0,0 +1,371 @@
+/****************************************************************************
+ * apps/system/ofloader/ofloader.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 <inttypes.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <mqueue.h>
+#include <sys/ioctl.h>
+
+#include "ofloader.h"
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+struct devinfo_s
+{
+  int fd;
+  off_t pos;
+  off_t base;
+  size_t size;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int get_partinfo(FAR struct devinfo_s *devinfo)
+{
+  struct partition_info_s info;
+  int ret;
+
+  ret = ioctl(devinfo->fd, BIOC_PARTINFO, &info);
+  if (ret < 0)
+    {
+      return -errno;
+    }
+
+  devinfo->base = info.sectorsize * info.startsector;
+  devinfo->size = info.sectorsize * info.numsectors;
+  return 0;
+}
+
+static void free_devinfo(FAR struct devinfo_s *devinfo, size_t count)
+{
+  if (devinfo == NULL || count == 0)
+    {
+      return;
+    }
+
+  while (count-- != 0)
+    {
+      if (devinfo[count].fd > 0)
+        {
+          close(devinfo[count].fd);
+        }
+    }
+
+  free(devinfo);
+}
+
+static FAR struct devinfo_s *parse_devinfo(FAR size_t *index)
+{
+  char table[] = CONFIG_SYSTEM_OFLOADER_TABLE;
+  FAR struct devinfo_s *devinfo = NULL;
+  FAR struct devinfo_s *tmp;
+  FAR char *save_once;
+  FAR char *save;
+  FAR char *p;
+
+  *index = 0;
+  p = strtok_r(table, ";", &save_once);
+  while(p != NULL)
+    {
+      p = strtok_r(p, ",", &save);
+      if (p == NULL)
+        {
+          goto out;
+        }
+
+      tmp = realloc(devinfo, (*index + 1) * sizeof(struct devinfo_s));
+      if (tmp == NULL)
+        {
+          goto out;
+        }
+
+      devinfo = tmp;
+      devinfo[*index].fd = open(p, O_RDWR);
+      if (devinfo[*index].fd < 0)
+        {
+          goto out;
+        }
+
+      p = strtok_r(NULL, ",", &save);
+      devinfo[*index].base = strtoul(p, NULL, 0);
+      if (devinfo[*index].base == 0)
+        {
+          if (get_partinfo(&devinfo[*index]) < 0)
+            {
+              (*index)++;
+              goto out;
+            }
+
+          goto again;
+        }
+
+      p = strtok_r(NULL, ",", &save);
+      if (p == NULL)
+        {
+          (*index)++;
+          goto out;
+        }
+
+      devinfo[*index].size = strtoul(p, NULL, 0);
+      if (devinfo[*index].size == 0)
+        {
+          (*index)++;
+          goto out;
+        }
+
+again:
+      devinfo[*index].pos = devinfo[*index].base;
+      p = strtok_r(NULL, ";", &save_once);
+      (*index)++;
+  }
+
+  return devinfo;
+
+out:
+  free_devinfo(devinfo, *index);
+  return NULL;
+}
+
+static ssize_t read_safe(int fd, FAR uint8_t *buff, size_t size)
+{
+  ssize_t i = 0;
+
+  while (i < size)
+    {
+      ssize_t ret = read(fd, buff + i, size - i);
+      if (ret < 0)
+        {
+          return -errno;
+        }
+
+      i += ret;
+    }
+
+  return i;
+}
+
+static ssize_t write_safe(int fd, FAR uint8_t *buff, size_t size)
+{
+  ssize_t i = 0;
+
+  while (i < size)
+    {
+      ssize_t ret = write(fd, buff + i, size - i);
+      if (ret < 0)
+        {
+          return -errno;
+        }
+
+      i += ret;
+    }
+
+  return i;
+}
+
+static ssize_t handle(FAR struct ofloader_msg *msg,
+                      FAR struct devinfo_s *devinfo, size_t count)
+{
+  FAR uint8_t *buff = NULL;
+  ssize_t ret = 0;
+  size_t index;
+
+  for (index = 0; index < count; index++)
+    {
+      if (msg->addr >= devinfo[index].base &&
+          msg->addr < devinfo[index].base + devinfo[index].size)
+        {
+          break;
+        }
+    }
+
+  if (index == count)
+    {
+      return -ENODEV;
+    }
+
+  if (devinfo[index].pos != msg->addr)
+    {
+      off_t off = msg->addr - devinfo[index].pos;
+
+      off = lseek(devinfo[index].fd, off, SEEK_CUR);
+      if (off < 0)
+        {
+          OFLOADER_DEBUG("lseek error\n");
+          return -errno;
+        }
+
+      devinfo[index].pos = msg->addr;
+    }
+
+  OFLOADER_DEBUG("index %zu pos %" PRIxOFF "\n", index, devinfo[index].pos);
+  OFLOADER_DEBUG("atcion %d addr %" PRIxOFF "size %zu\n",
+                 msg->atcion, msg->addr, msg->size);
+  switch (msg->atcion)
+    {
+      case OFLOADER_SYNC:
+        ret = fsync(devinfo[index].fd);
+        if (ret < 0)
+          {
+            ret = -errno;
+          }
+
+        break;
+      case OFLOADER_VERIFY:
+        buff = malloc(msg->size);
+        if (buff == NULL)
+          {
+            OFLOADER_DEBUG("verify no mem\n");
+            return -ENOMEM;
+          }
+
+        ret = read_safe(devinfo[index].fd, buff, msg->size);
+        if (ret < 0)
+          {
+            OFLOADER_DEBUG("verify read error\n");
+            free(buff);
+            break;
+          }
+
+        devinfo[index].pos += ret;
+        if (memcmp(msg->buff, buff, ret) != 0)
+          {
+            OFLOADER_DEBUG("verify error\n");
+            ret = -EIO;
+            free(buff);
+            break;
+          }
+
+        free(buff);
+        break;
+      case OFLOADER_READ:
+        ret = read_safe(devinfo[index].fd, msg->buff, msg->size);
+        if (ret < 0)
+          {
+            OFLOADER_DEBUG("read error\n");
+            break;
+          }
+
+        devinfo[index].pos += ret;
+        break;
+      case OFLOADER_WRITE:
+        ret = write_safe(devinfo[index].fd, msg->buff, msg->size);
+        if (ret < 0)
+          {
+            OFLOADER_DEBUG("write error\n");
+            break;
+          }
+
+        devinfo[index].pos += ret;
+        break;
+    }
+
+  return ret;
+}
+
+static pthread_addr_t fake_idle(pthread_addr_t arg)
+{
+  for (;;)
+    {
+    }
+
+  return NULL;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * ofl_main
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  FAR struct devinfo_s *devinfo;
+  FAR struct ofloader_msg *msg;
+  pthread_attr_t attr;
+  pthread_t thread;
+  size_t count;
+  size_t i;
+  mqd_t mq;
+
+  if (g_create_idle)
+    {
+      pthread_attr_init(&attr);
+      attr.priority = 1;
+      pthread_create(&thread, &attr, fake_idle, NULL);
+      pthread_attr_destroy(&attr);
+    }
+
+  mq = mq_open(OFLOADER_QNAME, O_CREAT | O_RDWR, 0660, NULL);
+  if (mq < 0)
+    {
+      OFLOADER_DEBUG("mq_open error:%d\n", errno);
+      return -errno;
+    }
+
+  devinfo = parse_devinfo(&count);
+  if (devinfo == NULL)
+    {
+      OFLOADER_DEBUG("parsdevinfo error\n");
+      mq_close(mq);
+      return -EINVAL;
+    }
+
+  for (i = 0; i < count; i++)
+    {
+      OFLOADER_DEBUG("seq %d, base %" PRIxOFF ", size %zx\n",
+                     i, devinfo[i].base, devinfo[i].size);
+    }
+
+  while (1)
+    {
+      if (mq_receive(mq, (FAR void *)&msg, sizeof(msg), NULL) < 0)
+        {
+          OFLOADER_DEBUG(" mq_receive error %d\n", -errno);
+          continue;
+        }
+
+      if(handle(msg, devinfo, count) < 0)
+        {
+          msg->atcion = OFLOADER_ERROR;
+        }
+      else
+        {
+          msg->atcion = OFLOADER_FINSH;
+        }
+    }
+
+  /* Never run to here */
+
+  free_devinfo(devinfo, count);
+  mq_close(mq);
+  return 0;
+}
diff --git a/system/ofloader/ofloader.h b/system/ofloader/ofloader.h
new file mode 100644
index 000000000..37efff624
--- /dev/null
+++ b/system/ofloader/ofloader.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ * apps/system/ofloader/ofloader.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 __APPS_SYSTEM_OFLOADER_OFLOADER_H
+#define __APPS_SYSTEM_OFLOADER_OFLOADER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <syslog.h>
+#include <stdlib.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define OFLOADER_QNAME "ofloader"
+
+#define OFLOADER_WRITE  1
+#define OFLOADER_READ   2
+#define OFLOADER_VERIFY 3
+#define OFLOADER_SYNC   4
+#define OFLOADER_ERROR  5
+#define OFLOADER_FINSH  6
+
+#ifdef CONFIG_SYSTEM_OFLOADER_DEBUG
+#define OFLOADER_DEBUG(...) syslog(LOG_INFO, ##__VA_ARGS__)
+#else
+#define OFLOADER_DEBUG(...)
+#endif
+
+/****************************************************************************
+ * Public Type Definitions
+ ****************************************************************************/
+
+struct ofloader_msg
+{
+  int atcion;
+  off_t addr;
+  size_t size;
+  FAR void *buff;
+};
+
+/****************************************************************************
+ * Public data
+ ****************************************************************************/
+
+extern FAR void *g_create_idle;
+
+#endif /* __APPS_SYSTEM_OFLOADER_OFLOADER_H */
diff --git a/system/ofloader/segger.c b/system/ofloader/segger.c
new file mode 100644
index 000000000..0e4d6c6ae
--- /dev/null
+++ b/system/ofloader/segger.c
@@ -0,0 +1,244 @@
+/****************************************************************************
+ * apps/system/ofloader/segger.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 <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <mqueue.h>
+
+#include <nuttx/init.h>
+
+#include "ofloader.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ONCHIP       1       /* On-chip Flash Memory */
+#define ALGO_VERSION 0x101   /* Algo version, must not be modified. */
+
+/****************************************************************************
+ * Private Type Definitions
+ ****************************************************************************/
+
+struct SECTOR_INFO
+{
+  uint32_t SectorSize;       /* Sector Size in bytes */
+  uint32_t SectorStartAddr;  /* Start address of the sector area
+                              * (relative to the "BaseAddr" of the flash)
+                              */
+};
+
+struct FlashDevice
+{
+  uint16_t AlgoVer;
+  uint8_t  Name[128];
+  uint16_t Type;
+  uint32_t BaseAddr;
+  uint32_t TotalSize;
+  uint32_t PageSize;
+  uint32_t Reserved;
+  uint8_t  ErasedVal;
+  uint32_t TimeoutProg;
+  uint32_t TimeoutErase;
+  struct SECTOR_INFO SectorInfo[2];
+};
+
+const struct FlashDevice FlashDevice
+locate_data("DevDscr") used_data =
+{
+  ALGO_VERSION,                      /* Algo version */
+  "NuttX",                           /* Flash device name */
+  ONCHIP,                            /* Flash device type */
+  0x00000000,                        /* Flash base address */
+  0xffffffff,                        /* Total flash device size in Bytes */
+  CONFIG_SYSTEM_OFLOADER_BUFFERSIZE, /* Page Size (number of bytes that will
+                                      * be passed to ProgramPage(). May be
+                                      * multiple of min alignment in order
+                                      * to reduce overhead for calling
+                                      * ProgramPage multiple times
+                                      */
+  1,                                 /* Reserved, should be 1 */
+  0xff,                              /* Flash erased value */
+  5000,                              /* Program page timeout in ms */
+  5000,                              /* Erase sector timeout in ms */
+
+  /* Flash sector layout definition
+   * Sector size equl with page size to skip erase
+   */
+
+  {
+    {CONFIG_SYSTEM_OFLOADER_BUFFERSIZE, 0x00000000},
+    {0xffffffff, 0xffffffff}
+  }
+};
+
+/* This array is used to mark the stack and transfer buffer
+ *locations used by the ofloader
+ */
+
+static uint8_t g_stack_buff[CONFIG_SYSTEM_OFLOADER_STACKSIZE +
+                            CONFIG_SYSTEM_OFLOADER_BUFFERSIZE]
+locate_data("DevStack") used_data;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int SEGGER_FL_Prepare(uint32_t PreparePara0, uint32_t PreparePara1,
+                      uint32_t PreparePara2)
+  locate_code("PrgData") used_code;
+
+int SEGGER_FL_Restore(uint32_t PreparePara0, uint32_t PreparePara1,
+                      uint32_t PreparePara2)
+  locate_code("PrgData") used_code;
+
+int SEGGER_FL_Program(uint32_t DestAddr, uint32_t NumBytes,
+                      FAR uint8_t *pSrcBuff)
+  locate_code("PrgData") used_code;
+
+int SEGGER_FL_Erase(uint32_t SectorAddr, uint32_t SectorIndex,
+                    uint32_t NumSectors)
+  locate_code("PrgData") used_code;
+
+int SEGGER_FL_Read(uint32_t Addr, uint32_t NumBytes, FAR uint8_t *pDestBuff)
+  locate_code("PrgData") used_code;
+
+uint32_t SEGGER_FL_Verify(uint32_t Addr, uint32_t NumBytes,
+                          FAR uint8_t *pData)
+  locate_code("PrgData") used_code;
+
+/****************************************************************************
+ * Public data
+ ****************************************************************************/
+
+/* Reference SEGGER_FL_Prepare to prevent it from being
+ * optimized by the compiler
+ */
+
+FAR void *g_create_idle = SEGGER_FL_Prepare;
+
+static int SEGGER_FL_SendAndWait(FAR struct ofloader_msg *msg)
+{
+  int atcion = msg->atcion;
+  mqd_t mq;
+  int ret;
+
+  mq = mq_open(OFLOADER_QNAME, O_RDWR, 0666, NULL);
+  if (mq < 0)
+    {
+      return -errno;
+    }
+
+  ret = mq_send(mq, (FAR void *)&msg, sizeof(msg), 0);
+  if (ret < 0)
+    {
+      ret = -errno;
+      goto out;
+    }
+
+  /* TODO:SEGGER disables interrupts by default during operation
+   * so wait ofloader main thread do somthing.
+   */
+
+  while (msg->atcion == atcion);
+  if (msg->atcion == OFLOADER_ERROR)
+    {
+      ret = -EIO;
+      goto out;
+    }
+
+out:
+  mq_close(mq);
+  return ret;
+}
+
+extern void __start(void);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int SEGGER_FL_Prepare(uint32_t PreparePara0, uint32_t PreparePara1,
+                      uint32_t PreparePara2)
+{
+  g_create_idle = NULL;
+  __start();
+  return 0;
+}
+
+int SEGGER_FL_Restore(uint32_t PreparePara0, uint32_t PreparePara1,
+                      uint32_t PreparePara2)
+{
+  struct ofloader_msg msg;
+
+  msg.atcion = OFLOADER_SYNC;
+  return SEGGER_FL_SendAndWait(&msg);
+}
+
+int SEGGER_FL_Program(uint32_t DestAddr, uint32_t NumBytes,
+                      FAR uint8_t *pSrcBuff)
+{
+  struct ofloader_msg msg;
+
+  msg.addr = DestAddr;
+  msg.size = NumBytes;
+  msg.buff = pSrcBuff;
+  msg.atcion = OFLOADER_WRITE;
+  return SEGGER_FL_SendAndWait(&msg);
+}
+
+int SEGGER_FL_Erase(uint32_t SectorAddr, uint32_t SectorIndex,
+                    uint32_t NumSectors)
+{
+  return 0;
+}
+
+int SEGGER_FL_Read(uint32_t Addr, uint32_t NumBytes, FAR uint8_t *pDestBuff)
+{
+  struct ofloader_msg msg;
+
+  msg.addr = Addr;
+  msg.size = NumBytes;
+  msg.buff = pDestBuff;
+  msg.atcion = OFLOADER_READ;
+  return SEGGER_FL_SendAndWait(&msg);
+}
+
+uint32_t SEGGER_FL_Verify(uint32_t Addr, uint32_t NumBytes,
+                          FAR uint8_t *pData)
+{
+  struct ofloader_msg msg;
+
+  msg.addr = Addr;
+  msg.size = NumBytes;
+  msg.buff = pData;
+  msg.atcion = OFLOADER_VERIFY;
+  if (SEGGER_FL_SendAndWait(&msg) < 0)
+    {
+      return 0;
+    }
+
+  return Addr + NumBytes;
+}

Reply via email to