全志V3S嵌入式驱动开发(解决32M spi-nor无法复位问题)

news2024/9/20 9:06:58

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        之前制作spi-nor image的时候,就发现v3s存在无法复位的问题。只要进入linux之后,不管是console输入reboot指令,还是按下复位键,都存在无法重启的问题。一开始,以为是硬件哪里出了问题,但是sd卡启动或者spi-nand启动的时候,则没有这个现象。这说明,应该不是硬件的问题,或者至少说不是共性问题,需要个别好好研究一下。

1、第一步,论坛找方案

        出现问题之后,第一步就是上网看看有没有其他同学遇到类似的问题,果然还发现了一个,

https://whycan.com/t_4550.html

        在它的描述中,输入reboot没有重启,主要是因为spi-nor还处于4 byte访问模式,没有办法重新启动。如果想reboot之后,还能正常从spi-nor启动,就必须要在启动前退出4 byte模式。之前选用spi-nor的时候,挑选的是mx25l25645g,大小是256M bit,即32M byte,确实超过了16M的正常地址访问空间。

        论坛上的讨论还说到,如果想退出这个模式,要么手改驱动,要么换上可以置位的pmu。当然,换pmu太麻烦了,还是修改驱动代码吧。网页上也给出了对应的地址,

https://whycan.com/t_534.html#p1447

        不想查看网页的朋友,可以直接看这个修改补丁,

static int m25p_remove(struct spi_device *spi) 
{ 
    struct m25p *flash = spi_get_drvdata(spi); 

    // manfeel note: add spi flash reset code 
    flash->command[0] = 0x66; 
    spi_write(flash->spi, flash->command, 1); 
    flash->command[0] = 0x99; 
    spi_write(flash->spi, flash->command, 1);
    /* Clean up MTD stuff. */ 
    return mtd_device_unregister(&flash->mtd); 
} 
 
 
static struct spi_driver m25p80_driver = { 
    .driver = { 
        .name   = "m25p80", 
        .owner  = THIS_MODULE, 
    }, 
    .id_table   = m25p_ids, 
    .probe  = m25p_probe, 
    .remove = m25p_remove, 
    // manfeel, add shutdown method to reset spi flash 
    .shutdown = m25p_remove, 
 
    /* REVISIT: many of these chips have deep power-down modes, which
     * should clearly be entered on suspend() to minimize power use.
     * And also when they're otherwise idle...
     */ 
};

        修改的文件位于w25p80.c,修改也确实不复杂,主要就是在芯片remove的时候发送两条命令,一条是0x66,一条是0x99。为了知道这两条命令啥意思,我们特定找了mx25l25645g的芯片手册来看,

        它的中心意思还是比较简单。一句话来说,就是实现spi-nor的复位模式,用0x66、0x99来实现和断电复位一样的效果。

2、准备测试

        看上去一切都准备好了。可是还是出错了,问题就出在我们的kernel比较新,是linux kernel 5.2.y版本,编译出来一堆错误,根本没有办法编译通过。比如它会告诉你,flash没有spi这个变量,spi没有command这个变量等等,这些都很明显,就是kernel版本不匹配,

drivers/mtd/devices/m25p80.c: In function ‘m25p_remove’:
drivers/mtd/devices/m25p80.c:249:7: error: ‘struct m25p’ has no member named ‘command’
  flash->command[0] = 0x66;
       ^~
drivers/mtd/devices/m25p80.c:250:19: error: ‘struct m25p’ has no member named ‘spi’; did you mean ‘spimem’?
  spi_write(flash->spi, flash->command, 1);
                   ^~~
                   spimem
drivers/mtd/devices/m25p80.c:250:29: error: ‘struct m25p’ has no member named ‘command’
  spi_write(flash->spi, flash->command, 1);
                             ^~
drivers/mtd/devices/m25p80.c:251:14: error: ‘struct m25p’ has no member named ‘command’
         flash->command[0] = 0x99;
              ^~
