This commit is contained in:
2024-08-10 19:46:55 +08:00
commit 2233526534
798 changed files with 35282 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
# 嵌入式是什么?可以吃吗?
> Author肖扬
## 概念引入与讲解
刚开始接触嵌入式的人,往往会有这样的疑惑:嵌入式到底是什么?
这不是因为那些人没有完全入门嵌入式,而是因为在嵌入式的学习过程中你会发现,它的概念会越来越大,逐渐模糊了你的认知,就拿一张某乎上的照片而言:
![](https://cdn.xyxsw.site/boxcny07MPlh99IIS5yxAdL4iDb.png)
可见嵌入式的概念之广。
而我也常常遇到学弟学妹们去向我提问:什么是嵌入式?
我觉得以我通俗的话来讲就是:在硬件设备上写软件代码。虽然这种说法并不是完全准确,但是对于初学者而言暂时性的保持这样的认知,在探索嵌入式的过程中不断完善自己的学习体系,已是极好。
不如举一个大学里玩嵌入式的常见概念吧:机器人。
这玩意儿大家估计不陌生,比如你去酒店里,也许会有一个可以坐电梯上下楼层来完成特定任务的机器人(说实话高二在某季酒店第一次见的时候还蛮新鲜)
![](https://cdn.xyxsw.site/boxcn99MPmacSrXPkIgQ13FLABc.jpg)
而它也是一个嵌入式产品(或者说它们)。
这是相对来说较为复杂的嵌入式系统,在我看来它需要的技能可能包括:基础人机交互(客房电话、前台终端)、基础运动控制、多机交互与编队(与其他机器人、电梯系统之间的交互)、图像处理、目标检测、目标识别、语音识别、路径规划等等。
再介绍一个我常举的例子:智能手表。
比如某米的经典智能运动手环,可以心率检测、可以登录 wx 等平台、可以完成相应的运动检测等等
在嵌入式开发者的眼里,这会是一款成功的作品(当然考虑到了它的营销方面),它用通用嵌入式操作系统 + 应用软件的高端嵌入式系统结构,在满足系统对功能、功耗等要求的前提下,能将产品价格维持在一个较低的水平上,并且在我看来其 GUI 设计非常的令人舒适。
塞一个我认为很帅的 DIY 自行车码表,其 UI 设计也相当的棒。
<Bilibili bvid='BV1GB4y1K7VV'/>
还有一个我最近关注的一个博主,我喜欢其富有想法的创造力与强大的执行力。
<Bilibili bvid='BV1YG4y177Mq'/>
## 想说的话
相信到这里,你对嵌入式或者嵌入式产品已经有了初步的认识。
说相对实在点的东西的话在大学中或者在杭州电子科技大学学了嵌入式的一些基础知识后你可以去参与一些相关的竞赛全国大学生电子设计竞赛、全国大学生智能车竞赛、全国大学生工程实践与创新能力大赛、Robot Master 机甲大师竞赛等等),也许你已经了解到杭电的环境会让你不断地接触许许多多的竞赛,在竞赛的学习过程中你可以获得一定的能力、获得一定的感悟,也许能获得到一定的荣誉,如果你足够优秀的话可以最后保研上岸,成为别人眼里的佼佼者。
**但是,笔者想说的是:**
大学不再是像从前那般循规蹈矩,你可以在大学的生活中尝试各种各样的事情,这四年时光本就是一个不断试错的过程。如果你本身对竞赛十分感兴趣,或者说想要通过竞赛让自己之后的路走的更加顺畅,那么我会祝愿你能学有所成,并且最终能获得到自己满意的成绩;
**但我更希望你是真正地对嵌入式感兴趣,热爱创造它的时光,热爱披荆斩棘后成功的欣喜,热爱它的生命,热爱它赋予你的意义...在这段学习历程中,竞赛会是你成长的一部分,但不是全部,也不能是全部。作为一个伪理想主义者(我认为完全的理想主义者不会痛苦,只有现实的理想主义者才会痛不欲生),生命中总会有更重要的东西,比如爱,无论是喜爱还是热爱,比如人,无论是亲朋还是蒹葭。**
科技的最终意义是提高生产力,但科技带来的意义也远不止于此,我希望你们在接下来学习嵌入式的过程中,能不忘本心,钦佩自己的永远独立,钦佩自己的永远自由,不被世界的功利化所迷惑,感受嵌入式那独特而又真实的生命力!
Ps可以去看看韩健夫老师写的一篇文章相信你会有更多的感悟[人文社科的重要性(韩健夫老师寄语)](/1.杭电生存指南/1.1人文社科的重要性(韩健夫老师寄语))
最后,欢迎来到嵌入式王国:)

