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