踩坑记 BSS段的初始化

news2024/11/7 5:25:10

title: 踩坑记 BSS段的初始化
category_bar: true
categories:

  • blog
    tags:
  • embedded
    date: 2023-10-20 19:23:05

前言

接手一个项目,调试全靠串口日志,测试同事测试产品的时候无法拿到日志,刚好产品RAM够大,且刚好有SD卡。所以就诞生了将日志缓存在RAM上,在特定条件下将它写到SD卡上的想法。
.
.
.
开工。
.
.
.
写完代码之后发现机器偶尔会无法启动,无法开机,无任何日志。
.
有的时候是烧录完成代码后重启无法启动,有些情况下是烧录完成代码后运行正常,放置一段时间后无法启动
.
有时候有些无法启动的机器放置一段时间又成功启动
.
.
.
一段一段代码,屏蔽,编译,验证,发现一个非常无法理解的事,TFCardLogBufferPut函数注释后设备可以正常启动。
.
.
.
看代码:

#define TF_CARD_LOG_BUFFER_SIZE     (64*1024ul)
uint8_t tfCardLogBuffer[TF_CARD_LOG_BUFFER_SIZE] = {0};
uint32_t tfCardLogBufferIndex = 0;

void TFCardLogBufferPut(uint8_t data) {
    tfCardLogBuffer[tfCardLogBufferIndex] = data;
    tfCardLogBufferIndex++;
    if( tfCardLogBufferIndex>=(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1 ) {
        tfCardLogBufferIndex = 0;
    }
}

.
.
.
我实在无法理解,这段代码是如何导致设备无法启动的,后面搁置了一段时间,遂归结于小众芯片不完善导致。
.
.
.
但是后面这个需求实在是过于旺盛,遂重新开始验证代码。

当时代码是这样的:

// main.c
int main(int argc, char **argv) {
    
    hal_uartInit();
    ax32xx_uart0SendByte('a');
    ax32xx_uart0SendByte('b');
    hal_uartSendData('1');
    hal_uartSendData('2');
    ax32xx_uart0SendByte('c');
    
    hal_sysInit();
    
    //.... some code here
}

// uart.c
void hal_uartSendData(u8 data)
{
    ax32xx_uart0SendByte(data);
    
    TFCardLogBufferPut(data);
}

void ax32xx_uart0SendByte(u8 data)
{
    R_UART_DATA0 = data;
    while((R_UART_PEND0 & 0x2)==0);
    R_UART_PEND0 |= 1;
}

#define TF_CARD_LOG_BUFFER_SIZE     (64*1024ul)
uint8_t tfCardLogBuffer[TF_CARD_LOG_BUFFER_SIZE] = {0};
uint32_t tfCardLogBufferIndex = 0;

void TFCardLogBufferPut(uint8_t data) {
    tfCardLogBuffer[tfCardLogBufferIndex] = data;
    tfCardLogBufferIndex = (tfCardLogBufferIndex>=(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1) ? 0 : tfCardLogBufferIndex+1;
}

运行后日志是这样的:

# 正常运行 的日志
ab12c ...

# 无法启动 的日志
ab1

.
.
.
后面我就猜想了很多:

  • 这个soc不能支持这么大的数值 64KB
  • 这个位置的内存被改写了
  • 和冷启动热启动有关
  • 芯片异常

.
.
.

后面我猜想,试试把TFCardLogBufferPut函数里面的tfCardLogBufferIndex的数值和data数值输出出来看看。
.
.

这一看不得了,越界了!

代码:
代码

输出日志:

ab1z31m00327300

.
.
.

这个tfCardLogBufferIndex越界了啊!而且初始化赋0并没有成功!这就非常坑爹了!
.
.
.
后面尝试在调用这个函数之前再次赋0,发现程序运行正常,设备也正常启动。

查看map文件这个数组和变量也是存放在BSS段的,这就非常令人费解了。
.
.
.
.
.
看到这里我直接就怀疑,就是这个芯片的锅。

但是别急这还不是让人最震惊的!后面还有让人更加鼻血飙升的。
.
.
.
.
.
.
.
.
.
.
.
.
.

最后找FAE排查问题很久,最后发现BSS段在hal_sysInit函数内初始化。

看代码:

void ax32xx_sysInit(u32 *saddr,u32 *eaddr)
{
	debg("sys init\n");			// 这个debg会调用 hal_uartSendData 函数输出日志
    
    //...
    
	ax32xx_wdtClear();

//-----cache set
	ax32xx_sysIcacheInit();
	ax32xx_sysDcacheInit();	
//-----bss clear
	ax32xx_sysBSSClear();
    
    // ...
}

.
.
.

实在是震惊,无法理解这个RAM的初始化为什么放在main函数里面,实在无法理解进入main函数了,c语言环境都没有OK。

最烦的就是这种xx芯片,总是会有一些让人血压飙升的操作。

.
.
.
.
.

教训

在对数组进行访问的时候一定要先检查范围。

// 原函数
void TFCardLogBufferPut(uint8_t data) {
    tfCardLogBuffer[tfCardLogBufferIndex] = data;
    tfCardLogBufferIndex = (tfCardLogBufferIndex>=(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1) ? 0 : tfCardLogBufferIndex+1;
}

// 改后
void TFCardLogBufferPut(uint8_t data) {
    if( tfCardLogBufferIndex>=(sizeof(tfCardLogBuffer)/sizeof(tfCardLogBuffer[0]))-1 ) {
        tfCardLogBufferIndex = 0;
    }
    tfCardLogBuffer[tfCardLogBufferIndex] = data;
    tfCardLogBufferIndex++;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1114996.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“传统”开发与AI开发的区别与联系(更新了GPT3.5的反馈)

1、传统开发的算法和软件整体,也可以看成是一个“大模型”,其中有不同层次的处理,最终能够完成从输入到输出的计算,不过,其中的计算都是人工定义的,一般依赖于研究成果的应用。研究成果在实际中的应用处理。…

伦敦银延时一定存在吗?

伦敦银市场是一个几乎24小时都在不停波动的市场,参与其中的人以短线交易为主,他们所追逐是行情短线波动所带来的收益,如果交易平台所提供的交易环境有问题,反复地出现延时、卡盘等的问题,恐怕会令投资的效果大打折扣&a…

window10/11 光学系统建模之Light Tools8.6 软件安装教程(亲测可用+附带免费资源可直接下载)

1.下载链接 (免费分享) 链接:https://pan.baidu.com/s/1qVubyRSC93xT-GKeK-k3ow 提取码:vkho 2.安装顺序 即按照图里的1234的顺序先安装完注册表,驱动,和lighttools的程序 我个人在win10系统安装这些程…

vuecli2关于下载本地取环境变量没问题部署后路径取不到环境变量问题解决

功能 下载功能,用a标签实现下载 代码错误思路分析 解决办法可以忽略直接看下面 解决思路 在每个config文件中都定义了file_url,本地运行没有问题,但是部署到服务器开发环境, 拿到的是生产环境的FILE_URL地址 首先看了流水线-构建配置-编译配置-编译脚本里的打包命令: ** 本…

澎湃OS上线:小米告别MIUI,跟小米汽车Say Hi

作者 | Amy 编辑 | 德新 10月17日,雷军发博官宣,「小米将启用全新操作系统,小米澎湃OS(Xiaomi HyperOS)」。 短短几百字的微博,数次提到了「小米汽车」: 小米向人车家全生态迈进,…

Kotlin笔记(六):泛型的高级特性

前面学习了Kotlin中的泛型的基本用法,跟Java中的泛型大致相同,Kotlin在泛型方面还提供了不少特有的功能,掌握了这些功能,你将可以更好玩转Kotlin,同时还能实现一些不可思议的语法特性,那么我们自然不能错过这部分内容了…

“30岁现象”揭示职场困境:职业瓶颈还是发展停滞?出路在何处?

“30岁现象”是指在职场上,30岁左右的员工面临一系列挑战和困境的一种现象。 以下是一些表现: 首先,许多30岁左右的员工会遭遇职业瓶颈,他们可能发现自己在职业发展上遇到了阻碍,难以再进一步。这可能是由于自身能力…

Spring Security基本认证(2)

前言: 对于安全管理框架而言,认证功能可以说是一切的起点,所以我们要研究Spring Security, 就要从最基本的认证开始。在Spring Security中,对认证功能做了大量的封装,以至于开发者只需要稍微配置一下就能使用认证功能&…

VBA_MF系列技术资料1-207

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧,我参考大量的资料,并结合自己的经验总结了这份MF系列VBA技术综合资料,而且开放源码(MF04除外),其中MF01-04属于定…

TCP通信实战:模拟BS系统

1、之前的客户端都是什么样的 其实就是CS架构,客户端是需要我们自己开发实现的 2、BS结构是什么样的,需要开发客户端吗? 浏览器访问服务端,不需要开发客户端 注意:服务端必须给浏览器响应HTTP协议格式的数据&#xff0…

CNN——卷积神经网络

文章目录 多层感知机(MLP,Multilayer Perceptron)神经网络定义MLP与神经网络的异同相同之处:不同之处:总结 为什么要使用神经网络CNN卷积层:池化层:全连接层: 卷积神经网络的优势pad…

Java持久层框架:MyBatis介绍

MyBatis 概述 概述 MyBatis,是支持定制化 SQL 、存储过程和高级映射的优秀持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain …

NVIDIA NCCL 源码学习(十一)- ring allreduce

之前的章节里我们看到了nccl send/recv通信的过程,本节我们以ring allreduce为例看下集合通信的过程。整体执行流程和send/recv很像,所以对于相似的流程只做简单介绍,主要介绍ring allreduce自己特有内容。 单机 搜索ring 在nccl初始化的过…

一道看似简单却易错的C语言的main函数的参数题目(海康威视的面试题)

一道海康的面试题,C语言的main函数有几个参数(多选) A:argc B:envp C:main D:argv 正确答案是:ABD 一般情况下,我们会认为是只有两个参数,因为从我们从第一…

JAVA栈、堆、方法区

一、什么是JAVA栈、堆、方法区 我们java程序的运行首先会先将.java的文件编译成.class文件,然后由JVM虚拟机的类加载器加载各个类的字节码文件到内存中进行执行,JVM虚拟机将这些数据加载到内存时会对内存进行划分为几个区域分别为栈、堆和方法区&#xf…

vue 02

目录简介 什么是渐进式框架? 就是一开始不需要你完全掌握它的全部功能特性,可以后续逐步增加功能。没有多做职责之外的事情。所以VUE的适用面很广,你可以用它代替老项目中的JQuery。也可以在新项目启动初期,有限的使用VUE的功能…

LLM ReAct: 将推理和行为相结合的通用范式 学习记录

LLM ReAct 什么是ReAct? LLM ReAct 是一种将推理和行为相结合的通用范式,可以让大型语言模型(LLM)根据逻辑推理(Reason),构建完整系列行动(Act),从而达成期望目标。LLM ReAct 可以应用于多种语言和决策任务,例如问答、事实验证、交互式决策等,提高了 LLM 的效率、…

论文导读 | 多模态知识图谱的构建

背景介绍 现有的知识图谱大多是以单一的文本的形式表示,而多模态知识图谱会将文本信息和图像等其他模态的信息综合起来。 多模态知识图谱主要分为两种表现形式,其一是将多模态信息作为实体的属性,另一种是将多模态信息作为单独的实体。 多…

uniapp接入萤石微信小程序插件

萤石官方提供了一些适用于uniapp / 小程序的方案 如 小程序半屏 hls rtmp 等 都TM有坑 文档写的依托答辩 本文参考了uniapp小程序插件 以及 萤石微信小程序插件接入文档 效果如下 1. 插件申请 登录您的小程序微信公众平台,点击左侧菜单栏,进入设置页…