嵌入式软件开发常见面试题整理

1,死锁的原因有哪些,怎么预防,排查

两个程序A,B ,都在争取资源,而相互等待,如果A申请了一个锁,没有释放,而B一直在等着,等不到,这种不要死锁
1个线程忘记释放,一个线程等待该锁,这个也勉强能算;
更广泛的是指,相互等待的情况,比如1:资源的访问和退出的顺序不对,如:AB两个线程,12两个锁,A占着1锁,等待2锁,而B占着2锁,等待着1锁;倒置了僵局,若无外力条件,线程无法推进;等待资源的顺序不对,如:A B两个线程,A线程等待B线程的信号,而B线程等待A线程的信号,导致了相互等待,主要这两种常见会导致死锁;
解决办法:
1,严格控制线程访问资源,申请释放锁的顺序
2,加上超时机制,占有锁多久久要退出,等待锁多久就要退出
3,死锁检测机制,将每个线程和对于占有的锁记录下来,可以是表,如果AB线程,A占着6锁,B线程要获取4锁的时候就遍历下4锁有没有被占用,检测到要发生死锁就可以执行对应的操作

优先级可以做什么用
参考https://blog.csdn.net/qq_38295166/article/details/79861460?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171245784016800184140095%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=171245784016800184140095&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-79861460-null-null.142v100pc_search_result_base3&utm_term=%E6%AD%BB%E9%94%81%E7%9A%84%E5%8E%9F%E5%9B%A0%E5%8F%8A%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95&spm=1018.2226.3001.4187

1.1,平时常用的锁有哪些,为什么一定要用锁,不用锁会怎么样

感觉我平时也不怎么用锁,如何知道代码因为没加锁导致了不可预计的结果;正常运行可能没有问题,但是如果出问题了,非常难以排查,出于减少以后出错,建议增加,而且这种写法写一次,可以用很久,所以接触新项目时,建议把项目里,创建线程,任务间通信,锁,信号量以及一些数据结构(如环形缓冲)单独记录下

2,线程间通信方式有哪些,每种的区别及适合场景,进程间通信方式有哪些,每种的区别和适合场景;进程与线程的区别,子进场与父进程的区别,子进程共享了父进程哪些资源
进程间通信:socket 管道,消息队列,信号量,共享内存
线程间同步方式:锁,信号量,事件,邮箱(rtthread)

3,freerots与rthread有哪些区别

4,嵌入式软件的内存管理方式
如何计算需要多大的堆栈空间

5,i2c 协议的时序说明,i2c常见的问题怎么解决,如死锁

6,spi协议说明

7,中断发生响应和恢复的过程细节描述

8,缓存一致性问题,什么是一致性,怎么保证一致性

cache一致性问题,在一代会出现,保存到代码的值,另一个任务去读,也读到,应该是保存的任务要特意执行刷入cache
cpu cache ram ,ram和cpu之间有一个cache,目的是为了提高访问速度
DMA访问是直接地址访问,直接访问ram,所以可能会造成cache的数据并不是ram中最新数据,所以DMA操作的时候需要注意一致性问题
参考https://blog.csdn.net/lu_embedded/article/details/78416041?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171246103416800215032606%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171246103416800215032606&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-2-78416041-null-null.142v100pc_search_result_base3&utm_term=mcu%E7%BC%93%E5%AD%98%E4%B8%80%E8%87%B4%E6%80%A7%E9%97%AE%E9%A2%98&spm=1018.2226.3001.4187

9,mcu的启动流程

bootroom根据按键决定从那边启动(spi,uart,emmc),bootroom做一些基本硬件初始化的工作,加载bootloader,以为bootloader比较大,所以分解了一个bootspl,先启动bootspl,再加载bootloader,bootloader后再运行应用程序

10,static,const,voiltage,typedef register,extern,eum关键字的作用说明
typedef 用法参考https://www.php.cn/faq/455779.html
const 指向常量
常量指针和指针常量

11,指针函数和函数指针的区别,写一个函数指针的用法,回调是什么作用

   指针函数是指,这个函数的返回值是个指针,适用于返回地址如 malloc
   函数指针是指,某个指针用来存放函数,1,适用于回调,将函数的地址传递给某个函数,等该函数达到某个条件时,执行回调,如唤醒识别算法;2,适用于动态调用,根据地址来动态选择某个函数
   写法:int* test(int x,int y)//指针函数;int (*test)() or int (*test)(int x,int y)  函数指针数组用来存放多种函数的指针,适合于动态选择函数执行  int (*test)(intx,int y)[x];  可以使用typedef int (*test)(int x,int y)  后直接 test a[x]

12,熟练常见驱动的调试 ,uart,spi,i2c

13,嵌入式发展的职业规划,第一个阶段,第二阶段,第三阶段
技能:mcu开发 linux 应用层,linux bsp层 驱动层
14,描述一个你做过的项目,你是负责哪一部分的工作,具体做了哪些工作,产品的框架是什么样的,你遇到过哪些有挑战性或者比较棘手的问题,怎么解决的

15,常见的debug分类,对应的解决思路
a,代码逻辑性或者书写错误性的问题,如,内存泄漏,指针错误等等
b,未知模块的错误问题,使用二分法,封装思想,交叉验证法,定位到问题的位置

16,代码编写的重要规则:
a,函数封装化思想
b,线程间通信到底是选择用锁还是消息还是锁信号量问题
c,内存管理,环形内存池(mcu用的还挺多)等,(可以再丰富)
d,回调的使用,怎么会想到,什么场景下使用回调
e,多使用枚举,宏定义
17,指针,二级指针,内存泄漏,段错误,怎么预防,发现了怎么排查解决 void指针

18, 常见数据结构面试题
19,uart驱动怎么设计的
怎么接收数据,怎么通知用户,怎么使用DMA,
数据是一个一个接收,还是一包一包接收
,看一些代码不应该是看着现有的代码流,能看懂,而是因为想为什么设计这些函数,从产品的功能性角度思考,如果uart,需要做什么,普通的数据收发,怎么知道数据来,怎么把数据通知给用户,数据来的快,而用户读的慢怎么办;DMA用来做什么,流程是什么样,怎么通知用户
20,进程重启的原因有哪些

21,日志系统怎么设计

22,内存溢出,内存泄露了,怎么排查,以及怎么避免


23,mcu负载率
负载率是指任务占用cpu的时间,比如100s内A任务占用2s那就是百分之2

24,uart驱动有哪些接口,框架是什么样
``

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值