0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式编程中使用qemu可以做什么?

嵌入式IoT 来源:嵌入式IoT 作者:嵌入式IoT 2021-06-01 08:56 次阅读

1.前言嵌入式开发的过程中,很多时间都是要和硬件设备打交道,通过程序控制硬件的具体行为,这些往往是单片机延续下来的开发模式,在目前复杂的嵌入式系统中,很多都需要借助设计模式来进行开发,比如文件系统,网络,图形,算法等等,这些如果能够利用软件模拟器进行开发,可以大大的减少上板调试的时间。减少硬件连接的烦恼,在家也能随时分析软件代码。

在实际项目的开发过程中,qemu也非常的有用,例如当进行网络编程时,往往都会直接使用socket编程,其上层接口符合POSIX接口,这样上层应用的开发和底层驱动便可以很简单的分离出来,将工作细节进行合理的划分。而当进行嵌入式GUI编程设计时,也可以通过framebuffer,来进行各种界面的设计。同时,如果想新学习一款嵌入式编程语言,或者深入理解一些处理器的架构方面的知识,通过裸机编程,直接到qemu上运行也能够非常方便的进行探究工作。

下面举出一些qemu实际好用的应用来进行详细的描述。

2.嵌入式的裸机或RTOS编程

qemu的是指令翻译进行的,所以可以根据实际的需求进行相应的裸机开发和学习,比如语言学习,嵌入式C语言,嵌入式RUST语言,等等项目。一些github上的好用学习型的项目也会对qemu进行支持,用RUST语言在arm上的编程,即使手上没有很好的硬件的条件,也能够去学习RUST语言在嵌入式编程上的使用。

针对arm的编程,qemu也可以模拟出许多的架构出来,通过对这些架构的学习和掌握,可以加快对架构编程的理解。

。/qemu-system-arm -M virt -cpu

Available CPUs:

arm1026

arm1136

arm1136-r2

arm1176

arm11mpcore

arm926

arm946

cortex-a15

cortex-a7

cortex-a8

cortex-a9

cortex-m0

cortex-m3

cortex-m33

cortex-m4

cortex-m55

cortex-m7

cortex-r5

cortex-r5f

max

pxa250

pxa255

pxa260

pxa261

pxa262

pxa270-a0

pxa270-a1

pxa270

pxa270-b0

pxa270-b1

pxa270-c0

pxa270-c5

sa1100

sa1110

ti925t

然而嵌入式开发往往会和硬件打交道,qemu也提供了不同类别的硬件,比如flash,网卡,sd卡,中断,串口等等,这些对于学习不同的体系架构,也有着非常关键的作用。

比如学习cortex-m3或者aarch64编程,采用qemu,运行自己写的裸机代码,能够非常方便的进行各种实验。

在进行rtos的开发过程中,经常会采用qemu作为调试工具,进行龙芯、树莓派riscv相关的开发和验证工作。在rtos中,比较关键的是上下文的切换,通过对寄存器信息的保存和恢复,另外就是中断的处理,能够很好的理解架构的底层编程方式。

以前的时候,也做过aarch64上的qemu编程,也是最开始基于qemu,然后慢慢的移植到树莓派上面,因为外设一致,代码层面不用改变,直接可以将qemu运行通过的固件放到树莓派的sd卡中也一样能够正常的运行。

bbad3648-c236-11eb-9e57-12bb97331649.png

上图是在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 -M nuclei_n,download=ilm -cpu nuclei-nx600fdp -nodefaults -nographic -serial stdio -kernel CMSIS/nmsis_release/NMSIS/DSP/Examples/RISCV/riscv_matrix_example/dsp_example.elf

这样可以进行相关的dsp的验证工作。因为nmsis是基于arm的cmsis在riscv上的一份移植,其中实现了许多的加速运算的demo,比如矩阵运算,卷积,图像处理等等,这些指令同样也可以在nuclei qemu中计算出正确的结果。

bbcda84c-c236-11eb-9e57-12bb97331649.png

由于对riscv的p扩展和v扩展的支持,使得其行为和实际硬件板子无差异。在qemu做算法优化和研究也是非常值得去尝试的。虽然qemu是用软件去模拟真实计算结果,但是从指令集的优化层面上来说,当功能逻辑实现正确后再移植到板子上做性能测试,这才是高效的处理方法。

在支持baremetal编程和rtos编程方面,nuclei-sdk也做了一些工作,可以更加好的观察分析软件的具体行为。

