首页 > 其他分享 >瑞萨问题排查记录

瑞萨问题排查记录

时间:2024-05-09 22:02:06浏览次数:20  
标签:CMN 记录 RFD bu4 bss 瑞萨 排查 FaciBaseAddress data

P1 当把 RFD28F 添加进项目时,报错如下:

参考链接: https://www.sekorm.com/news/73776172.html

栈溢出 .text

E0562330: Relocation size overflow : "DefaultBuild\sample_control_codeflash.obj" - ".text" -00000b

(1)右键 Subproject 的 CC-RH —— LinkOptions Tab —— Section —— Section start address 查看段分布。

(2)查看 subproject 的 DefaultBuild 文件夹下的 map 文件(MULTI_COER.map)。发现 .data 的 end address 距离 eitbl_pe0.const 的 start adress 还有很大的空间,不可能会越界。应该不是 段大小设置的问题,应该是代码的问题。

(3)首先通过 CS+ 的 查找工具 ctrl+F(“Find in files”,search location 选择“main project and subproject”),通过关键字 "sample_control_codeflash" 找到文件 "sample_control_codeflash.c"。

(4)右键 "sample_control_codeflash.c",选择 property,将 “Set as build-target” 设置为否,即屏蔽该文件,不让该文件参与编译。

(5)再次编译时,发现是 sample 文件夹下的 source 所有文件的问题。将这些文件全部屏蔽。发现编译通过。

备注:一般而言,双击编译器报错的行,会跳转到网页告诉你大致是什么错误。但是本机不能上外网。另一个方法是【点击 Help—— Open Help for Property Panel】
注意: 在不同的页面点击 Help—— Open Help for Property Panel 其跳转的网页均不同。网页就是当前页的相关帮助信息。

(6)双击编译输出的错误行,根据错误码,可以判断是跳转的错误。猜想是指令出了问题,指令相关选项一般在 "Compile Options" Tab。在当前页点击 Help—— Open Help for Property Panel,会出现当前页的相关指引。找到 “Specify jump instruction”的说明,应该选择 jarl32 跳转指令,即选择 "Create jarl32 and jr32 instructions"。

解决办法:打开build_tool工具,选到Compile options 
将Output code下面的Specify jump instruction设置为-Xcall_jump=32

最终,编译通过!

补充:但是办法只是并没有解决本质问题。

P2(接 P1)除了报错,还有一堆如下的 warning:

参考链接: https://www.sekorm.com/news/73776172.html

Section address is not assigned to ".R_RFD_CODE_CF.text"
Section address is not assigned to ".R_RFD_CODE_CF_RAM_NO_BGO.text"
...

备注:嵌入式的编译,一般要明白所有 warning 的原因,并消除所有的 warning,否则后面会出现各种奇奇怪怪问题。

既然 warning 是关于段的问题,因此我们去 map 文件查看,发现这几个段都处于 0xfdc0 24c0 ~ 0xfdc0 4041 ,而根据芯片手册,FDC0 0000H ~ FDC0 FFFFH 属于 Local RAM(CPU0) ,而这些 函数文本 text 段理应放在 .text (位于 code flash,根据手册,位于 0x00xx xxxx 开头的地址)

备注:对 section 地址的映射,可以在汇编代码里指出,也可以在 C 文件中用 pragma 关键字指出。

通过全局搜索 pragma,我们找到 r_rfd_memmap.h 文件,里面对 warning 涉及的所有段都进行了 pragma section 创建。
如下列链接所述, 通过编译指示pragma section,可以轻松地将多个对象定位到用户定义的section中。

https://blog.csdn.net/mirandali/article/details/118027790

再看 r_rf_cf_api.c 这个文件,这个文件是使用 define - include - undefine 的方式,将特定变量放在特定的段:

1)
#define R_RFD_EXTRA_START_SEC_CONST_UNSPECIFIED
#include "r_rfd_memmap.h"

2)
#define R_RFD_EXTRA_STOP_SEC_CONST_UNSPECIFIED
#include "r_rfd_memmap.h"

3) 
#define R_RFD_VERSION_CF_START_SEC_CONST_UNSPECIFIED
#include "r_rfd_memmap.h"

4) 
#define R_RFD_VERSION_CF_STOP_SEC_CONST_UNSPECIFIED
#include "r_rfd_memmap.h"

解决办法1:按照参考链接,在 link option 里将定义的段,分配到 0x0000 4000 后面的地址 【2023/10/11 注:0x0000 4000 是 code flash 的地址, BSS 段不可放于此处,应该放在地址为 0x0004 0000 的 data flash 空间】
在这里插入图片描述

解决办法2:在 r_rfd_memmap.h里,将 warning 的这几个段,都改为 #pragma section default

P3 发现当读取寄存器的值时报不对齐错误

