博主头像
小雨淅沥

Some things were meant to be.

头图

乐鑫实习回顾:2025/10/20

实习总结 2025/10/20

前言

自从 2025年7月 入职以来,算算也有3个月了,这三个月也经历了很多,想来是时候该总结做过了什么了。

岗位概述

我从事的工作是 嵌入式软件开发 岗位,公司是 乐鑫,这是一家芯片公司。我主要的工作模块就是 Bluetooth Low Energy (BLE)

主要的工作语言是 Python 和 C,这对我来说倒也没啥难度,除了一开始 Python 特性有一些遗忘了。

这个岗位另一个比较独特的地方就是需要一定的英文阅读门槛(因为操作手册是全英文的),这倒是成了我的一项优势了。虽然大学期间几乎没怎么学过英语,但是凭借着上海高考英语的老本还是有一个不错的六级成绩。

环境相关

我入职的时候是7月,公司在9月初进行了搬迁。搬迁之间在张江微电子港,工位稍微有点小,放两台电脑和显示器就不太有别的空间了。

不过在张江的环境不错,微电子港园区内绿化很好!我工作累了偶尔会走走转两圈,领导也不会管。

9月搬迁之后就到了陆家嘴·数智天地,这是公司单独买下来的一栋楼,工位宽敞得多,放两个电脑绰绰有余,加上一般工位并不是紧挨着的,几乎就是1.5个工位,完全够用。

公司八楼
公司八楼

工位,拍摄于新址(此时还可以拍照)
工位,拍摄于新址(此时还可以拍照)

唯一就是吐槽一下新椅子,没有原来的好,角度不好,午休比较难睡着,没以前舒服。

工作环境方面,同事之间交流蛮愉快的的,没有架子,我们部门主管也比较亲和,没什么压力。大家休息时候随便开开玩笑聊聊天,氛围很轻松。

也有可能是由于我是实习生的原因,我每天工作强度没有正式员工大,也就没那么累,天天到点下班。也没有 ddl 的压力。正式员工他们就比较忙碌了,这一行都这样,也是没有办法的事吧。

公司比较独有的一点就是有比较强的保密性:我们的办公室规则是不允许使用自己的手机的(实际就为了让你不要泄露公司内容,要是不一直用,戴个耳机放放歌就睁一只眼闭一只眼的)。

另外就是小部门之间的代码也是打包成 bin 加密的,跨部门相互保密的。我作为一个实习生没有公司 Gitlab 的主分支权限,只能通过 mt 单开 branch 操作,稍有麻烦吧。

工作压力方面,可能是实习生的缘故,我没什么压力,mt 也不催我 ddl,每次晚上大伙还会散步一会,稍作休息聊天吧,每天的上班时间也是弹性的,对实习生相对比较友好吧(老员工甚至从来不担心打卡不满,看来确实是有带你忙……)

熟悉业务

工作中有一点内容或许不方便透露,我会在规则内部描述一下。

进去第一件事情就是读指导书,Specification,全英文非常厚的一本,一开始我还是漫无目的的读,浪费了好多时间。

后面读了好久了发现实际并没有理解多少,开始认真对待,记笔记,重点步骤(类比 TCP 的三次握手)我会反复读,并确认没有给细节,光是这个步骤我就花了不少时间。在大致理解了以后就要熟悉代码了,去理解项目实际如何实现协议的规定。

乐鑫的这部分代码是开源的,可以稍微提提,其实所有的实现逻辑都在esp-idf GitHub 上给开源出来了。

主要就是核心代码,包括 net.c , transport.c 为主的这两个文件,详细到具体如何实现传输这个步骤

大概花了2周的样子,我把 spec 中主要的业务逻辑都理解了一下,但是实际上并没有很好地掌握,也是只一知半解。

第一个项目

在基本熟悉以后我收到了第一个任务,尝试将一个功能跑通,并对这个功能的性能进行测试。

这是一个我单人负责的一个框架,因为这个框架一直都是我在维护的,我觉得这个框架对我的开发能力倒是提升不少。

我做的工作主要在于Python 电脑端,在单片机端我就开发了一个统计的功能,这个主要就是帮助我对并发调度和嵌入式开发中数据处理有了更加深入的理解。

举个例子,在嵌入式开发中我们一般会使用这种方式来存储数据:

struct {
    int *num;
       int max;
} data_xxx;

// 在初始化的时候进行内存分配
data_xxx.num = malloc(n * sizeof(int));
data_xxx.max = n;
// 释放
free(data_xxx.num);
data_xxx.num = NULL;
data_xxx.amx = 0;

而我之前一直都在使用 C++,对于动态管理内存没不是很擅长,这里让我对堆的分配内存有了更好的理解。

同时我之前的开发都是使用GDB的方式,这让我很方便能供随时打断点进行每一个变量查看,也能够进行单步调试的方法,但是在单片机上我不能够这么做。

我一开始遇到 bug 都问 mt 该怎么办,但是每一次都羞愧地发现 mt 问我 “你试过打印一下这个变量的值吗?”这类的话。

我当时就突然发现自己不是在真正的做一个开发者,似乎成为了自己曾经最讨厌的那类——遇到问题只知道问,从来不知道思考。

后来我就学会了如何像一个程序员一样去问问题:我学会了遇到问题先尝试复现,通过 print 变量来进行 debug,最后实在不行的时候我再会提问,问的时候能给出以下内容:

  • 我在哪里遇到了问题?这个问题是如何复现的?
  • 我做了什么,我debug到哪里发现无法解决了?
  • 我对问题的理解,经过我的思考我认为问题可能出在哪里?

Debug 也帮助我更加了解整个项目,在一次次排查和深入代码调用栈的时候,潜移默化地就更加理解了整个项目的运行逻辑。

在这之后,我在 GitHub 上处理了一个 issue,我指导他如何进行问题的排查,一步步定位问题,最后发现他没有进行某个参数的初始化,我通过领悟的方法帮助他修复了这个问题,而这个方法是我在工作之后才总结学会的。

我理解到,开发遇到 bug 该怎么做——我们不是神,不能一眼看出代码 bug 在哪里,我们只能一步步地排查 bug,层层检查调用函数,定位错误位置,最后找出到底是哪个判断没有通过,到底是哪一个变量是悬挂指针……

我也处理了一些 FreeRTOS 相关的操作,在开发自己的测试用例的时候,通过信号量来实现线程之间的通信,实实在在地进行了并发编程(当然肯定是简单的低并发)

这让我对于多线程的理解更近一步,了解什么时候用锁,什么时候使用条件变量。在我的 case 中我就是使用信号量,有点类似于生产者和消费者,生产者一旦生产完毕(比如说接收到一个包)就会通知消费者去消费(应用层调用对应的应用读取并消费这个包),这中间又得需要队列来进行缓冲,还需要控制怎么不让死锁产生(你别说,我开发过程中还真出现了死锁)等等……

另一方便就是这个项目的PC端测试框架是我全权负责开发的,我在其中添加了相当多的内容,其中也包括了很多我在OOP中学习的内容。通过 framework 进行基类的编写,在某个具体的 case 中进行应用,继承相应的功能,如果变量有新增功能等就用重写。

这个脚本的开发是使用 Python的,通过这个项目经历,我对Python 熟悉程度也是有所提升,尤其是 import 逻辑,包管理等。(Python中有可能会出现循环应用的问题,在 C 语言中我们只需要声明,但是在 Python 中我们需要使用延迟导入才行)

在 Python 我巩固了两个编程设计思路:

  1. Manager:其实有点类似于工厂设计模式,通过 manager 类来进行所有设备的统一管理,而 device 的接口一般是不暴露的,这样复用可以提高代码的可维护性。
  2. 广播模式:我一个串口有很多个消费者,一个是 log 文件,一个是发送命令要监听反馈,最后还有个全程需要监听的线程(例如 assert 失败或者出现 crash 了),然而问题在于串口的 fd 锁 flock()构成独占,这么多消费者就需要就需要一个统一的监听,然后发送给所有的感兴趣的线程,这是用的是广播模式。更有就是一个线程会同时有多个正则匹配,而每一个正则匹配的结果又各不相同,那么就是用一个统一的 Dispatcher 来分配每一个正则匹配的 Callback。

还有一些就是经典的,“课堂上不会教你,但是都默认你会的技能”,其实主要就是 Git 指令,这个项目让我学会了如何正确使用 Git 进行多人协作,也让我对 Linux 系统的指令更加熟悉。

上述可以说都是开发经验,是将一个目标通过软件实现的方式,这些就是这个项目带给我的主要收获。

总结

今天就写到这里吧,剩下的内容放到下一次吧。

总结以下,我学到了这些东西,说来惭愧,这些也许是我在学校就应该掌握的:

  1. C 语言中对内存的手动管理,及时回收
  2. Debug 的底层逻辑,通过 print 中间变量,层层调用链来定位 bug,最终解决这个问题
  3. 更加了解多线程开发,使用信号量,队列等实现线程通信
  4. OOP 开发思想的进一步熟练运用
  5. Python 中如何引用包,如何延迟导入
  6. 两大开发过程中给常用的设计模式
  7. 一些基础的开发技能,包括 Git , Linux 命令等
乐鑫实习回顾:2025/10/20
https://www.rainerseventeen.cn/index.php/Minds/21.html
本文作者 Rainer
发布时间 2025-10-20
许可协议 CC BY-NC-SA 4.0

评论已关闭