qemu-system-riscv32 -M nuclei_n,download=ilm -cpu nuclei-n201 -nodefaults -nographic -serial stdio -kernel application/rtthread/msh/msh.elf

Nuclei SDK Build Time: May 31 2021, 1118

Download Mode: ILM

CPU Frequency 168290222 Hz

| /

- RT - Thread Operating System

/ | 3.1.3 build May 31 2021

2006 - 2019 Copyright by rt-thread team

Hello RT-Thread!

msh 》

msh 》ps

thread pri status sp stack size max used left tick error

-------- --- ------- ---------- ---------- ------ ---------- ---

tshell 6 ready 0x000000d8 0x00001000 10% 0x0000000a 000

tidle 7 ready 0x00000078 0x00000200 23% 0x00000020 000

main 2 suspend 0x000000b8 0x00000400 17% 0x00000013 000

msh 》

也可以支持其他的rtos,例如下面的ucosii和freertos等等。

ucosii的运行效果如下:

qemu-system-riscv32 -M nuclei_n,download=ilm -cpu nuclei-n201 -nodefaults -nographic -serial stdio -kernel application/ucosii/demo/demo.elf

Nuclei SDK Build Time: May 31 2021, 1145

Download Mode: ILM

CPU Frequency 182521692 Hz

Start ucosii.。。

create start task success

start all task.。。

task3 is running.。。 1

task2 is running.。。 1

task1 is running.。。 1

task3 is running.。。 2

task2 is running.。。 2

task3 is running.。。 3

task2 is running.。。 3

task1 is running.。。 2

task3 is running.。。 4

task2 is running.。。 4

task3 is running.。。 5

task2 is running.。。 5

freertos的运行效果如下:

qemu-system-riscv32 -M nuclei_n,download=ilm -cpu nuclei-n201 -nodefaults -nographic -serial stdio -kernel application/freertos/demo/demo.elf

Nuclei SDK Build Time: May 31 2021, 1145

Download Mode: ILM

CPU Frequency 232205516 Hz

Before StartScheduler

Enter to task_1

task1 is running 0.。。。。

Enter to task_2

task2 is running 0.。。。。

timers Callback 0

timers Callback 1

task1 is running 1.。。。。

task2 is running 1.。。。。

timers Callback 2

timers Callback 3

task1 is running 2.。。。。

task2 is running 2.。。。。

利用qemu作为底层研究将会非常的高效。同时,善于借助gdb等调试工具,将能够非常容易的找到问题出现的点。

3.利用qemu网络编程

研究由于qemu的网络可以直接连接主机的网络,对这方面的研究可以从网络协议栈,网络的上层应用编程等等进行研究。例如去研究lwip协议栈的实现等等。

我写过一个qemu上的e1000网卡设备的驱动,针对于qemu riscv64的virt版本。

https://github.com/bigmagic123/rt-thread/tree/riscv_virt_network

针对rt-thread的qemu riscv的virt64版本,可以进行如下的设置。

bbd98f04-c236-11eb-9e57-12bb97331649.png

其中其底层的驱动为e1000,为qemu提供了网络数据的收发、以及网络数据包的接收中断服务。

借助rt-thread上适配的lwip驱动程序,可以非常容易的实现上层网络编程应用。

比如借助rt-thread的IOT软件包

bbf29c38-c236-11eb-9e57-12bb97331649.png

使能一些例子

bc0c13ac-c236-11eb-9e57-12bb97331649.png

最后可以测试一下web的通信情况。

bc293504-c236-11eb-9e57-12bb97331649.png

当然,上述这个例子只是一个非常简单网络编程的演示,其中socket的编程部分实际上是通用的,无论是arm架构、mips架构或者riscv架构,借助qemu的好处在于可以采用一个架构平台,进行协议栈或者上层开发后,可以无缝的移植到自己的真实的板子上,非常方便进行整体业务的联调。

对于qemu riscv64 virt平台,整个系统从底层的virtio或者e1000的网卡设备提供数据的收发、中断消息机制之外,rt-thread也通过提供lwip协议栈的支持,这样整个网络链路才是比较合理的。开发起来也比较的方便。

物联网模块的开发方面,采用qemu,也可以不用rt-thread,直接裸机驱动virt上的e1000网卡驱动,然后借助对寄存器的读写操作,移植其他的网络协议栈,从而实现网络数据的收发工作,网络编程的上层对接阿里云、腾讯云等云服务器,非常容易的实现业务的编程,同时调试方面,qemu的gdb调试功能也是非常的强大,也可以dump出内存进行ram parse分析。

