STM32
直播中

徐胤

7年用户 1075经验值
私信 关注
[问答]

怎样通过Keil软件导出memory窗口的内容呢

怎么从导出的内容中解析出想要的数据呢?
怎样通过Keil软件导出memory窗口的内容呢?

回帖(1)

王珍珠

2021-11-19 11:42:55
  引言
  调试代码过程中经常将变量储存在大数组中,以分析数据的变化趋势。使用TI的ccs时,数组可以方便的导出。但是keil并没有直接导出数组的功能,好在keil提供了其他方法。Keil无法导出watch窗口的内容,但是可以导出memory窗口的内容。那么,怎么从导出的内容中解析出想要的数据呢?
  一、导出到文件
  导出方式如下:
  1、 将需要导出的变量添加到memory窗口
  2、 使用sava命令导出内存区域
  Save命令格式如下:
  SAVE d:data.txt 0x20000924,0x20000924 – 1 + 1000
  其中d:data.txt为要导出文件的路径,0x20000924为要导出内存区域的起始地址,0x20000924 - 1+2000为要导出内存区域的结束地址。每个地址1byte;要导出内存区域长度由数组大小决定,如uint32_t debug[1000]占用的内存为1000*4字节,若debug[0]的地址为0x20000924,上述命令可写成SAVE d:data.txt 0x20000924,0x20000924 – 1 + 4000,uint16_t[1000]占用内存为1000 * 2字节,若debug[0]的地址为0x20000924,上述命令可写成SAVE d:data.txt 0x20000924,0x20000924 – 1 + 2000;导出的数据按照HEX386格式保存。
  二、HEX386格式解析
  HEX386格式也叫intel hex格式,在keil官网可以找到该格式的详细定义,
  
  使用keil导出的hex386格式文本每行以:开头
  接下来一个字节为ll,表示有效数据长度
  接下来两个字节为aaaa,表示这一行数据的起始地址
  接下来一个字节为tt,表示这一行数据的含义,
  tt=00表示本行数据为导出的内存数据
  tt=01表示本行是文件的结尾
  tt=02表示本行记录的是内存段
  tt=04表示本行记录的是内存地址
  接下来若干字节为数据
  最后一个字节为校验
  
  综上,解析hex文件就是找出tt = 00时的数据。
  三、合成有效数据
  完成hex文件的解析之后,只是实现了按照地址从低到高逐字节读出,还需要根据数组储存数据的类型进行转换。
  因为stm32使用小端模式储存数据,对于32位数据aabbccdd,在内存中有低到高储存为ddccbbaa,所以完成hex格式解析后,要根据需要的数据类型重新排列数据,并转换为便于观察的整形数据。
  对于有符号数,需要增加正负处理。
  四、matlab代码实现
  本次实验通过三部实现上述过程:
  1) 读取文本文件到字符串数组
  具体代码如下:
  function strArray = readDataFromTxt(filename)
  f = fopen(filename,‘r’);
  line_num = 1;
  while 1
  tmp = string(fgetl(f));
  if(tmp) == “-1”
  break;
  else
  strArray(line_num) = tmp;
  line_num = line_num + 1;
  end
  end
  函数输入为文件路径。
  函数输出为字符串数组。
  2) 解析hex格式
  代码如下:
  function [address,data] = hex386Decode(strArray)
  dataIndex = 1;
  for rowIndex = 1 : length(strArray)%逐行扫描
  charTmp = char(strArray(rowIndex));
  byteNum = length(charTmp);
  state = 1;
  byteIndex = 1;
  while 1 %逐字节扫描
  switch(state)
  case(1)%:
  if(charTmp(byteIndex) == ‘:’)
  state = 2;
  byteIndex = byteIndex + 1;
  end
  case(2)%ll
  dataByteNum = hex2dec(charTmp(byteIndex:byteIndex+1));
  state = 3;
  byteIndex = byteIndex + 2;
  case(3)%aaaa
  addr = hex2dec(charTmp(byteIndex:byteIndex+3));
  state = 4;
  byteIndex = byteIndex + 4;
  case(4)%tt
  dataType = hex2dec(charTmp(byteIndex:byteIndex+1));
  if(dataType == 0)
  state = 5;
  byteIndex = byteIndex + 2;
  else
  break;
  end
  case(5)%[dddddd]
  for dataByteCnt = 1 : dataByteNum
  address(dataIndex) = addr + dataByteCnt - 1;
  data(dataIndex,1:2) = charTmp(byteIndex:byteIndex+1);
  byteIndex = byteIndex + 2;
  dataIndex = dataIndex + 1;
  end
  break;
  end
  end
  end
  使用状态机控制读取过程。
  函数输入为字符串数组,字符串数组的序号对应导出文本的行。
  函数输出为内存地址,以及每个地址对应的内容。
  3) 转换为真实数据
  代码如下:
  function data = byte2word(hexByte,bits,isSigned)
  data = ‘ff’;
  switch(bits)
  case(8)
  data = hexByte;
  case(16)
  len = length(hexByte);
  cutNum = mod(len,4);
  hexByte = hexByte(1:len - cutNum,:);
  byte1 = 1 : 2 : length(hexByte);
  byte2 = 2 : 2 : length(hexByte);
  data = [hexByte(byte2,:),hexByte(byte1,:)];
  case(32)
  len = length(hexByte);
  cutNum = mod(len,4);
  hexByte = hexByte(1:len - cutNum,:);
  byte1 = 1 : 4 : length(hexByte);
  byte2 = 2 : 4 : length(hexByte);
  byte3 = 3 : 4 : length(hexByte);
  byte4 = 4 : 4 : length(hexByte);
  data = [hexByte(byte4,:),hexByte(byte3,:),hexByte(byte2,:),hexByte(byte1,:)];
  case(64)
  len = length(hexByte);
  cutNum = mod(len,4);
  hexByte = hexByte(1:len - cutNum,:);
  byte1 = 1 : 8 : length(hexByte);
  byte2 = 2 : 8 : length(hexByte);
  byte3 = 3 : 8 : length(hexByte);
  byte4 = 4 : 8 : length(hexByte);
  byte5 = 5 : 8 : length(hexByte);
  byte6 = 6 : 8 : length(hexByte);
  byte7 = 7 : 8 : length(hexByte);
  byte8 = 8 : 8 : length(hexByte);
  data = [hexByte(byte8,:),hexByte(byte7,:),hexByte(byte6,:),hexByte(byte5,:),hexByte(byte4,:),hexByte(byte3,:),hexByte(byte2,:),hexByte(byte1,:)];
  otherwise
  err = “不支持的输入”
  end
  data = hex2dec(data);
  if(isSigned 》 0)
  switch(bits)
  case(8)
  data(data 》= 2^7)= -2^8 + data(data 》= 2^7);
  case(16)
  data(data 》= 2^15)= -2^16 + data(data 》= 2^15);
  case(32)
  data(data 》= 2^31)= -2^32 + data(data 》= 2^31);
  case(64)
  data(data 》= 2^63)= -2^64 + data(data 》= 2^63);
  end
  end
  函数输入为hexByte字符数组,每行为一个byte的内存数据。bits为每个输出数据占用的内存字节数,支持8bit,16bit,32bit,64bit,isSigned 》0表示数据为有符号数,否则数据为无符号数。
  函数输出为想要导出的数组内容。
  发挥matlab矩阵操作的优势,实现了8位、16位、32位、64位有符号整形及无符号整形的处理。
  4)调用方式如下:
  file = ‘d:data.txt’
  strArray = readDataFromTxt(file);
  [a,d] = hex386Decode(strArray);
  data = byte2word(d,32,0)
举报

更多回帖

发帖
×
20
完善资料,
赚取积分