代码拉取完成,页面将自动刷新
同步操作将从 觉皇/flmparse 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
* flmparse.c
*
* Created on: 2021年4月10日
* Author: hello
*/
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include "elf.h"
#define FILENAME "STM32F4xx_2048.FLM"
static int ReadDataFromFile(const char* FName, uint32_t offset, void* buf, uint32_t size);
static int FLM_Prase(const void* FName, void* pBuffer, uint32_t* Size, uint32_t* Init, uint32_t* UnInit, uint32_t* EraseChip, uint32_t* EraseSector, uint32_t* ProgramPage);
int main(int argc, char const *argv[])
{
int i = 0;
uint32_t RAM[256] = {0};
uint32_t Addr[5] = {0};
uint32_t Size = 0;
if(argc != 2)
{
printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
printf("Usage:\n");
printf(" flmparse.exe [filename]\n");
printf("\n\n");
goto __exit;
}
/* 这8个数是中断halt程序,让函数执行完后返回到这里来执行从而让CPU自动halt住 */
RAM[0] = 0xE00ABE00;
RAM[1] = 0x062D780D;
RAM[2] = 0x24084068;
RAM[3] = 0xD3000040;
RAM[4] = 0x1E644058;
RAM[5] = 0x1C49D1FA;
RAM[6] = 0x2A001E52;
RAM[7] = 0x4770D1F2;
if(FLM_Prase(argv[1], &RAM[8], &Size, &Addr[0],&Addr[1],&Addr[2],&Addr[3],&Addr[4]) < 0)
{
printf("错误:解析FLM格式文件失败,请检查FLM文件是否存在或格式正确性!\r\n");
goto __exit;
}
fprintf(stdout, "\r\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\r\n");
Size += 32;
fprintf(stdout, "\r\nstatic const uint32_t flash_code[] = \n{");
for(i = 0; i < (Size >> 2); i++)
{
if(i % 8 == 0)
{
fprintf(stdout, "\n ");
}
fprintf(stdout, "0X%08X,", RAM[i]);
}
fprintf(stdout, "\n};\n");
fprintf(stdout, "\r\nconst program_target_t flash_algo =\n{\n");
fprintf(stdout, " 0X%08X, // Init\n", Addr[0] + 0X20000020);
fprintf(stdout, " 0X%08X, // UnInit\n", Addr[1] + 0X20000020);
fprintf(stdout, " 0X%08X, // EraseChip\n", Addr[2] + 0X20000020);
fprintf(stdout, " 0X%08X, // EraseSector\n", Addr[3] + 0X20000020);
fprintf(stdout, " 0X%08X, // ProgramPage\n", Addr[4] + 0X20000020);
fprintf(stdout, "\n");
fprintf(stdout, " // BKPT : start of blob + 1\n");
fprintf(stdout, " // RSB : address to access global/static data\n");
fprintf(stdout, " // RSP : stack pointer\n");
fprintf(stdout, " {\n");
fprintf(stdout, " 0X20000001,\n");
fprintf(stdout, " 0X20000C00,\n");
fprintf(stdout, " 0X20001000,\n");
fprintf(stdout, " },\n");
fprintf(stdout, "\n");
fprintf(stdout, " 0x20000400, // mem buffer location\n");
fprintf(stdout, " 0x20000000, // location to write prog_blob in target RAM\n");
fprintf(stdout, " sizeof(flash_code), // prog_blob size\n");
fprintf(stdout, " flash_code, // address of prog_blob\n");
fprintf(stdout, " 0x00000400, // ram_to_flash_bytes_to_be_written\n");
fprintf(stdout, "};\n");
fprintf(stdout, "\n");
fprintf(stdout, "\n");
fprintf(stdout, "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
__exit:
return 0;
}
static int ReadDataFromFile(const char* FName, uint32_t offset, void* buf, uint32_t size)
{
int ret = 0;
int fd = 0;
if ((fd = open(FName, O_RDONLY | O_BINARY)) < 0)
{
ret = -1;
goto __exit;
}
if (lseek(fd, offset, SEEK_SET) < 0)
{
ret = -2;
goto __exit;
}
if (read(fd, buf, size) != size)
{
ret = -3;
goto __exit;
}
__exit:
close(fd);
return ret;
}
int FLM_Prase(const void* FName, void* pBuffer, uint32_t* Size, uint32_t* Init, uint32_t* UnInit, uint32_t* EraseChip, uint32_t* EraseSector, uint32_t* ProgramPage)
{
#define LOAD_FUN_NUM 5
uint8_t buffer[1024] = {0};
int i = 0, k = 0;
int found = 0;
const Elf32_Phdr* pPhdr = (const Elf32_Phdr *) buffer;
const Elf32_Shdr* pShdr = (const Elf32_Shdr *) buffer;
const Elf32_Sym* pSymbol = (const Elf32_Sym *) buffer;
Elf32_Ehdr ehdr = {0}; // ELF文件信息头
Elf32_Shdr ShdrSym = {0}; // 符号表头
Elf32_Shdr ShdrStr = {0}; // 字符串表头
const char* StrFunNameTable[LOAD_FUN_NUM] = { "Init", "UnInit", "EraseChip", "EraseSector", "ProgramPage"};
int StrFunIndexTable[LOAD_FUN_NUM] = {-1, -1, -1, -1, -1};
//
// 读取ELF文件头信息(ELF Header)
//
ReadDataFromFile(FName, 0, &ehdr, sizeof(Elf32_Ehdr));
// 不是ELF格式文件
if (strstr((const char *)ehdr.e_ident, "ELF") == NULL)
{
return -1;
}
//
// 读取程序头信息(Program Header)
//
ReadDataFromFile(FName, ehdr.e_phoff, buffer, sizeof(Elf32_Phdr) * ehdr.e_phnum);
for (i = 0; i < ehdr.e_phnum; i++)
{
if (pPhdr[i].p_type == PT_LOAD && (pPhdr[i].p_flags & (PF_X | PF_W | PF_R)) == (PF_X | PF_W | PF_R))
{
if (pPhdr[i].p_filesz > sizeof(buffer)) // RAM代码过大
{
return -2;
}
if(ReadDataFromFile(FName, pPhdr[i].p_offset, pBuffer, pPhdr[i].p_filesz) < 0) // 提取需要下载到RAM的程序代码
{
return -3;
}
printf("====:%d\r\n", pPhdr[i].p_filesz);
*Size = pPhdr[i].p_filesz;
}
}
//
// 读取节区头部(Sections Header)
//
ReadDataFromFile(FName, ehdr.e_shoff, buffer, sizeof(Elf32_Shdr) * ehdr.e_shnum);
// 查找符号表头并拷贝出来备用
for (i = 0; i < ehdr.e_shnum; i++)
{
if (pShdr[i].sh_type == SHT_SYMTAB)
{
memcpy(&ShdrSym, &pShdr[i], sizeof(Elf32_Shdr));
// 查找字符串表头并拷贝出来备用
if (pShdr[ShdrSym.sh_link].sh_type == SHT_STRTAB)
{
memcpy(&ShdrStr, &pShdr[ShdrSym.sh_link], sizeof(Elf32_Shdr));
found = 1;
break;
}
}
}
if(!found)
{
return -4;
}
//
// 根据字符串表头读取所有字符串表
//
ReadDataFromFile(FName, ShdrStr.sh_offset, buffer, ShdrStr.sh_size);
for (i = 0; i < ShdrStr.sh_size; i++) if (buffer[i] == '\0') buffer[i] = '\n';
buffer[ShdrStr.sh_size] = 0;
for (i = 0; i < LOAD_FUN_NUM; i++)
{
char* p = NULL;
if (StrFunNameTable[i] != NULL && (p = strstr((const char *) buffer, StrFunNameTable[i])) != NULL)
{
StrFunIndexTable[i] = (uint32_t) p - (uint32_t) buffer;
}
}
//
// 读取符号表
//
ReadDataFromFile(FName, ShdrSym.sh_offset, buffer, ShdrSym.sh_size);
// 遍历查询我们用到的函数符号
for (i = 0; i < ShdrSym.sh_size / sizeof(Elf32_Sym); i++, pSymbol++)
{
for (k = 0; k < LOAD_FUN_NUM; k++)
{
if (StrFunIndexTable[k] >= 0 && StrFunIndexTable[k] == pSymbol->st_name) // symbol.st_name的值就是偏移地址
{
switch (k)
{
case 0:
*Init = pSymbol->st_value;
break;
case 1:
*UnInit = pSymbol->st_value;
break;
case 2:
*EraseChip = pSymbol->st_value;
break;
case 3:
*EraseSector = pSymbol->st_value;
break;
case 4:
*ProgramPage = pSymbol->st_value;
break;
default:
break;
}
}
}
}
return 0;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。