4.嵌入式图形开发

因为嵌入式编程的实现,也会多少涉及到图形编程,当接上LCD屏后,其中的显示驱动对上层应用暴露出来的实际上是一块显存,通过对显存的读写,flush进行lcd的图像更新。

在图像编程方面,qemu也提供了显示窗口。这种显示窗口可以为gui相关的开发工作带来很多便捷。

关于嵌入式图像编程,可以参考

rt-threadsp

aspberry-pi

aspi3-64

相关的bsp,只需要完善显示程序即可。

可以寻找一张bmp的图片,图片大小为800x480的图片。

利用Image2Lcd的工具进行图像转换成数组。

最后将数组程序编译到程序代码中,将该数组放到显存中即可。

bd3ef924-c236-11eb-9e57-12bb97331649.png

一切准备就绪后,就能够进行显示器的开发了。

#define LCD_BUF_SIZE (800 * 480)

extern unsigned char gImage_1[];

void lcd_test()

{

struct rt_device *lcd;

struct rt_device_graphic_info *test_lcd_info;

test_lcd_info = rt_malloc(sizeof( struct rt_device_graphic_info));

//找到lcd lcd = (struct rt_device *)rt_device_find(“lcd”);

rt_kprintf(“lcd get info:

”);

rt_device_control(lcd, RTGRAPHIC_CTRL_GET_INFO, test_lcd_info);

rt_kprintf(“lcd width is %d

”, test_lcd_info-》width);

rt_kprintf(“lcd height is %d

”, test_lcd_info-》height);

rt_kprintf(“lcd bpp is %d

”, test_lcd_info-》bits_per_pixel);

rt_memcpy(test_lcd_info-》framebuffer, &gImage_1[0], LCD_BUF_SIZE*4);

//刷新图片

rt_device_control(lcd, RTGRAPHIC_CTRL_RECT_UPDATE, NULL);

rt_thread_delay(20);

}

如果要进行触摸操作,qemu也进行了基本的支持,只需移植相关的底层驱动即可进行开发工作,非常的高效和方便。

5.进行嵌入式Linux的开发

进行Linux开发工作,如果深入去学习某一个设备的开发,当然少不了不断的对Linux的内核部分进行编译和下载,这是一个十分耗时的工作,如果只是进行应用程序的开发,可能感觉不到许多的差别,但是一旦涉及到Linux内核的分析,频繁的下载也会浪费大量的时间。

当使用qemu后,这种问题将会得到很好的解决,采用qemu进行内核层面的裁剪,进行内核层面模块化的验证工作后,再进行移植,让其变得更加通用,不仅仅针对这个项目有效,而且也为自己积累了很多经验。

bd5be6a6-c236-11eb-9e57-12bb97331649.png

从分析linux的loader,分析Linux的驱动框架,内存管理,多核管理等等,都能够非常方便进行调试工作。

在实际硬件设备没有稳定之前,对软件项目进行评估,qemu是非常好用的工具。

6.小结

接触很多软件开发工作中,使用qemu确实能够在一定程度上节省时间,提高软件调试与分析的效率。

用软件模拟硬件的操作行为,本质上来说和实际的硬件操作区别不大,因为在嵌入式编程中,最底层的指令集的行为已经在qemu中实现的很好了,硬件模拟方面,qemu也大致能够模拟操作寄存器后,处理器的行为,这些在对qemu的底层支持和学习的过程中已经进行了大量的实验和研究。

理解qemu的使用,会对嵌入式软件原理有着更加深刻的理解,从更大的层面上来说,虚拟化的行为本来就是一种很好的解决方案,去设计一个嵌入式软件方案,去演示一个底层软件,或者节约下载调试时间,开发嵌入式上层业务系统软件的功能层面来说,qemu都是值得去研究和使用的工具。

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 显示器
    +关注

    关注

    21

    文章

    4944

    浏览量

    139816
  • 驱动
    +关注

    关注

    12

    文章

    1825

    浏览量

    85177
  • 编程
    +关注

    关注

    88

    文章

    3591

    浏览量

    93592
  • LCD屏
    +关注

    关注

    0

    文章

    122

    浏览量

    15397

原文标题:嵌入式编程中使用qemu能够做什么?