在执行完如下寄存器赋值局部变量语句时,

l_bu4_FSTATR = R_RFD_REG_FSTATR;  

跳转到如下汇编,MAE 即 Miss Align Error,即地址不对齐错误

jr32 _Dummy ; MAE

上一条语句是下述的调用函数:

rfd_fv0_SetFaci(i_u2_TargetFACI)
{
 if (i_u2_TargetFACI == R_RFD_FACI0)
 {
    bu4_CMN_FaciBaseAddress = R_RFD_BASE_FACI0;
 }
}
========
#define R_RFD_BASE_FACI0 0xFFA10000UL

于是进入函数调试。

我们查看数据手册,寄存器 R_RFD_REG_FSTATRFaciBaseAddress + 0x80,即在 FACI 基地址上偏移 0x80。于是,关注FACI 基地址的赋值。

//  R_RFD_REG_FSTATR 的定义由来如下:
extern T_u4 bu4_CMN_FaciBaseAddress;
#define FACI (*(volatile struct faciRegisters *)bu4_CMN_FaciBaseAddress)
#define R_RFD_REG_FSTATR (FACI.FSTATR)

通过调试,确定编译时,bu4_CMN_FaciBaseAddress 即为 FACI0 的地址 0xFFA10000

if (i_u2_TargetFACI == R_RFD_FACI0)
{
  bu4_CMN_FaciBaseAddress = R_RFD_BASE_FACI0;
   ...
}
========
#define R_RFD_BASE_FACI0 0xFFA10000UL

我们再回到 bu4_CMN_FaciBaseAddress = R_RFD_BASE_FACI0; 对应的汇编代码。由于编译器会有优化策略,导致汇编代码有些理解不了的地方,我们勾选 Compile Options - Optimization-Level of optimizationPerform the default optimization 调整编译器优化策略为无策略。调整后,汇编代码如下:

bu4_CMN_FaciBaseAddress = R_RFD_BASE_FACI0;
movhi  0x3,  r0,  r2
movhi  0xffa1,  r0,  tp    ; tp 即 r5
st.w      tp  -0x3458[r2]  ; 0x00030000 - 0x00003458  = 0x2cba

由于 bu4_CMN_FaciBaseAddress 是全局变量,我们可以在 link options —— Output symbol information 里配置 Output symbol information 勾选为 Yes。这样 .map 文件就记录了全局变量的地址信息。

我们发现 bu4_CMN_FaciBaseAddress 的内存地址为 0x2cba,即汇编代码是成功将 tp (值为FACI0 的基地址:0xffa1) 写入变量bu4_CMN_FaciBaseAddress 。而 变量bu4_CMN_FaciBaseAddress 跟预期值不一致。手动修改 tp 寄存器的值,观察发现内存 0x2cba 的值依旧不变化。表明该地址无法执行写操作。

阅读代码,发现全局变量bu4_CMN_FaciBaseAddress 是未赋值的全局变量,应当放在 BSS 段。打开 Link Options —— Section —— Section start address 发现 _R_RFD_BSS,bss 段添加在了地址 0x00004000 后面,而该地址是 code flash ,是只读无法修改的地址。应该将该段添加在地址 0xFDC00000 里面,0xFDC00000 ~ 0xFDC0FFFF地址是 Local RAM(CPU0)。

// Section Settings
0xFDC0 0000     .data.R
                .bss
                .stack.bss

但是,应该注意,苏工在设置heap 时,让 heap 范围为 .stack.bss 的 end 到 0xFDC10000:

/* board.c */
extern char _E_stack_bss[];

void rt_hw_board_init()
{
  r_device_init();
  rt_system_heap_init((VOID *)_e_STACK_BSS, (void *)0xFDC10000);
  ...
}

其中 _E_STACK_BSS 是编译器自动生成的,表示段 .stack.bss 的 end address;同理,表示 _S_STACK_BSS 表示段 .stack.bss 的 start address。

因此,对于 .R_RFD_BSS.bss,必须放到 .stack.bss 前面:

// Section Settings
0xFDC0 0000     .data.R
                .bss
                .R_RFD_BSS.bss
                .stack.bss

完整的段设置 section settings 如下:

0x0000 4000     .const
                xxx
                xxx
                .data
                .xxx.text
                .xxx.text
0x0004 0000     EIINTTBL_PE0.const
                EIINTTBL_PE1.const
                EIINTTBL_PE2.const
                EIINTTBL_PE3.const
0xFDC0 0000     .data.R
                .bss
                .R_RFD_BSS.bss
                .stack.bss

补充1:要学会从导航栏 Help—Help 里寻找有用的信息,比如上述 _E_STACK_BSS_S_STACK_BSS的命名规则可以在帮助文档里的 Compiler—SECTION SPECIFICATIONS—Sections—Special Symbol 里找到。