drivers/mtd/devices/m25p80.c:252:26: error: ‘struct m25p’ has no member named ‘spi’; did you mean ‘spimem’?
         spi_write(flash->spi, flash->command, 1);
                          ^~~
                          spimem
drivers/mtd/devices/m25p80.c:252:36: error: ‘struct m25p’ has no member named ‘command’
         spi_write(flash->spi, flash->command, 1);
                                    ^~
make[3]: *** [scripts/Makefile.build:279: drivers/mtd/devices/m25p80.o] Error 1
make[2]: *** [scripts/Makefile.build:498: drivers/mtd/devices] Error 2
make[1]: *** [scripts/Makefile.build:498: drivers/mtd] Error 2
make: *** [Makefile:1077: drivers] Error 2

3、另辟蹊径

        到这里,有的同学也许会说,既然这样,我们不如研究一下如何在现有版本的基础上实现spi_write这些内容。可人毕竟是想偷懒一下的,总想找到一个更容易的办法。很幸运,我们又找到这个链接,

https://blog.csdn.net/Adrian503/article/details/118484202

        文章提示我们,现在新版本的kernel已经支持spi-nor在reboot的时候,进行模式切换了。它所要做的也很简单,就是在spi-nor.c文件中,把对应型号的模式修改一下即可,这很对我们的脾气。修改前,驱动的注册是这样的,

{ "mx25l25645g", INFO(0xc22019, 0, 64 * 1024, 512, 0) },

        修改之后,是这样的,

{ "mx25l25645g", INFO(0xc22019, 0, 64 * 1024, 512, SPI_NOR_4B_OPCODES) },

        修改后,验证了一下,果然是有效的。不管是手动输入reboot,还是按下复位键,系统都可以正常重启了。这说明我们的修改是对的。

4、修改过程中的小插曲

        这次因为修改的是spi-nor镜像,所以一部分代码又从spi-nand回退过来了。但是回退的过程中就发现了,我们修改了kernel代码之后,内核没有办法自动从uboot加载了。这还不是最诡异的,最奇怪的是手动sf read和bootz之后却又是可以加载的,只不过文件系统又起不来了,真是匪夷所思。

[    7.166496] VFS: Mounted root (jffs2 filesystem) on device 31:3.
[    7.172557] devtmpfs: error mounting -2
[    7.177734] Freeing unused kernel memory: 1024K
[    7.182449] Run /sbin/init as init process
[    7.186654] Run /etc/init as init process
[    7.190678] Run /bin/init as init process
[    7.194754] Run /bin/sh as init process
[    7.198602] Kernel panic - not syncing: No working init found.  Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance.
[    7.212754] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.2.0-licheepi-zero #14
[    7.219877] Hardware name: Allwinner sun8i Family
[    7.224611] [<c010ede4>] (unwind_backtrace) from [<c010b774>] (show_stack+0x10/0x14)
[    7.232353] [<c010b774>] (show_stack) from [<c075c598>] (dump_stack+0x88/0x9c)
[    7.239572] [<c075c598>] (dump_stack) from [<c011dd64>] (panic+0x110/0x2fc)
[    7.246534] [<c011dd64>] (panic) from [<c0772dbc>] (kernel_init+0xfc/0x10c)
[    7.253494] [<c0772dbc>] (kernel_init) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
[    7.261051] Exception stack(0xc3833fb0 to 0xc3833ff8)
[    7.266099] 3fa0:                                     00000000 00000000 00000000 00000000
[    7.274266] 3fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[    7.282431] 3fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[    7.289051] Rebooting in 5 seconds..

        问题折腾来折腾去,弄了一个晚上,直到后来休息了一会,才想起来应该是自己把spi-nand的布局模式当成了之前spi-nor的布局。spi-nand的布局中,0x100000 ~0x120000是dtb,0x120000 ~ 0x620000是kernel。而spi-nor的布局中,0x100000~0x110000是dtb,0x110000~0x610000是kernel。就是这中间0x10000大小的差距,产生了林林总总奇怪的现象,因此后期这部分还是有必要统一解决下的。要么都是一样的布局,要么用脚本自动屏蔽差异。

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

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

