当前位置: 首页 > news >正文

BUG——imx6u开发_结构体导致的死机问题(未解决)

简介:

        最近在做imx6u的linux下裸机驱动开发,由于是学习的初级阶段,既没有现成的IDE可以使用,也没有GDB等在线调试工具,只能把代码烧写在SD卡上再反复插拔,仅靠卑微的亮灯来判断程序在哪一步。

        至于没有使用串口的原因是,我现在就是卡在了这个串口的开发上。我的感受和这位老兄大抵是相同的

问题为:对下面结构体局部变量的定义前面加上volatile关键字,结果程序运行到这步时,直接卡死。理论上,并不应该会出现这种情况

typedef struct{uint8_t HYS;   // 迟滞uint8_t PULL;  // 上拉/下拉uint8_t ODE;   // 开漏uint8_t SPEED; // 速度uint8_t DSE;   // 驱动强度uint8_t SRE;   // 转换速率uint8_t SION; // 软件输入             } MyStruct;/*------------在某个函数内部---------------*///定义一个局部变量时会卡死
volatile MyStruct my2 = {0};

尝试

        对此,我做了一些尝试,但仍未能找到根本原因:

1,猜测是成员变量导致的问题

        于是,我对成员变量的类型做了一些改变,发现,只要不都是uint8_t或者char类型就不会卡死

typedef struct{uint16_t HYS;   // 迟滞uint8_t PULL;  // 上拉/下拉uint8_t ODE;   // 开漏uint8_t SPEED; // 速度uint8_t DSE;   // 驱动强度uint8_t SRE;   // 转换速率uint8_t SION; // 软件输入             } MyStruct;typedef struct{uint8_t HYS;   // 迟滞uint8_t PULL;  // 上拉/下拉uint8_t ODE;   // 开漏uint8_t SPEED; // 速度uint8_t DSE;   // 驱动强度uint8_t SRE;   // 转换速率uint32_t SION; // 软件输入             } MyStruct;

        同时,对成员变量的数量做了一些改变,只要不是7个uint8_t或char类型,就不会卡死

typedef struct
{uint16_t HYS ;   // 迟滞uint16_t PULL ;  // 上拉/下拉uint16_t ODE ;   // 开漏uint16_t SPEED ; // 速度uint16_t DSE ;   // 驱动强度uint16_t SRE ;   // 转换速率uint16_t SION ;  // 软件输入} MyStruct;typedef struct{uint8_t HYS;   // 迟滞uint8_t PULL;  // 上拉/下拉uint8_t ODE;   // 开漏uint8_t SPEED; // 速度uint8_t DSE;   // 驱动强度uint8_t SRE;   // 转换速率uint8_t SION; // 软件输入   uint8_t SIO; // 软件输入             } MyStruct;

        此外,改变了结构体名也仍会出现上面问题

2,怀疑是优化级别导致的问题

        由于我默认开的是-O2级别优化,为此,对上述代码进行了-Og、-O0、-O1、-O2、-O3优化(没少被-O2坑过),结果仍会出现相同的问题。此外也怀疑过是堆栈溢出,但是栈大小足足设置了2MB,并且通过增加不优化的无关变量数组排除掉了这个可能。 

 3,怀疑是变量定义导致的

        于是尝试了下面几种形式,只要最后一种会出现这种问题。奇怪的是第三种竟然没出现问题(这可能是个伏笔)

   MyStruct my1;MyStruct my1 = {0};volatile MyStruct my1;volatile MyStruct my1 = {0};

4,怀疑是内存排列导致的问题(最有可能)

         对此,使用了__attribute__((aligned(4/6/8/16/32)));进行测试,仍然不能解决问题,改变了成员变量排列顺序(像是无用功)仍未解决

        后来使用了位域来测试,如果是uint32_t、uint16_t等组成的位域,哪怕都是8位位宽也不会出现问题。如果是7个uint8_t类型,倘若位宽不尽相同的话,那么也可能不会出现问题。

typedef struct
{uint16_t HYS : 8;   // 迟滞uint16_t PULL : 8;  // 上拉/下拉uint16_t ODE : 8;   // 开漏uint16_t SPEED : 8; // 速度uint16_t DSE : 8;   // 驱动强度uint16_t SRE : 8;   // 转换速率uint16_t SION : 8;  // 软件输入} MyStruct;typedef struct
{uint8_t HYS : 5;   // 迟滞uint8_t PULL : 5;  // 上拉/下拉uint8_t ODE : 5;   // 开漏uint8_t SPEED : 5; // 速度uint8_t DSE : 5;   // 驱动强度uint8_t SRE : 5;   // 转换速率uint8_t SION : 5;  // 软件输入} MyStruct1;typedef struct
{uint8_t HYS : 8;   // 迟滞uint8_t PULL : 8;  // 上拉/下拉uint8_t ODE : 8;   // 开漏uint8_t SPEED : 8; // 速度uint8_t DSE : 8;   // 驱动强度uint8_t SRE : 8;   // 转换速率uint8_t SION : 8;  // 软件输入} MyStruct2;

       进一步测试中发现,在选用7个uint8_t的情况下,如果位宽都为1、2、3、4就不会出现问题,如果是其余数字(包括8)就会出现问题。也就是说位宽都低于4(包括4),就不会发生问题。

        更进一步测试,如果7个uint8_t成员里,有至少两个位宽低于4(包括4),并且它们可以不连续排列,那么也不会发生问题

        由此观之,很大程度上与结构体在内存中的排列有关,这现象着实诡异,也可能与imx6u这块板有关,总之原因暂时不明

typedef struct
{uint8_t HYS : 1;   // 迟滞uint8_t PULL : 1;  // 上拉/下拉uint8_t ODE : 1;   // 开漏uint8_t SPEED : 1; // 速度uint8_t DSE : 1;   // 驱动强度uint8_t SRE : 1;   // 转换速率uint8_t SION : 1;  // 软件输入} MyStruct;typedef struct
{uint8_t HYS : 2;   // 迟滞uint8_t PULL : 2;  // 上拉/下拉uint8_t ODE : 2;   // 开漏uint8_t SPEED : 2; // 速度uint8_t DSE : 2;   // 驱动强度uint8_t SRE : 2;   // 转换速率uint8_t SION : 2;  // 软件输入} MyStruct1;typedef struct
{uint8_t HYS : 6;   // 迟滞uint8_t PULL : 6;  // 上拉/下拉uint8_t ODE : 6;   // 开漏uint8_t SPEED : 6; // 速度uint8_t DSE : 6;   // 驱动强度uint8_t SRE : 6;   // 转换速率uint8_t SION : 6;  // 软件输入} MyStruct2;

点灯调试:

    /*初始化串口IO*/volatile MyStruct my1 = {0};_Debug_LED;//卑微点灯宏volatile MyStruct1 my2 = {0};_Debug_LED;volatile MyStruct2 my3 = {0};_Debug_LED;volatile IOMUXC_ConfigTypeDef uart_config = {0}; // 卡死在这里,与结构体有关_Debug_LED;

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Redis 有序集合【实现排行榜】
  • 【ARM+Codesys 客户案例 】基于RK3568/A40i/STM32+CODESYS开发的控制器在自动输送分拣系统上的应用,支持定制
  • 大数据开发工程师面试整理-性能优化
  • 细数目标管理的坑:避免陷阱,实现高效执行
  • Oracle-OraclePartition
  • Unity | 游戏开发中的优化思维
  • 使用微软Detours库进行DLL注入
  • 【JAVA】阿里巴巴 EasyExcel:高效的Excel处理解决方案
  • 【java】RuoYi-Vue前后端分离版本-登陆请求流程解析
  • OpenAI推出GPT-4o微调功能
  • Nuitka 打包 exe 软件步骤
  • JSON, YAML, XML, CSV交互可视化
  • 设计模式六大原则(一)--单一职责原则
  • 一站式NVR模组解决方案:基于海思 3520D芯片的完整源码与系统集成
  • 基于Python的机器学习系列(7):多元逻辑回归
  • Git的一些常用操作
  • Java 23种设计模式 之单例模式 7种实现方式
  • Javascript弹出层-初探
  • k8s如何管理Pod
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Octave 入门
  • redis学习笔记(三):列表、集合、有序集合
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • Vue--数据传输
  • windows下如何用phpstorm同步测试服务器
  • 面试总结JavaScript篇
  • 项目实战-Api的解决方案
  • 新版博客前端前瞻
  • 一份游戏开发学习路线
  • 自制字幕遮挡器
  • ​MySQL主从复制一致性检测
  • ​第20课 在Android Native开发中加入新的C++类
  • ​软考-高级-系统架构设计师教程(清华第2版)【第1章-绪论-思维导图】​
  • ​数据链路层——流量控制可靠传输机制 ​
  • #Datawhale AI夏令营第4期#AIGC方向 文生图 Task2
  • #QT 笔记一
  • (2)nginx 安装、启停
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (多级缓存)多级缓存
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • (五)MySQL的备份及恢复
  • (一)基于IDEA的JAVA基础10
  • (原)本想说脏话,奈何已放下
  • (原創) 如何刪除Windows Live Writer留在本機的文章? (Web) (Windows Live Writer)
  • (转)http协议
  • (转)JAVA中的堆栈
  • (转)jQuery 基础
  • *Django中的Ajax 纯js的书写样式1
  • .gitignore文件使用
  • .NET Framework Client Profile - a Subset of the .NET Framework Redistribution
  • @EnableWebSecurity 注解的用途及适用场景
  • @RestControllerAdvice异常统一处理类失效原因