文章出处:【微信号:Embeded_IoT,微信公众号:嵌入式IoT】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    有什么比较热门的嵌入式项目?

    大佬们想问一下可以做什么样的嵌入式项目好找工作?工作1到2年左右
    发表于 11-08 09:57

    嵌入式学习建议

    ,最好能有自己动手的空间。不花一分硬件钱想要学好嵌入式系统不实际,因为这是实践性很强的学科。好书,可以让人少走弯路,不被误导。好老师也可以是做过一些实际项目的学长(一定要找做过几个成功项目的学长或老师做
    发表于 10-22 11:41

    嵌入式主板是什么意思?嵌入式主板全面解析

    嵌入式主板,通常被称为嵌入式系统的核心组件,是一种用于控制和数据处理的计算机硬件,其设计旨在嵌入特定设备中执行专门任务。嵌入式主板如同是设备的“大脑”,主要功能是根据需要管理和控制设备
    的头像 发表于 09-30 10:05 364次阅读

    嵌入式C编程常用的异常错误处理

    记录到非易失性存储器或通过串口输出。 总结 嵌入式C编程中的异常错误处理方法多种多样,选择合适的方法取决于具体的应用场景和系统要求。通过合理的错误处理机制,可以提高系统的稳定性和可靠性。
    发表于 08-06 14:32

    如何提升嵌入式编程能力?

    如何提升嵌入式编程能力? 要提升嵌入式编程的能力,可以从以下几点学习: 1. 理解硬件:熟悉你正在编程
    发表于 06-21 10:01

    USB嵌入式主机堆栈

    在USB标准下,USB设备之间不能直接通信。它们只能与控制一个或多个设备通信的总线的 USB 主机通信。常见的 USB 主机是 PC。本应用笔记讨论了 USB 嵌入式主机,它可以使嵌入式应用程序在各种 USB 设备
    发表于 05-03 09:13 172次阅读
    USB<b class='flag-5'>嵌入式</b>主机堆栈

    嵌入式主板,你了解多少?

    嵌入式主板,也称为嵌入式计算机主板,是一种专门设计用于嵌入式系统的计算机主板。与台式机和笔记本电脑中使用的常规主板不同,嵌入式主板设计用于集
    的头像 发表于 04-17 15:11 1413次阅读

    如何成为一名嵌入式C语言高手?

    的特性和工作原理对于嵌入式C语言编程至关重要。你应该学习如何与外设进行交互、如何配置寄存器和控制器等。阅读相关设备的数据手册和技术文档,参加硬件相关的课程,可以帮助你更好地理解嵌入式
    发表于 04-07 16:03

    嵌入式编程片上系统是什么

    嵌入式编程片上系统(Embedded Programmable System-on-Chip,或简称EPSoC)是一种特殊的嵌入式系统,它结合了嵌入式系统的特点和可
    的头像 发表于 03-28 15:33 531次阅读

    如何成为一名嵌入式C语言高手?

    的特性和工作原理对于嵌入式C语言编程至关重要。你应该学习如何与外设进行交互、如何配置寄存器和控制器等。阅读相关设备的数据手册和技术文档,参加硬件相关的课程,可以帮助你更好地理解嵌入式
    发表于 03-25 14:12

    fpga是嵌入式

    FPGA(现场可编程门阵列)不是嵌入式系统,但FPGA在嵌入式系统中有着重要的应用。
    的头像 发表于 03-14 17:19 2141次阅读

    fpga与嵌入式的区别 嵌入式和fpga开发有什么关系

    fpga与嵌入式的区别 FPGA与嵌入式系统在设计和应用上存在一些关键的区别,具体如下: 灵活性:FPGA具有高度的灵活性,可以根据需要重新编程以实现不同的功能。而
    的头像 发表于 03-14 17:04 6764次阅读

    嵌入式软件开发应该掌握哪些知识?

    掌握的知识 1.基础知识 1.1 c/c++编程语言和数据结构 C/C++ 是嵌入式系统中常用的编程语言,因为它们提供了直接访问硬件的能力。通过使用特定的编译器和调用硬件相关的接口,可以
    发表于 02-19 11:23

    嵌入式学习步骤

    嵌入式行业是一个涉及广泛领域的行业,嵌入式、物联网、人工智能、智能与科学、电子信息工程、通信工程、自动化工程、测控、计算机科学等专业在嵌入式系统中使得软件和硬件的结合更加高效,适合从事
    发表于 02-02 15:24

    什么是嵌入式系统?嵌入式系统的具体应用

    嵌入式,一般是指嵌入式系统。用于控制、监视或者辅助操作机器和设备的装置。
    的头像 发表于 12-20 13:33 2403次阅读