相关文章

【C/C++解决读者-写者问题】

目录 一、问题描述二、问题分析三、三种策略实现1.读者优先策略2. 读写公平策略3.写者优先策略&#xff08;后续更新&#xff09; 一、问题描述 有读者和写者两组并发进程&#xff0c;共享一个文件&#xff0c;当两个或两个以上的读进程&#xff08;只是读数据&#xff0c;不会…

将数据转化为创新机会:8 种业务分析模型指南

当我们想要创新时&#xff0c;往往需要有实际的依据来支撑我们的想法。商业咨询顾问通常被认为是聪明的人&#xff0c;他们拥有模型化的分析思维&#xff0c;这种思维方式可以帮助他们更好地理解市场、竞争对手和客户需求。商业分析思维是一种系统性的思考方式&#xff0c;它可…

力扣 222. 完全二叉树的节点个数

题目来源&#xff1a;https://leetcode.cn/problems/count-complete-tree-nodes/description/ C题解1&#xff1a;层序遍历计算节点。 时间复杂度&#xff1a;O(n)空间复杂度&#xff1a;O(n) /*** Definition for a binary tree node.* struct TreeNode {* int val;* …

已开源!网易云信的热点探测平台实践

背景 对于一个互联网平台&#xff0c;特别是 toB 的 PaaS/SaaS 平台&#xff0c;热点 key 是一个绕不过去的问题。作为一个开放的系统&#xff0c;平台每天要承载来自大量的外部系统或者海量终端的请求&#xff0c;虽然所有的请求都需要满足开放平台定义好的鉴权规则&#xff0…

虚幻引擎(UE5)-大世界分区WorldPartition教程(四)

文章目录 前言一、Data Layers的使用1.添加Actor到Data Layers2.运行时处理 总结 上一篇&#xff1a;虚幻引擎(UE5)-大世界分区WorldPartition教程(三) 前言 Data Layers&#xff08;UE4中叫Layers&#xff09;用于将Actor划分到不同的Layer中&#xff0c;通过在编辑器和运行…

Qt在Ubuntu下如何进行桌面软件开发?

文章目录 0.引言1.新建项目2.编写第一个程序3.在Qt外部启动程序 0.引言 笔者研究的方向涉及在ubuntu中运行代码&#xff0c;早先是直接利用控制台运行代码文件&#xff0c;在控制台中虽然设法将代码精简到一个三个文件中&#xff0c;只需要在控制台运行这三个文件即可&#xff…

应用在5W~20W无线充电器中的电机驱动芯片

随着用电设备对供电质量、安全性、可靠性、方便性、即时性、特殊场合、特殊地理环境等要求的不断提高&#xff0c;使得接触式电能传输方式越来越不能满足实际需要。无线充电器是利用电磁感应原理进行充电的设备&#xff0c;其原理和变压器相似&#xff0c;通过在发送和接收端各…

基于深度学习的高精度条形码二维码检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度条形码二维码检测识别系统可用于日常生活中或野外来检测与定位条形码二维码目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的条形码二维码目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系…

2023上半年软考系统分析师科目一整理-07

2023上半年软考系统分析师科目一整理-07 信息资源规划&#xff08;Information Resource Planning&#xff0c;IRP&#xff09;是信息化建设的基础工程&#xff0c;IRP强调将需求分析与&#xff08; &#xff09;结合起来。IRP的过程大致可以分为7个步骤&#xff0c;其中&#…

微信小程序组件间通讯

1.父传子 1.1父组件 1.1.1wxml文件 <!-- 定义的my-props组件 --> <my-props count"{{count}}"></my-props> <!-- 分割线 --> <view></view> <view>父组件的count值:{{count}}</view> <button bindtap"ad…

一步一步学OAK之五:通过OAK相机实现边缘检测

