嵌入式Linux学习笔记/记录

Linux学习笔记[主线 - 项目]


[toc]


#0 当我们学习Linux时我们在学什么?

当我们想要学习不明觉厉的Linux时,你可能会疑惑,我们到底在学什么?

这是一个很重要的问题,我是学电子的,和每一个电子人一样从最基础的单片机,51单片机开始学起,当我们学完单片机时我们学的是一个学习电子,学习开发板的思路和方法。电路板是学不完的,但当我们拿到电路板,我们有一个基本的思路,即有没有原理图?拿什么软件/语言开发?有没有例程?点个灯?…

因为MCU裸机开发是非常好理解的一件事,MCU就是一个小计算机,一个复杂的电路,你将代码编译为bin/hex,并将其烧录进MCU,然后电路就按程序一句一句运行了,很符合直觉是吧。

但是如果项目复杂起来,你发现裸机开发开始变得很难受了,于是你决定往上爬技能树,上系统!但当我想要学习OS时,发现我不知道要从哪里开始。经过分析,我发现问题在于你不知道操作系统到底帮你解决了什么问题!裸机开发时,如果你找到了BSP或者库,你知道你可以偷懒了,可以直接调库而不是从0开始。那么操作系统的作用是什么呢?

问题导向往往是学习技术最有效的方法,遗憾的是我很难找到一个具体而又简洁的教学内容。就像学会单片机之后你了解了当初你学的东西的作用,但那时候你已经把坑都踩过了。没有办法,我现在无法回答这个问题,我希望我学习结束之后能完成这部分内容。

2025.1.4

#1 从项目出发

自底向上学习往往是系统的,全面的,但是也是最难坚持的,如果是完全新手还好,但是如果是会一点,那就很痛苦,按顺序学起你会遇到很多很多学过的内容,因为教程往往要兼顾0基础的同学,但是这样也让有基础的同学非常痛苦,新旧知识混杂,教程看起来就会变得节奏拖沓,自然就算不得好教程了。所以我觉得如果有一定基础的话,直接从项目出发来学习是比较能够坚持下去的。先自顶向下,通过项目对整体有了个把握,然后再自底向上,这个过程遇见之前大概了解的内容,应是如遇故人,恍然大悟的感觉。

所以我在这里设定一个项目,也是我一直想做的一个项目,即做一个Linux小相机。我列出了具体的需求:

  1. 具有拍照和录像功能

  2. 能够存储照片和录像

  3. 能够与PC进行数据通信导出(和导入)照片
  4. [挑战1] 带驻极体话筒,录像可录音,带喇叭,可播放视频。
  5. [挑战2] 超长时间延时摄影(低功耗运行,可考虑加上太阳能)
  6. [挑战3] 手势控制拍照和录像(延时几秒后开始)

有了需求之后就需要选型了,我决定使用我早前买的3块Milkv Duo开发板作为主控,主要因为是它设计之初就是针对视频监控相关领域设计的,并且这个版本不多不少的资源相当适合做我这种小项目,好像还带0.5T算力,非常适合后期进阶。先前冲动消费花100米入手了3块,现在正好拿来试试水。

然后是屏幕,我选择使用一块2 inch大小240x320分辨率作为显示屏,不大不小,分辨率够。而摄像头是Milkv配套的CG2083。有显示屏和摄像头就可以完成基本功能了,收音和放音就再说吧。控制的话需要按键,按键用什么还在考虑,但是远离总归差不多,套一层抽象先用普通按键就可以了。电池的话打算用一个18650供电,方便易用。

然后对于基本功能,当然是一步一步调通各个模块了,首先是亮屏,然后学会操作这块屏幕,做界面的话倾向于选择使用LVGL。学会操作屏幕之后学习摄像头,学习如何利用摄像头拍照和录像,并保存为文件。完成这两步之后应该对Linux,lvgl以及camera都有所了解了,可以开始设计程序架构和交互逻辑了。后面的功能就再说了,一步一步来。

