嵌入式linux的几点小经验总结

114 阅读9分钟

[toc]

开发阶段

经验:

  • 网友评价全志:
全志,主打要啥没啥

全志资料是最差的,找也找不到,找到了还读不懂
  • 驱动代码的函数尽量只有一个return 返回值的地方,其他fail的地方都 goto 到末尾,这样在return的时候打印出返回值来,类似如下:
printk("%s %d exit:rc=%d\n", __FUNCTION__,__LINE__,rc);
  • 提交代码前打开4个空格的检测,保持代码的整洁;

  • 多次被调用的api,打印出调用者的行号:

修改前:

SensorRet_e pateo_cci_write_reg_seq(max96712a_context_t* pCtxt, uint8_t slaveAddr,CameraI2CDataType_e addrType, CameraI2CDataType_e dataType,CameraI2CReg_t * regSeq, uint32_t size);

修改后:

#define pateo_cci_write_reg_seq(a,b,c,d,e,f) pateo_cci_write_reg_seq_(__LINE__,a,b,c,d,e,f)

SensorRet_e pateo_cci_write_reg_seq_(uint32_t line , max96712a_context_t* pCtxt, uint8_t slaveAddr,CameraI2CDataType_e addrType, CameraI2CDataType_e dataType,CameraI2CReg_t * regSeq, uint32_t size);

这样调用者接口不需要改动代码,即增加年行号的入参,fail时候可以打印出来.

  • 一个好的嵌入式linux开发板,需要:1.支持apt等软件包下载和安装功能(避免做各种项目时缺lib库等,自己折腾) 2.最好国外soc比如NXP等,因为资料开放,很多公司在github有官方的维护代码分支; 3. 不要vmware虚拟机方式编译,改用wsl或者docker方式,避免初学者折腾环境很久
  • /proc 还有一个功能是查看当前进程的链接库,比如77391进程的: cat /proc/77391/maps
  • 用msleep替代mdelay,可以加速开机速度
  • sysfs,procfs 的文件名命名尽量通用,因为后续新产品可能使用不同的芯片,如果文件名用诸如 camera_max96722_detect_err,后续换掉max96722,需要通知上下游改名字,徒增工作量.

硬件设计的评审: 硬件设计需要经过驱动的评审,不要自己就拍板定下,比如S31中改的max96722的4个link的用法:

图片.png 和S73a2的max96722的4个link的用法不同,导致出现一个芯片,需要调试2次的情况:

