星星充电 嵌入式软件开发 一面 面经

1. 自我介绍,说说你的项目经历和技术方向。

答:

  • 按"背景 → 技术栈 → 代表项目 → 求职意向"四段走,控制在2分钟
  • 星星充电是充电桩方向,如果有IoT、通信协议、嵌入式Linux相关经验要重点提
  • 结尾说一句为什么对充电桩/新能源方向感兴趣,体现你做过功课

2. 你的项目有没有实际落地,落地过程中遇到了哪些和开发阶段不一样的问题?

答:

  • 考察项目真实性和工程化思维,不是考你功能实现了多少
  • 落地和开发的典型差异:实验室环境和真实环境的差异(电磁干扰、温度、电源质量)、用户使用方式和预期不一致、硬件批次差异导致的兼容性问题
  • 如果项目没有落地,要说清楚做到了哪个阶段,测试验证了哪些场景,不要说"功能都实现了"但说不出测试细节

3. UART、RS232、RS485三者有什么区别,实际调试串口通信时遇到过哪些问题?

答:

  • UART是通信协议(逻辑层),RS232和RS485是电气标准(物理层)
  • RS232:单端信号,±3V到±15V,点对点,传输距离约15米,抗干扰弱,适合短距离设备间通信
  • RS485:差分信号,±1.5V到±6V,支持多点总线(最多32个节点),传输距离可达1200米,抗干扰强,工业场景主流
  • 实际调试常见问题: 波特率不匹配导致乱码,用逻辑分析仪抓波形确认实际波特率RS485总线两端没有加120Ω终端电阻,长距离传输时信号反射导致误码半双工RS485收发切换时序问题,发送完成后没有及时切换到接收模式,丢失对方的响应地线没有共地,导致共模电压超出接收器范围,通信不稳定

4. I2C通信中,主机如何检测从机是否存在,ACK和NACK分别在什么情况下产生?

答:

  • 检测从机是否存在:主机发送从机地址后等待ACK,收到ACK说明从机存在并响应,收到NACK或超时说明从机不存在或未就绪
  • ACK(应答)产生条件:从机正确接收到地址或数据字节后,在第9个时钟周期拉低SDA线
  • NACK(非应答)产生条件: 从机地址不匹配,没有设备响应从机忙碌,无法接收新数据主机读操作的最后一个字节,主机发NACK告知从机不再需要数据从机接收到无法处理的命令
  • 实际调试:用逻辑分析仪抓I2C波形,看第9个时钟周期SDA是否被拉低,是排查I2C问题最直接的方法

5. FreeRTOS中任务优先级怎么设置,设置不合理会导致什么问题?

答:

  • 优先级设置原则:实时性要求高的任务优先级高,后台任务优先级低;优先级数量不要太多,3-5级通常够用
  • 充电桩场景的优先级参考:安全监控任务(过压/过流检测)最高,通信任务(OCPP协议处理)次之,计费和日志任务最低
  • 设置不合理的问题: 优先级反转:低优先级任务持有互斥锁,高优先级任务等待,中优先级任务抢占低优先级任务运行,高优先级任务被间接阻塞,用优先级继承的互斥量解决低优先级任务饥饿:高优先级任务一直运行,低优先级任务永远得不到CPU,日志无法写入、状态无法上报优先级设置过于集中:大量任务同一优先级,时间片轮转,实时性无法保证

6. volatile关键字的作用是什么,在嵌入式中哪些场景必须用volatile?

答:

  • volatile告诉编译器:这个变量可能在编译器不知道的情况下被修改,每次访问必须从内存读取,不能缓存在寄存器里,不能对其访问做重排优化
  • 嵌入式必须用volatile的场景: 内存映射的硬件寄存器:volatile uint32_t* const GPIOA_ODR = (uint32_t*)0x40020014,不加volatile编译器可能把多次读取优化成只读一次ISR和主程序共享的标志变量:volatile bool data_ready = false,不加volatile主程序可能把标志变量优化到寄存器里,看不到ISR的修改DMA传输的缓冲区:DMA直接写内存,CPU不知道内存被修改了,需要volatile防止编译器用缓存值
  • volatile不能保证线程安全,不能替代互斥锁,多线程共享数据要用原子操作或加锁

7. 什么是看门狗,独立看门狗和窗口看门狗有什么区别,喂狗时机怎么选择?

答:

  • 看门狗是硬件定时器,系统正常运行时软件定期喂狗(重置计数器),超时没喂狗则触发复位,用于从死锁、死循环、程序跑飞中自动恢复
  • 独立看门狗(IWDG):由独立的低速时钟(LSI)驱动,即使主时钟故障也能工作,只要在超时前喂狗即可,适合检测系统整体是否卡死
  • 窗口看门狗(WWDG):有上下窗口限制,只能在特定时间窗口内喂狗,太早或太晚都会触发复位,能检测程序时序是否正常,适合对时序有严格要求的场景
  • 喂狗时机:在主循环的固定位置喂狗,确保只有程序正常运行完一个完整周期才喂狗;多任务系统中,用任务心跳机制,所有关键任务都正常运行才喂狗,任何一个任务卡死都不喂狗

8. 程序中的内存分区有哪些,BSS段和data段有什么区别?

答:

  • 嵌入式程序的内存分区: text段(代码段):存放程序指令,只读,在Flash中rodata段:只读数据,如字符串常量、const变量,在Flash中data段:已初始化的全局变量和静态变量,初始值存在Flash,运行时复制到RAMBSS段:未初始化或初始化为0的全局变量和静态变量,不占Flash空间,启动时由启动代码清零heap(堆):动态分配的内存,malloc/free管理,向高地址增长stack(栈):局部变量和函数调用信息,向低地址增长
  • BSS和data的核心区别:data段的初始值需要存在Flash里(占Flash空间),启动时从Flash复制到RAM;BSS段不存初始值(不占Flash空间),启动时直接清零,节省Flash
  • 嵌入式启动代码(startup.s)负责:把data段从Flash复制到RAM,把BSS段清零,然后跳转到main

9. 什么是大端和小端,如何判断当前系统的字节序,网络通信中为什么要处理字节序?

答:

  • 大端(Big Endian):高字节存在低地址,如0x12345678存储为12 34 56 78,符合人类阅读习惯,网络协议使用大端
  • 小端(Little Endian):低字节存在低地址,如0x12345678存储为78 56 34 12,x86和ARM(默认)都是小端
  • 判断方法:
int x = 1;
if (*(char*)&x == 1) // 低地址存的是低字节,小端
else // 大端

  • 网络通信处理字节序的原因:TCP/IP规定网络字节序为大端,嵌入式设备通常是小端,发送前用htonl/htons转换为网络字节序,接收后用ntohl/ntohs转换为主机字节序,否则对方收到的数据解析错误
  • 充电桩的OCPP协议基于JSON,字符串传输不涉及字节序;但如果用私有二进制协议,字节序处理是必须考虑的

10. 什么是内存对齐,结构体对齐规则是什么,#pragma pack有什么用?

答:

  • 内存对齐:变量的存储地址

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

嵌入式面试八股文全集 文章被收录于专栏

这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务