support openflashloader for nuttx
wiki:https://wiki.segger.com/SEGGER_Flash_Loader Signed-off-by: anjiahao <anjiahao@xiaomi.com> Signed-off-by: chao an <anchao@xiaomi.com>
This commit is contained in:
parent
85988dc77f
commit
d0ad047f81
44
system/ofloader/Kconfig
Normal file
44
system/ofloader/Kconfig
Normal file
@ -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
|
23
system/ofloader/Make.defs
Normal file
23
system/ofloader/Make.defs
Normal file
@ -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
|
30
system/ofloader/Makefile
Normal file
30
system/ofloader/Makefile
Normal file
@ -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
|
371
system/ofloader/ofloader.c
Normal file
371
system/ofloader/ofloader.c
Normal file
@ -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;
|
||||
}
|
68
system/ofloader/ofloader.h
Normal file
68
system/ofloader/ofloader.h
Normal file
@ -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 */
|
244
system/ofloader/segger.c
Normal file
244
system/ofloader/segger.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user