![Linux嵌入式系统开发从小白到大牛](https://wfqqreader-1252317822.image.myqcloud.com/cover/667/41398667/b_41398667.jpg)
4.4 【案例实战】微处理器的两种编程方式
案例实战演示微处理的裸机编程和移植Linux系统编程。源代码可以通过扫描封底二维码获取。
对于嵌入式微处理器,根据项目的复杂程度以及任务数量,可以分为带操作系统编程和裸机编程。其中裸机编程主要通过操作微处理器的寄存器达到项目需求的效果,比较典型的就是传统的单片机编程方式;带有操作系统的微处理器编程方式比较简单,工程师只需要关注代码如何实现的逻辑功能,其中微处理的寄存器被封装成库函数,提供给工程师调用。在任务调度方面,工程师只需要将任务的调度逻辑实现就可以。下面通过两个具体的案例帮助大家理解。
4.4.1 微处理器裸机系统的GPIO操作
微处理器的裸机编程其实就是单片机编程。现在使用比较多的是STM32系列单片机,这个系列的单片机就属于裸机编程(带有操作系统的除外)。STM32系列单片机在国内比较流行是因为它的配套环境,首先是多种IDE支持STM32系列单片机,其次就是STM32官方提供标准库函数和HAL库,大大简化了STM32开发复杂度。这一章采用i.MX6ull微处理器用裸机方式实现GPIO操作,大家会发现,没有库函数、没有集成开发环境、没有操作系统以后,裸机开发的工作量非常大。
在4.3.2小节中,介绍了ARM处理器的7种工作模式。对于这款i.MX6ull微处理器来说,它的内核是ARM Cortex-A7,因此裸机编程的默认工作模式是SVC。第一步需要设置这个微处理器的SVC工作模式,具体操作如下。
Step 1 新建一个设置SVC模式的汇编文件,i.MX6ull没有提供官方的启动文件,因此需要自己动手写,如图4-8所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/95_01.jpg?sign=1738885747-W6kfLrGGh18utHOKtBYwVvWMQsui2r1u-0-c522630ed151d354ad375073bb9739f4)
图4-8 设置处理器的SVC模式
Step 2 配置微处理器的寄存器并使能时钟,如图4-9所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/95_02.jpg?sign=1738885747-38IrvMlQR1FcDVnByl1ASJVw8kaUjwHv-0-4ccb863879e727cb665e093c127d209c)
图4-9 配置寄存器操作
Step 3 编写操作GPIO的主函数,控制LED灯灭500ms然后亮500ms,周而复始,如图4-10所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/95_03.jpg?sign=1738885747-aQvUQUm53sSBp5HouAvcqo0nkACunceh-0-afe67899e9d83b12556d21ad7011243a)
图4-10 主函数
Step 4 配置文件和主函数写好后,编写Makefile文件,如图4-11所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/96_01.jpg?sign=1738885747-0CI93uo4cerj64jVH8NSIKlRswmV0JS1-0-85fe4415b82bddd45868a7b652efe2fd)
图4-11 Makefile文件
Step 5 执行make指令,如图4-12所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/96_02.jpg?sign=1738885747-doe8Dbgbivjz7jnKKEnxGtLFHZW7folR-0-b6c52b1987a6ea2e5a75ea0196f1e171)
图4-12 执行make指令
Step 6 插入SD卡,然后选择连接到虚拟机,如图4-13所示。
Step 7 SD卡连接到虚拟机以后就能够将生成的led.bin文件直接复制到SD卡中,如图4-14所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/96_03.jpg?sign=1738885747-jP0WK1ILaMBNMH6E7xqxZd9tsN3yb6sl-0-9439e7b4167897b5bee7263895588783)
图4-13 SD卡连接虚拟机
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/96_04.jpg?sign=1738885747-2P48kthw5KWh7SzM7OlInrSAaerPdB7V-0-9299b53921ad1d05019ca076e93bdf03)
图4-14 将ledc.bin文件拷贝到SD卡中
Step 8 将SD卡插上板卡,上电效果如图4-15和图4-16所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/97_01.jpg?sign=1738885747-TcwJi6rxkbGQSkhC64YxGD4MMDHOyXMY-0-31fa5cc058807726ff13a83552e10951)
图4-15 红色LED灯灭500ms
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/97_02.jpg?sign=1738885747-WsbOwd2rN0Xcqzy6aH03le5p9M95qiTn-0-fdb5d04afcbd87fe9e6f80b63f69156b)
图4-16 红色LED灯亮500ms
4.4.2 微处理器移植Linux系统的GPIO操作
读者如果没有单片机的编程经验,对于4.4.1小节的裸机编程会感到非常复杂,因为微处理器的裸机编程,首先要求工程师要对芯片技术参数非常清楚,最低要掌握常用的寄存器。但是如果在移植好的Linux系统里编程就显得比较轻松了,这里选择第1章介绍过的树莓派开源硬件。本章案例就是采用树莓派来操作其自身的GPIO,为了给读者展示效果,专门在GPIO上接了一个LED灯,通过灯的亮灭更能体现效果。
Step 1使用树莓派通过C语言的方式操作GPIO,需要下载安装树莓派的C语言的支持库wiringPi库。然后使用命令gpio readall来查看树莓派的型号和GPIO的分布,如图4-17所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/97_03.jpg?sign=1738885747-3SLOjfPwg3digOmovcKu0ljAFud85Xz2-0-35dda59d3b01fecd4fc7a8b0ef126684)
图4-17 安装wiringPi库并查看GPIO
Step 2 在安装完wiringPi库并查看GPIO口以后,选择GPIO. 27引脚,然后在树莓派的目录里新建一个led.c文件,新建命令为touch led.c,接着使用vim led.c打开并编写下述程序代码。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/98_01.jpg?sign=1738885747-7PuZ2vpCgw9gRmSlqTSCU7xJcFWlJWiD-0-e0758dbbb5a3f213309f052db6535ecc)
Step 3 使用交叉编译工具(后面章节会介绍)编译led.c文件,编译的时候一定要关联wiringPi库,否则编译器会报错。这里使用的命令是:gcc-o led-lwiringPi led.c。最后使用目标文件./led使其执行,如图4-18所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/98_02.jpg?sign=1738885747-zYwSnqIrR1pBtZWa55w9aYvaMAnRHA8I-0-d2019f367291a6be1005b9df20e6b911)
图4-18 LED灯的状态信息
Step 4 可以看到LED灯会以一秒的时间间隔周期闪烁,并闪烁10次,效果如图4-19和图4-20所示。
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/99_01.jpg?sign=1738885747-Iy6Z3aqJAXsbSgFsi66tFIKS8729UjFs-0-43969a16142f9237bce6010d7410b701)
图4-19 LED灯灭
![](https://epubservercos.yuewen.com/DEDA9F/21570843408785506/epubprivate/OEBPS/Images/99_02.jpg?sign=1738885747-U7W7YIQY24yUfwTCcjWlWYqnlADVXfdg-0-4c98d99b83145fa6f048884dea9cd50a)
图4-20 LED灯亮
通过对比两个案例实战的GPIO操作,很明显在系统上编程更有效率。对于系统上的编程,只需要配置相应的支持库,不需要关心微处理器的底层寄存器。但是裸机编程不单单要写主函数,还需要对底层的寄存器进行配置,工作量比较大。