1.前言
2.嵌入式的裸机或RTOS编程
3.利用qemu网络编程研究
4.嵌入式图形开发
5.进行嵌入式Linux的开发
6.小结
1.前言嵌入式开发的过程中,很多时间都是要和硬件设备打交道,通过程序控制硬件的具体行为,这些往往是单片机延续下来的开发模式,在目前复杂的嵌入式系统中,很多都需要借助设计模式来进行开发,比如文件系统,网络,图形,算法等等,这些如果能够利用软件模拟器进行开发,可以大大的减少上板调试的时间。减少硬件连接的烦恼,在家也能随时分析软件代码。
在实际项目的开发过程中,qemu也非常的有用,例如当进行网络编程时,往往都会直接使用socket编程,其上层接口符合POSIX接口,这样上层应用的开发和底层驱动便可以很简单的分离出来,将工作细节进行合理的划分。而当进行嵌入式GUI编程设计时,也可以通过framebuffer,来进行各种界面的设计。同时,如果想新学习一款嵌入式编程语言,或者深入理解一些处理器的架构方面的知识,通过裸机编程,直接到qemu上运行也能够非常方便的进行探究工作。
下面举出一些qemu实际好用的应用来进行详细的描述。
2.嵌入式的裸机或RTOS编程qemu的是指令翻译进行的,所以可以根据实际的需求进行相应的裸机开发和学习,比如语言学习,嵌入式C语言,嵌入式RUST语言,等等项目。一些github上的好用学习型的项目也会对qemu进行支持,用RUST语言在arm上的编程,即使手上没有很好的硬件的条件,也能够去学习RUST语言在嵌入式编程上的使用。
针对arm的编程,qemu也可以模拟出许多的架构出来,通过对这些架构的学习和掌握,可以加快对架构编程的理解。
./qemu-system-arm-Mvirt-cpu?AvailableCPUs:armarmarm-r2armarm11mpcorearmarmcortex-a15cortex-a7cortex-a8cortex-a9cortex-m0cortex-m3cortex-m33cortex-m4cortex-m55cortex-m7cortex-r5cortex-r5fmaxpxapxapxapxapxapxa-a0pxa-a1pxapxa-b0pxa-b1pxa-c0pxa-c5sasatit
然而嵌入式开发往往会和硬件打交道,qemu也提供了不同类别的硬件,比如flash,网卡,sd卡,中断,串口等等,这些对于学习不同的体系架构,也有着非常关键的作用。
比如学习cortex-m3或者aarch64编程,采用qemu,运行自己写的裸机代码,能够非常方便的进行各种实验。
在进行rtos的开发过程中,经常会采用qemu作为调试工具,进行龙芯、树莓派、riscv相关的开发和验证工作。在rtos中,比较关键的是上下文的切换,通过对寄存器信息的保存和恢复,另外就是中断的处理,能够很好的理解架构的底层编程方式。
以前的时候,也做过aarch64上的qemu编程,也是最开始基于qemu,然后慢慢的移植到树莓派上面,因为外设一致,代码层面不用改变,直接可以将qemu运行通过的固件放到树莓派的sd卡中也一样能够正常的运行。
上图是在qemu的rt-thread/bsp/raspberry-pi/raspi3-64中编译的固件在qemu上的运行效果,基本上完成对aarch64体系架构中的栈帧、中断、mmu的支持,以及外设部分SD卡、图形、串口、mbox的支持。该固件也可以直接放到树莓派硬件的sd卡中运行,其效果和在qemu效果一样。
除此之外,我也在qemu的支持上做了一些扩展开发,比如在riscv的生态支持上对gd32的rv-star在中科院软件研究所的基础上做了一些研究,同时对nuclei的各种处理器系列做了适配。这样对于软件层面的验证更加有用,比如去运行一下nuclei-sdk,或者对于RISCV的V扩展的支持的nmsis的支持。
qemu-system-riscv64-Mnuclei_n,download=ilm-cpunuclei-nxfdp-nodefaults-nographic-serialstdio-kernelCMSIS/nmsis_release/NMSIS/DSP/Examples/RISCV/riscv_matrix_example/dsp_example.elf
这样可以进行相关的dsp的验证工作。因为nmsis是基于arm的cmsis在riscv上的一份移植,其中实现了许多的加速运算的demo,比如矩阵运算,卷积,图像处理等等,这些指令同样也可以在nucleiqemu中计算出正确的结果。
由于对riscv的p扩展和v扩展的支持,使得其行为和实际硬件板子无差异。在qemu做算法优化和研究也是非常值得去尝试的。虽然qemu是用软件去模拟真实计算结果,但是从指令集的优化层面上来说,当功能逻辑实现正确后再移植到板子上做性能测试,这才是高效的处理方法。
在支持baremetal编程和rtos编程方面,nuclei-sdk也做了一些工作,可以更加好的观察分析软件的具体行为。
qemu-system-riscv32-Mnuclei_n,download=ilm-cpunuclei-n-nodefaults-nographic-serialstdio-kernelapplication/rtthread/msh/msh.elfNucleiSDKBuildTime:May,11:48:18DownloadMode:ILMCPUFrequencyHz\
/-RT-ThreadOperatingSystem/
\3.1.3buildMay2006-9Copyrightbyrt-threadteamHelloRT-Thread!mshmshpsthreadpristatusspstacksizemaxusedlefttickerror---------------------------------------------------------tshell6ready0xd80x%0x0atidle7ready0x780x0020023%0x20main2suspend0xb80x0040017%0x13msh
也可以支持其他的rtos,例如下面的ucosii和freertos等等。
ucosii的运行效果如下:
qemu-system-riscv32-Mnuclei_n,download=ilm-cpunuclei-n-nodefaults-nographic-serialstdio-kernelapplication/ucosii/demo/demo.elfNucleiSDKBuildTime:May,11:49:45DownloadMode:ILMCPUFrequencyHzStartucosii...createstarttasksuccessstartalltask...task3isrunning...1task2isrunning...1task1isrunning...1task3isrunning...2task2isrunning...2task3isrunning...3task2isrunning...3task1isrunning...2task3isrunning...4task2isrunning...4task3isrunning...5task2isrunning...5
freertos的运行效果如下:
qemu-system-riscv32-Mnuclei_n,download=ilm-cpunuclei-n-nodefaults-nographic-serialstdio-kernelapplication/freertos/demo/demo.elfNucleiSDKBuildTime:May,11:49:45DownloadMode:ILMCPUFrequencyHzBeforeStartSchedulerEntertotask_1task1isrunning0.....Entertotask_2task2isrunning0.....timersCallback0timersCallback1task1isrunning1.....task2isrunning1.....timersCallback2timersCallback3task1isrunning2.....task2isrunning2.....
利用qemu作为底层研究将会非常的高效。同时,善于借助gdb等调试工具,将能够非常容易的找到问题出现的点。
3.利用qemu网络编程研究由于qemu的网络可以直接连接主机的网络,对这方面的研究可以从网络协议栈,网络的上层应用编程等等进行研究。例如去研究lwip协议栈的实现等等。
我写过一个qemu上的e1网卡设备的驱动,针对于qemuriscv64的virt版本。