目录 边缘检测简介Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 创建pipelineSetup 5: 创建节点创建相机节点创建边缘检测节点创建XLinkOut数据交互的节点 Setup 6:设置相关属性设置彩色相机的相关属性设置左侧和右侧的单目相机的相关属性设置边缘检测器的…

【计算机网络 - 第三章】运输层

目录 一、多路复用和多路分解 1、运输层端口号 2、概述 3、原理 1、无连接的多路复用与多路分解 - UDP 2、面向连接的多路复用与多路分解 - TCP 二、无连接运输——UDP用户数据报协议 1、UDP概述 2、UDP的优点 三、可靠数据传输原理 1、概述 2、rdt1.0——可靠信道上…

【AUTOSAR】BMS开发实际项目讲解(十一)----电池管理系统相关项功能安全要求

相关项功能安全要求 SG-BMS-1 : BMS系统应防止电池单体过充导致热失控&#xff08;ASIL C&#xff09; 功能框图&#xff08;SG-BMS-1&#xff09; 功能组件说明 功能组件ID 功能组件名称 描述 ASIL等级 FSC-FC-01 Detection Cell Volt&Temp 采集表征单体电压和温度的…

Qt中QCompleter自动补全功能

在Qt中有QCompleter这个类可以和QLineEdit组合实现自动补全功能&#xff0c;类似搜索框形式的&#xff0c; 1.QCompleter类可以在输入框输入字符时&#xff0c;进行提示可以匹配上的字符 例&#xff1a;为QLineEdit设置自动补全QLineEdit* pLineEdit new QLineEdit(this);QStr…

【算法】最长递增子序列:动态规划贪心+二分查找

文章目录 最长递增子序列解法一&#xff1a;动态规划解法二&#xff1a;LIS 和 LCS 的关系解法三&#xff1a;贪心 二分查找 相关题目673. 最长递增子序列的个数 https://leetcode.cn/problems/number-of-longest-increasing-subsequence/1964. 找出到每个位置为止最长的有效障…

29.组件库 Element UI

Element UI是PC端常用的组件库&#xff0c;支持vue2与vue3&#xff0c;vue2项目使用的叫 Element UI,vue3使用的叫 Elements Plus&#xff0c;官网地址 一个 Vue 3 UI 框架 | Element Plus 我们下面的代码都是以vue3为例 目录 1 安装 2 引入 3 使用 1 安装 2 引入 完…

快消EDI:联合利华Unilever EDI需求分析

联合利华&#xff08;Unilever&#xff09;是一家跨国消费品公司&#xff0c;总部位于英国和荷兰&#xff0c;在全球范围内经营着众多知名品牌&#xff0c;涵盖了食品、饮料、清洁剂、个人护理产品等多个领域。作为一家跨国公司&#xff0c;联合利华在全球各地都有业务和生产基…

el-table表单一键展开折叠,展开部分后一键全部展开或折叠

实现功能&#xff1a; 1.表单一键展开或者一键折叠 2.表单点击展开一部分后&#xff0c;再次点击展开或折叠按钮可以全部展开或全部折叠 3.完整代码在最后 1.建立el-table的树形结构 1.ref"table"&#xff0c;用节点绑定的方式实现 2.data&#xff1a;树形结构…

Redis系列--数据过期清除策略缓存淘汰策略

一、过期策略 一、前言 Redis 所有的数据结构都可以设置过期时间&#xff0c;时间一到&#xff0c;就会自动删除。可以想象里面有一个专门删除过期数据的线程&#xff0c;数据已过期就立马删除。这个时候可以思考一下&#xff0c;会不会因为同一时间太多的 key 过期&#xff0…

windows电脑设置每天自动关机

有时候我们需要我们的笔记本或者电脑在每天固定的时间自动关机&#xff0c;但是windows本身是没有带这个设置的&#xff0c;下面记录下如何设置电脑每天自动关机&#xff0c;无需安装任何第三方软件&#xff1b; 文章目录 一、设置自动关机程序二、取消自动关机三、Windows任务…