View File

@@ -0,0 +1,157 @@
# New meaning of C
> Author肖扬
在上一篇文章中,我们介绍了嵌入式相关的产品,其中芯片充当着及其重要的作用,本篇我们将以孵化器实验室的部分考核流程与教程作为参考,并且加以一定的概念解析,逐步地为大家解开单片机裸机开发的面纱。
PS在学习此模块之前我希望你们能熟练掌握 C 语言的基础知识,特别是指针方面的内容。
如果你还没有完成 C 语言的学习,可以参考此文章:[3.4C 语言](../3.%E7%BC%96%E7%A8%8B%E6%80%9D%E7%BB%B4%E4%BD%93%E7%B3%BB%E6%9E%84%E5%BB%BA/3.4C%E8%AF%AD%E8%A8%80.md)
## STC89C52--一款入门级的芯片
### 相关介绍
Intel 的 STC89C51\C52 系列早在上世纪 80 年代就已经广泛运用,考虑到其精简但较为充足的硬件资源以及其低廉的价格,笔者十分建议可以从 51 单片机系列开始去接触整个嵌入式行业(因为你需要知道自己适不适合进入到嵌入式行业,大学本就是一个试错的过程,而低廉的价格使得其试错成本变得很低)
以下是比较推荐的学习路线:
1、购买 51 单片机:[CZ0001「普中 51 单片机学习板开发板 stc89c52 单片机实验板 C51 单片机 diy 套件」](https://m.tb.cn/h.UuGJR5G?tk=kN94dm040JX)
2、推荐学习视频[【51 单片机入门教程 -2020 版 程序全程纯手打 从零开始入门】](https://b23.tv/KmaWgUK)
3、相关学习资料
软件安装包、开发板资料、课件及程序源码百度网盘链接:
[https://pan.baidu.com/s/1vDTN2o8ffvczzNQGfyjHng](https://pan.baidu.com/s/1vDTN2o8ffvczzNQGfyjHng) 提取码gdzf链接里压缩包的解压密码51如果打不开请复制链接到浏览器再打开
## 寄存器VERRY--IMPORTANT!!!
相信学完 C51 的内容,你已经对寄存器有了一定的了解。
但是由于其重要性,以及为了巩固各位的基础知识,防止出现有些人学了 A 只会 A学了 B 只会 B而不会 CDEF...的现象,所以这里我必须要着重重新讲解一下寄存器的概念。
在 C 语言中我们有 int、short、long 等变量,实际上 C 语言中还可以定义一个寄存器变量register
那么为什么需要寄存器呢,或者说我们为什么需要一个寄存器变量呢。
这里我不从计算机组成原理或者微机接口与技术的概念入手,而是举一个简单的例子:
如果我们在图书馆上准备看书,去获取知识,此时我们是 CPU、书则是数据。
如果我们去图书馆里的书架上拿书并观看,则需要:走到对应书架 - 拿书(获取数据)- 回到书桌,这需要花费相当一部分的时间,此时硬盘相当于书架;如果我们直接拿书桌上的书,则相对速度会快很多,此时书桌相当于主存;如果我们手上就有一本书,那么我们低头就可以看到,手就相当于寄存器。所以,寄存器是 CPU 内部用来存放数据的一些小型的存储区域,用来暂时存放参与运算的数据和运算结果以及一些 CPU 运行所需要的信息。
以我举例而言,**可见寄存器获得数据的速度会快于主存与硬盘,而存储数据的大小将会小于主存与硬盘**,如果这块不清楚的话也可以去看 也许你会用上的基础知识 中的存储器知识部分。
而从汇编语言的角度来讲(此为 Intel 的汇编语法):
```asm
WAIT_FOR_TIMER:
MOV A, LED_COUNT ;读取当前亮灯的编号
CJNE A, #00H, NOT_FIRST_LED ;如果不是第一个灯则跳转到NOT_FIRST_LED标签
MOV A, #03H ;如果是第一个灯则将延时设为3秒
SJMP DELAY ;跳转到延时
NOT_FIRST_LED:
.......
DELAY:
.......
;此汇编代码块中累加器A作为一个常用的特殊寄存器充当着暂时存储数据信息的作用
;存储LED_COUNT的编号并用于比较大小存储所需延时时间并用于DELAY块
```
```asm
ORG 0BH
PUSH ACC ; 保存寄存器状态
PUSH PSW
......
POP PSW ; 恢复寄存器状态
POP ACC
RETI ; 返回中断
;此汇编代码块用于基本的中断处理我们需要保存ACC、PSW的状态来维持中断以及中断后程序的正常进行
```
以上简单例举了寄存器的一般作用,以汇编语言出发去讲的原因是:它能有效地展现底层代码的工作原理,既不会像机器语言那样只用 0、1 表示的晦涩难懂,又不会像高级语言那般难以直观地看到底层的工作方式。但是,我们做嵌入式入门开发的过程中并不会让你直接去写汇编语言,而是以最基础的 C 语言相比汇编而言C 在功能上、结构性、可读性、可维护性上有明显的优势),通过 Keil、IAR 等拥有交叉编译器的 C 语言软件开发系统来完成高级语言、汇编语言、机器语言的转码工作,从而通过 C 语言的编写来控制单片机等嵌入式系统的开发。
而抽象层面的 C 代码需要通过访问寄存器来直接控制硬件。所以在嵌入式开发的过程中C 有了特殊的含义:**C 里的数字代表的可能只是一个地址或者一个数据,但是在嵌入式开发里,这样一个数字也可以代表着一种寄存器状态。**
下面引入一个 STM32F1 系列的 GPIO 部分寄存器图(来源正点原子提供的 F1 参考手册):
![](https://cdn.xyxsw.site/MyDMbeCKLowC1Mx7Q6Ec9BLPn4g.png)
![](https://cdn.xyxsw.site/LJ1SbFfv6oUIgtx8CstcbWTNnRg.png)
如果我们想做一个简单的实验 - 驱动一个 LED 灯(假设此 LED 灯以 PB5 为输出驱动口),在对相应的 RCC 时钟等配置之外,最重要的是对相应的 GPIO 口的配置,首先我们查阅其寄存器的物理起始地址:
![](https://cdn.xyxsw.site/CZ3cbiEhsoWDgJxhwXIcpUkAnMg.png)
![](https://cdn.xyxsw.site/HTFUbsQCNouQVzx0QYiciQWOnZf.png)
可见 GPIO 外设通过 APB2 总线进行地址定位与传输数据的,所以我们要控制 PB5 的话首先需要定位到对应的地址:
```c
#define PERIPH_BASE ((uint32_t)0x40000000) //外设基址
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) //APB2 基址
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define AFIO_BASE (APB2PERIPH_BASE + 0x0000)
#define EXTI_BASE (APB2PERIPH_BASE + 0x0400)
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)//GPIOB 基址,计算可得 0x40010C00
#define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
#define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
#define GPIOF_BASE (APB2PERIPH_BASE + 0x1C00)
#define GPIOG_BASE (APB2PERIPH_BASE + 0x2000)
//APB2 还有相关定时器的基址,这里就不再展示
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE)
```
根据如上提供的 CRL、ODR 寄存器的功能映射,要使得 PB5 推挽输出且初始电平输出为高,则需要:
```c
void LED_Init(void)
{
RCC->APB2ENR|=1<<3; //GPIOB 的时钟使能,只有使能对应的时钟后 GPIO 才能正常工作
GPIOB->CRL&=0XFF0FFFFF; //由图可知CRL 的第 20-23 位控制 5 口,此举是对第 20-23 位清零
GPIOB->CRL|=0X00300000; //此举是对第 20-23 位赋值 0011根据寄存器功能可知此代表 50Mhz 推挽输出
GPIOB->ODR|=1<<5; //设置 ODR 第 5 位为 1输出高电平
}
```
其中 GPIOB 的结构体如下所示:
```c
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
```
所以由以上提到的例子而言C 语言可以从如下三方面进行与寄存器之间的控制:
1. 寄存器的地址可以使用**指针变量**来访问。
2. C 语言中的**结构体可以用于表示寄存器映射**。
3. C 语言中的**位域可以用于表示寄存器中的位**。
而且 C 语言中的内联汇编可以用于直接访问寄存器。在某些情况下,如果我们需要直接访问寄存器来完成复杂的硬件控制操作,则可以使用汇编语言指令来直接访问寄存器,从而实现复杂的硬件控制操作。常见的如,堆栈大小的设置等。
```asm
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
```

View File

@@ -0,0 +1,172 @@
# 还玩裸机?上操作系统!
> Author肖扬
在 [New meaning of C](./5.2New%20meaning%20of%20C.md) 栏目中,我们已经从 stc51 单片机系列和 stm32 单片机系列进行了一定的裸机开发讲解,并且延伸到了通过相关的 datasheet 对刚接触到手的芯片进行开发(毕竟你总不能成为 stm32 开发工程师或者 cubemx 工程师对吧<del>【然鹅大多数急于求成的开发者往往忽视了这方面的能力,也许是为了更快入手竞赛】</del>
而在此栏目中,我们将讲述相关操作系统在嵌入式上的应用,让你的嵌入式产品更加的智慧!(当然裸机并不一定就比带操作系统的嵌入式产品差,只是应用方向不同或者说有时候需要考虑产品的成本问题)
Ps本栏目只例举几个目前开发工程中常见的操作系统的学习与开发**具体的移植过程可 web 或者自行探索 - 相信我,出色的移植能力是嵌入式开发者必不可少的。**
## RTOS
MCU 本身就能做到一定的实时性,那为什么还是需要 RTOS实时操作系统**其实评判实时系统的关键并不是系统对外部事件的处理速度,而是处理事件的时间的可预见性和确定性。**举个例子Windows 操作系统在 CPU 没有其他任务时可以在很短的时间内对外部事件作出一定的响应,但是当某些后台任务在运行时,有时候响应速度会变得很慢甚至出现假死现象,这并不是因为 Windows 速度不够快或者效率不够高导致的,而是因为 Windows 对事件的响应不能提供准确性,所以其不能算作一个实时操作系统。**并且在笔者看来,实时操作系统除了可以达到完成每次任务所需时间的一致性外,其相应的操作系统产品(例如我们本栏目将重点介绍的 FreeRTOS这里可以简单提一下为啥要选 FreeRTOS显而易见因为-Free还具有可以简化整体架构、开发等工作的作用。**
RTOS 中最重要的概念则是“任务”。
我们可以回想一下在 MCU 开发过程中,一般都是在 main 函数里做个 while1来完成大部分的处理将一些相对来说对实时性要求高的函数如 PID 控制器扔到定时器中断当中即应用程序是个无限的循环是个单任务系统前后台系统while1作为后台中断服务函数作为前台。这里采用了“正点原子”的一张图
![](https://cdn.xyxsw.site/boxcnFySF1Cd02I052V0a9glH1c.png)
而 RTOS 则是一个多任务系统,那么它这么做有什么好处呢?
2>1 嘛(乐),实际上在前后台系统中,你的每项 Task 要轮流排队等着上次 Task 执行结束后再进行自己的程序,大大影响了其系统的实时性要求;而 RTOS 中我们把整个 while1区分成了很多小任务并且在表面上看起来这些任务运行起来像是同时进行实际上是因为任务所需的时间较少导致它看起来像是并行但这将会带来新的疑问到底什么任务先执行呢RTOS 就为此提供了任务的相关 API 接口,赋予任务相应的执行优先级属性,并通过任务调度器来控制任务的执行顺序。这里同样采用了“正点原子”的一张图:
![](https://cdn.xyxsw.site/boxcntQgR61yRboDpyb1bpI10Xp.png)
所以,**其实可以这么说RTOS 将整个流程变成了很多个 while1【每个任务都是个 while1】。**
并且根据我上述所描述的内容,一个任务需要的属性大致如下(以启动函数为例进行介绍):
```c
#define START_TASK_PRIO 1 //任务优先级
#define START_STK_SIZE 256 //任务堆栈大小
TaskHandle_t StartTask_Handler; //任务句柄
void start_task(void *pvParameters); //任务函数
int main{
systemInit()//硬件初始化
xTaskCreate(
TaskFunction_t start_task, //任务函数
const char * const "start_task", //任务名称
const uint16_t START_STK_SIZE, //任务堆栈大小
void * const NULL, //传递给任务函数的参数
UBaseType_t START_TASK_PRIO, //任务优先级
TaskHandle_t * const StartTask_Handler //任务句柄
)
}
```
至于有关于任务的运行态、挂起态、就绪态、阻塞态等我便不在此栏目进行讲解,希望读者能根据以上的引入去学习 FreeRTOS 的开发,可供参考的文档或者学习视频如下:
1、b 站正点原子官方 FreeRTOS 教学(在今年有做全面的更新,比之前讲的更为清晰,难得的优秀入门视频)
<Bilibili bvid='BV19g411p7UT'/>
2、FreeRTOS 官网(官网往往是最适合学习的地方)[www.freertos.org](http://www.freertos.org)
## Linux以 ROS 为例)
首先,如果你不了解 Linux 系统的话,我建议你去 [附加模块Linux](../3.%E7%BC%96%E7%A8%8B%E6%80%9D%E7%BB%B4%E4%BD%93%E7%B3%BB%E6%9E%84%E5%BB%BA/3.Y%20%E9%99%84%E5%8A%A0%E6%A8%A1%E5%9D%97%EF%BC%9ALinux.md) 中进行一定的学习。
如果你不了解 Python我建议你去以及 [3.6Python(灵巧的胶水)](../3.%E7%BC%96%E7%A8%8B%E6%80%9D%E7%BB%B4%E4%BD%93%E7%B3%BB%E6%9E%84%E5%BB%BA/3.6Python%EF%BC%88%E7%81%B5%E5%B7%A7%E7%9A%84%E8%83%B6%E6%B0%B4%EF%BC%89.md)中进行学习。
如果你已经对以上所涉及到的方面有了一定的了解,那么欢迎来到机器人开发者的殿堂-Robot Operating System
由于硬件技术的飞速发展,针对于机器人软件设计的框架也面临着极大的挑战,而 ROS 的出现无异是所有机器人开发者的福音,因为如果按照以前的制作一个机器人流程来讲,也许你要经历以下步骤:硬件结构搭建、控制处理、相关算法构建等等,但是 ROS 的开源共享模式令其可以在其平台上巧妙利用别人的开源模型完成自己的机器人搭建,**也就是说 Ros 的出现打破了原本各个开发者(或团队)闭门造车的开发现象,使得其可以共享优秀的机器人应用软件,换句话说就是提高了机器人研发的软件复用率。(毕竟哪个团队都不可能同时在建图、导航、视觉等机器人应用方面处于顶尖位置)**
![](https://cdn.xyxsw.site/boxcnRy7E27xggqNshXX3cu4J5Q.png)
由于 ROS 中完成度最高的是 Ubuntu所以我们建议你以此展开学习当然你也可以选择 macOS、Debian 等 OS。
但是 Linux 只是一个通用系统,并没有在机器人开发上提供相应的中间件,所以 ROS 提供了基于 TCP/UDP 的通信接口(机器人的工作当然需要通讯),在再此之上提供了相应的基础开发库供给至应用层。
此时应用层则有个很重要的概念-Master管理者其负责管理整个系统的正常运行。如果我们需要获得比较成熟的相关领域开源机器人包按以往的操作必将是进行一次比较复杂的移植你需要考虑各种因素比如硬件支持、与其他移植包是否冲突等等。**但是在 ROS 系统中引入了功能包的概念,你可以在 ROS 社区中下载相关版本(与你的 ROS 版本相匹配的机器人应用功能包完成一次非常简单的移植过程CV你不需要关注其内部的具体运行机制只需关注接口的定义与使用规则便可进行相应的二次开发在 ROS 中你需要关注的是相关节点之间的关系,可以通过 rqt_graph 获取清晰的节点图),相当于给你做好了一个跟机器人开发有关的高集成度****SDK****平台。**(当然如果你感兴趣的话可以做一定的了解,但这将牵扯到相关内容的庞大体系,比如如果你想了解自主导航是如何运行的,你首先需要了解 SLAM 算法的运行机制以及激光雷达或者相关深度摄像机的运用,然后你需要了解什么是深度信息什么是里程计信息,为什么可以表示机器人的位置信息,要如何进行一些相关的位置信息修正,然后 bulabula。**以笔者自身的学习经历而言,学习相关的理论基础体系,将对你的二次开发有极大的帮助,而不会造成盲目使用接口的情况**
根据以上我讲述的相关内容可知:**ROS 系统的优点在于,你能将社区里的有关机器人的开发模块集大成于一身,并且通过 ROS 与控制板通讯(此时类似于 STM32 的裸机主控便变成了控制板 - 用于接收 ROS 的调控完成相应电机、舵机的控制,或者完成一定的例如 oled 显示的简单任务),从而完成 ROS 系统内部开源算法对整个机器人的控制。**
以下我简单介绍一下 ROS 的基础通讯方式:
在裸机开发中我们的通讯不论是蓝牙、WiFi 还是最基础的串口通讯)本质上都来自于串口中断,也就是说裸机开发引入了 ISR 来处理相应的数据接收。ROS 通讯中同样需要这样的函数来完成对目标数据的处理,而在 ROS 中我们称之为回调函数。
我们以话题通讯机制来做简要介绍,在此通讯中需要有两个节点,一个 Publisher发布者以及一个 Listener订阅者他们将发布和订阅同一个来完成相应的通讯 - 将发布和订阅的内容交给 ROS Master整体流程类似于 WiFi 中的 mqtt 协议通信,将发布和订阅的内容交给公共服务器,形成一个转接的效果)。
所以通过这样的一个流程,具体的代码如下(以 C++ 为例):
```cpp
//Publisher
int main(int argc, char **argv)
{
//首先我们要初始化节点
ros::init(argc, argv, "talker");
//其次,为了对这个类更好地进行处理,我们需要创建节点句柄
ros::NodeHandle n;
//创建一个 Publisher=> pub发布名为 chat 的 topic消息类型为 std_msgs::String
ros::Publisher pub = n.advertise<std_msgs::String>("chat", 1000);
//设置循环的频率,对应着 sleep 延时
ros::Rate loop_rate(10);
while (ros::ok())
{
// 初始化 std_msgs::String 类型的消息
std_msgs::String msg;
/*
对数据的处理
*/
// 发布消息
ROS_INFO("%s", msg.data.c_str());
pub.publish(msg);
// 循环等待回调函数
ros::spinOnce();
// 按照循环频率延时
loop_rate.sleep();
}
return 0;
}
```
```cpp
//Listener
int main(int argc, char **argv)
{
//节点与节点句柄是必不可缺的
ros::init(argc, argv, "listener");
ros::NodeHandle n;
// 创建一个 Subscriber订阅名为 chatter 的 topic注册回调函数 chatCallback
ros::Subscriber sub = n.subscribe("chat", 1000, chatCallback);
// 循环等待回调函数
ros::spin();
return 0;
}
```
而其中,在 Listener 中出现了回调函数,其功能类似于裸机中的中断控制 - 当接收到对应的订阅消息后,进行对应的数据、逻辑处理,例如如果我只是想把接收到的数据打印出来的话,我可以这么写回调函数 chatCallback
```cpp
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("I heard: [%s]", msg->data.c_str());
}
```
至于 ROS 其他的内容便不在这里阐述ROS 是机器人开发者的福音,此模块是希望有更多地人能注意到这样的良心开源平台,并督促各位进行相关的知识学习,可供参考的文档或者学习视频如下:
1、b 站古月居 ROS21 讲(讲的比较浅,但是可以作为入门学习视频,了解整个框架,感兴趣地可以看胡老师的 ROS2 系列视频,毕竟 ROS1 近期已经停更了,要保持不断学习的姿态)
<Bilibili bvid='BV1zt411G7Vn'/>
**提一嘴:很多人学 ROS 就学一个开头 - 比如就学了古月居的 21 讲,就认为自己已经了解到了 ROS 的大部分内容了****(不会有人现在还是纯看视频学习吧)****,实际上这是非常错误的想法。当你学完了视频的内容后,你甚至可能不会移植 wiki 上的功能包x_x甚至不知道如何去开发一个真实的机器人因为此 21 讲只是理论上的讲解,去做一个虚拟机器人在 gazebo 上运行。ROS 的学习上需要我们花大量的心思去学会接触新的东西,你们并不能只局限于我提供的推荐学习资料,因为相应的功能包不是一成不变的,而且也不是只有那么几个功能包,当你感受了 ROS 的自主建图、自主导航、机械臂控制、机器学习开发等等等等等等后,你才会发现 ROS 的世界是如此美妙!**
2、b 站赵虚左 ROS 课程(讲得细致多了,需要耐心看下去,要是我入门 ROS 的时候有这个视频就好了)
<Bilibili bvid='BV1Ci4y1L7ZZ'/>
3、古月居的《ROS 机器人开发实践》根据国外的《ROS By Example》改编但是更贴近于入门开发会有相关功能包更细致的解析
4、[http://wiki.ros.org/cn](http://wiki.ros.org/cn)(不会用 ROSwiki 的 ROS 玩家不是好 ROS 玩家)
如果未来有能力的话,希望我们能反哺 ROS 社区,促进开源社区的发展。
## 其他常见嵌入式操作系统(入门仅作了解)
相对于通用计算机操作系统而言,嵌入式操作系统除有任务调度、同步机制、内存管理、中断处理、文件处理等基本功能外更有其强大的实时性、强稳定性、硬件适应性等等。与通用计算机不同,嵌入式操作系统行业是一个百家争鸣的环境,没有一款产品能够占据绝对统治地位,但是也有很多应用面较广、有突出特色的嵌入式操作系统享有较高的知名度。
1、微软的嵌入式 Windows 操作系统(从个人计算机到嵌入式系统的更变)
此嵌入式操作系统的初衷就是“使当今的个人计算机复杂的软件环境扩展到嵌入式世界”,也就是说希望能在嵌入式产品上用到 windows 系统的桌面软件。主流上 EOS 分为两个Windows Embedded CompactWEC系列和 Windows EmbeddedWE系列。常见用于手持设备、机顶盒、数码娱乐设备等等。
2、VxWorks集多种处理器大成的操作系统
VxWorks 是硬实时操作系统,比 FreeRTOS 这类软实时操作系统有更强的实时性,更加专注于人的交互性、可靠性,用于军事、航空、控制等领域。并且 VxWorks 支持 PowerPC、CPU32、x86 等多种嵌入式处理器体系,所以有较好的可裁剪性、兼容性。

View File

@@ -0,0 +1,21 @@
# 5.富有生命的嵌入式
> Author肖扬
孵化器实验室 2023 招新群 (QQ): 879805955
预热 OJ 平台:[OJ 平台 (C 语言为主)](http://hdufhq.cn/)
> 实验室不仅有嵌入式方向,还有硬件、网络 web 开发方向!
在本模块,我们将为你讲述何为嵌入式、如何学嵌入式、如何爱上嵌入式
同时我们希望你知道,大学本就不止枯燥的学业
它会是一两醉人的花酒,亦可能会是一张泛黄的纸,一场绝美的梦
> “点星星之火,燃燎原之势,热血芳华,理想当燃”
![](https://cdn.xyxsw.site/boxcn3t2GyLQqe4RpGdRtakcwBc.png)
ps若对此部分讲义有相关疑问或者建议欢迎 QQ 联系 -1213047454

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB