第三阶段总结报告
完成的独立工作
前期学习内容
- 阅读《200行讲透Rust Future》(原文)
- 阅读《Embassy Book》(原文)
- 阅读《通过迭代 WebServer 逐步深入 Rust 异步编程》(原文)
项目实践内容
- 首先由代码demo在debug单步执行中了解整个embassy的基础执行流程,关于executor和future部分有了自己的理解,于是产生了一个改进的思路,尤其是对于原来embassy的interrupt executor实现机制的改进思路
- 由之前十分熟悉的UCOSII实时操作系统出发,进行功能裁剪和修改,适配到embassy的底层做一个线程运行时,让我们能够同时使用多个embassy thread executor,并且支持他们之间的优先级抢占,解决了原来interrupt executor方式支持的优先级抢占的两个问题:
- 优先级会占用中断,使得可用的外设中断减少,并且不灵活
项目的实现做到了不使用额外中断,只需要pendsv和systick中断来维护线程的切换以及时间片优先级的调度 - 高优先级任务如果没有await的操作,也就是没有内部future会poll返回pending的话,其它低优先级任务不会得到执行,它会独占MCU/CPU,除非它被设计为timer wait一段时间来定时交出控制权
这里我们的项目实现是通过stride算法(略有修改),实现优先级抢占的线程调度算法,一个executor会独自占用一个线程,从而赋予了其优先级以及实现了executor之间的抢占,而且通过stride算法的调度策略,避免了高优先级executor独占MCU/CPU
- 优先级会占用中断,使得可用的外设中断减少,并且不灵活
- 调试工作的实施:学习到了rcore里面的makefile的思路,gdb配合openocd调试,通过读反汇编代码以及查看内存情况,解决了代码过程中的一些比如栈溢出,莫名进入hardfault,时钟频率不对等的bug
一些体会与收获
感觉前期的学习思考是最关键的时期,两周的时间都是花在看文章,跑跑demo程序,然后理解,思考,没有前面对于rust异步机制的理解,后面阅读embassy的代码肯定是无从下手的。中期的embassy部分,我觉得真的很需要一个真实的板子来跑它的示例程序,这样一步步调试着学习,能很快的明白整个流程,如果只是单纯看着代码做的话,很难把握整体的流程,而且调试过程中可以对embassy里面代码做修改,来查看你猜想的结果,这样对于细节处理的地方也能搞清楚,因为对于我这种情况(从训练营才开始接触rust语言)来说,单纯只读代码不运行,不调试,挑战性会很大,这是我自己学习embassy过程中的一点体会吧。
还有对于后期项目开发的方式,我也有一些收获。首先是合作的开发方式选择,最开始和我的队友的确打算分branch分模块开发,但是,对于这部分硬件相关部分(并不是开发一个后端或者前端项目),而且还是在项目起草初期,我们很难把模块分得很细,而且中途更改会很多很频繁,所以我们选择现在很成熟的实时协作方式,在vscode上利用live share插件。到了开发中后期的项目debug以及调试模块的部分,的确可以分branch分模块开发,我们的流程基本是这样。然后是在嵌入式单片机调试方面的一些收获和经验吧,我在调试过程既用到了图形化调试,也用了gdb+dashboard的方式,我觉得这两个方式都很重要,很需要。在单片机上开了gdbserver过后,gdb命令行调试的反汇编查看效果,以及单汇编指令执行过程的效果看起来更好,能够在一些关键的bug查看上很方便(比如查看栈溢出的情况,看看是否溢出到把一些全局变量的内存单元改变了,还比如查看一些hardfault的进入原因,在我们用的cortex-m系列里面,它会把描述信息压入任务栈(也就是psp堆栈),和riscv里面是放入在特定的寄存器里面,主要是查看进入异常的pc以及lr还有当时处理器的状态(xpsr),这样来debug),而图形化的调试更简单,能快速的查看一些其它小的bug,并且可视化查看代码也更方便,所以我的推荐是两个都使用。最后想谈谈我在移植UCOSII线程模块到embassy的项目的思考吧,其实观察到embassy这边的任务是一个统一的栈空间,而纯的线程支持的话就会是让每个线程独占一个栈,这样会导致栈的划分肯定是有内碎片的,所以统一的栈空间能让这些任务对于栈的利用率更好,一个任务的开销就变得更小,我们跑出来的测试效果也显示出在混合线程的情况下,任务的切换情况以及开销是优于纯的线程,只是和纯协程的情况几乎相同(在线程的切换systick较高10ms这种情况下),后续也想看看如果把线程和协程的混合更彻底,是否能真正做到无缝的task切换(目前实现方式的“缝隙”是源自于线程切换走后时间片的10ms会让另一边被切走的executor阻塞较长时间)
总结我的整个训练营的体会
开始
我刚好是在4.7号训练营开营的时候报的名,在刚开始做这个训练营的任务的时候,我就觉得这些lab的设计真的很好,使用官方的rustlings这种资料以及rcore实验和详细的参考书。我因此变得很有兴趣并且毫不犹豫的分享给我身边的同学和室友,让他们也来参加。事实上我能有机会在这里发言,离不开在训练营当中和室友之间相互学习,讨论分享,这些让我学到了更多,做出了更好的成果,这也是我训练营里面额外的收获。
中间
在前两个阶段的实验是对于操作系统的实践学习部分,很好的弥补了我在课内学习操作系统所缺乏的实践不足,这里我想引用LINUX之父说的一句话来说明这部分对于我学习操作系统的重要性: Talk is cheap. Show me the code。在这个过程里面,我慢慢的习惯上了命令行调试,自己也开始写脚本来做自动化的流程,从前不那么熟悉的makefile、shell脚本还有gdb都习惯起来了。不过不管怎么说,debug的过程还是有些煎熬的,遇到隐蔽的bug,还得看看内存或者看看寄存器。但是做实验的时候真的是干劲十足,那几天里面,每天就是起床,然后写lab,每过一个实验就去看看排行榜上排名提高了多少,正好就在5.1劳动节快结束的那几天把lab实验部分做完了,后面我就重新去看了rcore-tutorial book并且把它上面的思考题给做了,真的觉得这本书写得很不错的,是我入门操作系统看的第一本书,给我的印象很好。
结束
然后就是参加项目6的过程了,最开始选择这个项目就是看到了embassy,查到它是一个嵌入式的异步框架,自己感兴趣的是在嵌入式方面,而异步这个内容对我是一个新鲜未知的东西,于是我就更有兴趣来从项目中学习新的内容,也有一点信心能做出点什么。但是完成这个项目学习后,我发现我的收获不止于这些内容,因为作为大二的学生,其实我就逐渐开始迷茫于自己到底要做什么了,特别是当我做了一些经典的lab比如:csapp、cs144以及rcore,并且也学了编译原理、数据库、计网、操作系统还有一堆的数学基础之后,我不知道自己能做出什么东西。我只知道自己对计算机的体系结构感兴趣,还想做与嵌入式相关的内容,但是该从什么地方切入,怎么才算作是做研究,我一点头绪也没有。而在参加项目6这6周的时间里面,它更重要的是给我打开了一个小的缺口,让我知道在操作系统这个广阔的领域里面可以接纳许多不同的诉求,许多学到的内容以及想要应用的场景都可以和操作系统相关联,或者说操作系统和许多地方都能联系起来。在我和我的队友这一个多月的项目所做的成果中,我们在研究异步操作系统的同时,也给我们之前在学校里面所涉及的四轴飞行器的项目优化有了思路,对于如何做研究,怎么做也有了认识,在我自己的目标里面,我是希望能做一些虽然长期且有挑战,但是很有意义的事情。而这次的经历,就让我知道在我本科接下来的时间里面可以在什么领域做工作,并且这些工作是极具挑战且很有意义的。
感谢
最后我想感谢和我一起工作的队友:施诺晖同学,我和他是室友,做这个项目和他交流学习中收获很多,后续开发过程中和他的合作让我能够高效的完成工作。
还有很感谢向老师很耐心的指导而且老师也没push得很紧张,让我能在学校考试和训练营项目的交替中成功的都分得了合适的时间片完成任务。