补充2:注意 section settings 里将 .data 映射到 code flash(ROM),同时将其映射到 RAM 的段 data.R 放在 Local RAM 上。.data 与 .data.R 的映射关系在【 Link Options — Section — ROM to RAM mapped section】中添加 ,里面的值为 .data = .data.R

标签:CMN,记录,RFD,bu4,bss,瑞萨,排查,FaciBaseAddress,data
From: https://www.cnblogs.com/MasterBean/p/18183152

相关文章

  • stm32 出现 hard fault 的排查记录
    参考链接:https://blog.csdn.net/qq_43118572/article/details/1327596261、先验知识先验知识1:cortexm3在中断/异常时,会把8个寄存器(xPSR、PC、LR、R12以及R3-R0)的值压入栈。入栈顺序以及入栈后堆栈中的内容如下(CM4是从低地址到搞地质):地址寄存器被保存的顺序......
  • stm32 将外部 Flash挂载在 SPI 出现数据传输时好时不好的排查过程
    现象:将外部Flash挂载在SPI,在hardware_init()->read_jedec_id()里的result=spi->wr(spi,cmd_data,sizeof(cmd_data),recv_data,sizeof(recv_data))中,recv_data的值经常不一致,result的值偶尔为SFUD_SUCCESS,大部分会Error。备注:正常情况下,recv_data的值为......
  • SQL练习之打卡记录数据统计类问题
    最近老婆的公司,关闭了OA系统中,各类打卡时间数据统计的功能,为了不麻烦老婆手算,就做了一个简单的打卡系统,方便自动统计老婆想要知道的各类数据。做的过程中就遇到了几个还挺有意思的SQL,这里写成一篇博文,方便后期练习~Tip:需要答案的盆友可以访问参考答案的链接,密码是123456~建表......
  • 20240509线上问题排查
    iotop-oPpidstat-d1mpstat-PALL5cat/proc/*/status|grep-E'State:.*Z.*|State:.*D.*'-A10-B2tophttps://blog.csdn.net/chrisy521/article/details/128532234db.system.profile.find({"millis":{$gte:500}}).limit(10).sort({ts:......
  • 云服务器遭到黑客入侵植入木马病毒排查过程
    1、问题说明在一个安静的下午,突然手机上面接收到云服务器厂商发的一条短信。短信内容为服务器疑似被木马病毒入侵,监测到病毒文件。然后我就使用FinalShell登录服务器准备进去看一看,刚登陆进去FinalShell左边监控程序显示cpu占用100%。服务器正常来说cpu只会在3%~9%之间,突然这个CP......
  • crawlergo学习.pdf 观看学习笔记的记录
    起因想学习爬虫的编写:看到大佬对一个爬虫项目,的学习笔记。跟着大佬的学习笔记学一遍项目地址:https://github.com/Qianlitp/crawlergo学习记录: 对浏览器环境的hook: 看到这个之前没见到过学习一波参考文章理解爬虫HOOK技术-掘金(juejin.cn)   通过hook,修改j......
  • 记录一次虚拟机非LVM扩容的操作
    以下操作都是在测试机上进行操作的操作系统:Centos7.5  所属平台:EXSI由于本地根目录容量太小只有20G,在关闭虚拟机后将硬盘容量更改到100G,重新启动虚拟机。由于没有LVM通过传统的方式进行扩容目标将sda5扩大 通过fdisk可以看到,sda是有100G的,然后我们需要将其中多余的......
  • CF516E 做题记录
    link纪念一下独立切的*3100的数论+贪心题,思考时的思路一波三折,像极了考试中的我。个人感觉难度至少*3300。考虑先求出\(d=\gcd(n,m)\),那么编号根据模\(d\)结果分成了\(0...d-1\)共\(d\)个部分,每个部分里的人不能和外面的人玩。因此当\(d>b+g\)时一定无解,......
  • 学习记录+vcode+GPIO例程+正点原子 DNESP32S3 开发板教程-IDF 版
    第一个程序:UART模式和JTAG模式,配置完成不同。配置主要就是.vscode文件夹中 c_cpp_properties.json,tasks.json,launch.json,settings.json四个文件。一个想法:备份UART模式和JTAG模式的配置文件,用时直接文件替换。简单粗暴方式是.vscode文件夹替换。当然每次要选好串口、设置目标......
  • 记一次线上Redis内存占用过高、大Key问题的排查
    问题背景在一个风和日丽的下午,公司某项目现场运维同学反馈,生产环境3个Redis的Sentinel集群节点内存占用都很高,达到了17GB的内存占用量。稍加思索,应该是某些Key的Value数据体量过大,占用了过多的内存空间,我们在使用Redis的过程中,单个Value或者单个集合中的元素应该保证不超过10KB,......