nuttx-apps/system/ofloader/segger.c
anjiahao d0ad047f81 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>
2023-08-01 23:22:52 -07:00

245 lines
7.2 KiB
C

/****************************************************************************
* 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;
}