所以总结一下,当下的目标就是这三个:学习lvgl,学习camera,学习前两者的同时熟悉Linux,学会基础的Linux应用开发。

开干!!!

#2 Linux开发初探 - 第一周总结

第一周的工作有,熟悉Milkv的SDK,编译系统镜像,点屏幕,测试lvgl,其中主要是点屏幕。

lvgl_test

亮屏

这一周最大的收获应该是修改设备树和fbtft的驱动然后编译系统镜像了,对设备树和驱动程序有一个初步的接触。主要参考的是以下几篇文章:

【spi】Milk-V Duo点亮st7735 - Duo - Milk-V Community

Milk-V Duo SPI驱动点亮屏幕(st7789) - Duo - Milk-V Community

主要就是配置引脚功能,修改设备树文件,修改st7789v驱动文件(我的屏幕驱动芯片为st7789),然后在编译配置中添加相应的配置,然后就可以编译了。

其中有几个点卡了比较久的时间,一个是开发板设备树中引脚名称和linux内核文件fbtft-core.c中引脚的联系?不一样的话是不行的。我想这部分涉及设备树和设备驱动的知识,但这里我交叉对比两个参考文章发现了这个问题。我觉得这部分应该还是要学的,因为后面还要添加按键控制。我打算搜集资料添加完按键之后再去学习这个知识点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// cv1800b_milkv_duo_sd.dts
&spi2 {
status = "okay";
/delete-node/ spidev@0;
st7789v: st7789v@0{
compatible = "sitronix,st7789v";
...
dc = <&porta 23 GPIO_ACTIVE_HIGH>; //DC
reset = <&porta 15 GPIO_ACTIVE_HIGH>; //RES
led = <&porta 14 GPIO_ACTIVE_HIGH>; //BL
debug = <0x0>;
};
};

// fbtft-core.c
static void fbtft_reset(struct fbtft_par *par)
{
...
gpiod_set_value_cansleep(par->gpio.reset, 1);
msleep(10);
gpiod_set_value_cansleep(par->gpio.reset, 0);
msleep(200);
gpiod_set_value_cansleep(par->gpio.reset, 1);
msleep(10);
}

还有一个卡住的地方是修改u-boot中引脚初始化文件时修改的文件不对导致编译出来的结果没有实现对应的功能,原因是SDK中存在两套代码:cv1800b_milkv_duo_sdcv1800b_sophpi_duo_sd,看来应该是该其中任意一个,然后编译时选择对应的编译选项即可。不过一键编译脚本只有cv1800b_milkv_duo_sd的选项,所以我直接都改的这个文件夹里面的文件,这里又是一个小知识点,即分步编译时都编译了哪些文件呢

解决了这些问题然后就能够编译出可以点亮屏幕的镜像了,但是烧录镜像开机之后发现显示屏显示有偏移。经查找资料发现是1.14inch - 135x240的屏幕需要修改偏移量,这里参考了这篇文章:SPI LCD驱动移植(基于fbtft) - 哔哩哔哩,但是其中一个偏移数值需要改大(+1),评论区有提到。

至此,就能通过操作/dev/fb0设备操作屏幕显示内容了。

lvgl测试

本来是自己去clone lvgl/lv_port_linux进行编译的,但是发现编译不通过,不知道是不是因为lvgl更新到了v9版本,很多原来的教程和新代码有出入了,行不通。本来是要卡在这里,但是发现milkv官方提供了lvgl例程,于是直接编译测试了。

milkv-duo/lv_port_linux: LVGL configured to work with a standard Linux framebuffer

不过感觉学习的话还是得学习新版的V9版本啊。

#3 LVGL与Linux按键设备学习

Linux开发学习[支线 - 技能点]

这里是主线任务中的一些可跳过或者不可跳过的知识点集合。

设备树和设备驱动

[暂时还没有东西]

Milkv Duo SDK分步编译过程

[暂时还没有东西]


嵌入式Linux学习笔记/记录
https://everyoung.fun/2025/01/10/嵌入式Linux学习记录/
作者
EveRYouNg
发布于
2025年1月10日
许可协议