图片.png

  • [高通]高通的cci很容易搞dump,因为不是使用系统的I2C,而是使用CCI,导致CCI power down之后,如果上层仍然读写文件系统相关节点,有可能出发CCI读写I2C操作,导致full dump

  • 上层打开底层驱动时,需要先close再open,防止已经open后上层app被kill后,重新打开上层app,初始化时底层不知道(比如摄像头的id地址已经重新分配为0x41~0x44了),再做初始化会出现报错.

  • 自己的功能一定要做下班后的自动化测试,不能指望测试部给测出问题(自动化测试可以用python来控制,比如python通过继电器控制产品的上下电或者触控等操作,比如打开关闭摄像头,然后通过 adb 读取测试完毕后的状态,比如摄像头是否有图像输出)

  • 电信类产品特点: -往往要求很高,所以常常有主备分区备份的功能,比如主备的boot flash,flash不能频繁擦写 -有采用uboot ->vboot(小linux内核,通过菜单用于选择ftp下载软件版本到本地等)->kexec启动大内核,执行真正的版本

  • 单板软复位后需要能查复位前的dmesg log,类似zte的保留分区存log的做法,这些都是基础设施,最好能做成一个标准做法,后面可以沿用

  • flash分区要提前确定,否则后面无法在线升级,只能手动升级工作量太大;在线升级需要提前搞

  • 添加 IO_CTRL 枚举值的时候要顺序定价,不要中间插,因为有可能新增的枚举值,在用户态的代码和内核态代码都有使用,如果用户态是旧代码,内核态是新代码(或者反之),会导致功能出问题。

  • uboot启动时已经把系统的寄存器配置完备了,后面linux直接使用,不需要初始化了

  • 使用fpga注意FPGA可能会有几个bank,同一bank的电压和信号电压是一致的,不同bank的电压可能不一致

  • android的有些模块可能有自己独立存日志的情况,比如qcm6125的ais_log.txt,需要升级版本后先find 和ls -al 打印出所有文件的大小,再挂机测试若干小时候,再执行一遍,看看是否有多余的文件或者文件增大了,说明就是有生成日志,需要检查日志是否会一直增加的风险.

  • gpio的开机启动模式pin脚,开机之后还可以做个其他的用处,避免gpio不够用。

  • 开发初期,睡眠默认关闭了,中后期再打开.关闭或者减少不必要的sleep/delay动作,后期测试过程中酌情增大.

  • 板子上没有的器件,dts里一定去掉,否则即使没有出现功能问题,但是性能可能有问题,比如访问不存在的寄存器导致重试等等(mpq2022去掉后,dts没有去掉)

  • 新项目很有可能使用旧的屏幕等等,所以不要急于替换屏幕等,是否有一个简单的方法来切换新旧屏幕呢

  • 虚拟文件夹中设备树节点的变化需要及时通知到上层,否则上层无法打开设备节点,造成错误,比如这里i2c的地址式bus7的0x24,如果变化了就需要通知上层。 /sys/devices/platform/57247000.i2c/i2c-7/7-0024/ic_ver

  • 使用page页来切换寄存器地址的芯片,比如TP2855,对应用层比如有查询状态的接口(比如cat /sys/bus/i2c/devices/i2c-8/8-0029/camera_status_value),则使用自己的调试脚本时,先写了40# page寄存器,再读其他地址的时候,这中间可能app已经切换了40# page地址,所以app的接口(比如cat /sys/bus/i2c/devices/i2c-8/8-0029/camera_status_value) 需要做一个备份和还原40# page寄存器的动作.

  • 开机log中打印开机需要的时间,进入桌面的时间,避免代码修改慢慢积累造成性能变差的情况

  • 大的修改一定要切分支,比如摄像头4合1改4路独立,涉及到上下游,风险很大,就要拉分支来单独修改

  • i2c等通信通道一定要提前做压力测试,检查是否能稳定可靠工作。写压力测试用例时,需要考虑一边(比如通过继电器)测试,一边检查文件系统的节点,看是否符合预期,这样不用每天搜索日志,看是否有fail。

  • 外部上下拉电阻必须和软件的配置一致,否则在测试高低压脉冲时,芯片复位后读取的外部上拉电阻,导致功能异常。

  • 产品本身及其内部模块都要有reset机制,当上层检测到状态不对的时候就需要reset。

  • 每个硬件板子准备一个金机和使用最后的版本,方便回溯问题

  • 问题要提前压力测试,不要像保隆的斯特威摄像头,到了装车时,才发现有小概率的出图问题

  • 项目开发过程中需要定期检查系统的资源消耗和进程,后台,避免随着项目的进行,消耗的系统资源越来越大。

  • 使用逻辑分析仪抓波形,要找一个gpio,在抓波形的时候拉高,退出之后拉低,从逻辑分析仪上方便找到故障点的波形。

  • 摄像头要用mmap方式取图,由bsp提供cma内存,避免使用系统内存

  • 文件系统操作后需要执行sync,才能真正保存

  • 多个控制器之间一定要有责任划分,否正出问题扯不清楚.比如FAPA的日志如何才能导出,方便澄清是FAPA的问题,还是车机的问题

  • 考虑车机设计的可维修性:尽量使用带总线,故障时能查询故障原因或者寄存器的IC

  • 芯片有几路i2c就尽量各自接不通的外设芯片,避免出故障后,几个芯片在一个i2c bus,不方便分析问题

  • 开发阶段核心版尽量使用插卡式的,方便替换和应用新的产品,类似zte的CC128S一样.

  • 代码修改如果涉及到上一个版本和本版本的不同,比如上一个版本的monitor日志是1_monitor.txt,现在改成1_monitor.csv,需要评估老版本兼容上一个版本的问题.

  • 设备树要标记原理图的网络标识,比如

SC_P_MIPI_CSI0_MCLK_OUT_LSIO_GPIO1_IO24 0x00000020?????//BJ23 pad =MAX9286_MIPI_CSI1_RST_B =pull-up??

方便定位问题

  • 删除别人的功能,需要看看别人添加功能时的修改——比如周qw修改monitor日志,增加新功能后,把写文件从>改成>>,后续我在去掉他的功能时,没有把>>改成>。

发货阶段

//市场有A,B,C版本,每次测试推送市场的新版本如D,都要从市场存量最大的A版本向上升级到D,而不仅仅测试C升级到D,因为版本跨度越大,可能隐藏问题越多

管理方法

华为:需求管理和下发,敏捷迭代 + 站会,相关技术问题在TMG上升,加班能攒调休,沟通问题通过共享桌面很方便.通过(相对低)的工资+ 较高的年终奖,当希望员工离职时,通过打C不给年终奖,迫使员工离职,避免员工长期待在公司,养成懈怠的风气. 中兴通讯:敏捷迭代 ,需求用看板管理+ 站会+周报,白嫖式加班