Linux 程序开发流程 / 基本开发工具 / Vim / GCC工具链 / Make 工具 / Makefile 模板

news2024/11/19 19:43:19

编辑整理 by Staok。

本文部分内容摘自 “100ask imx6ull” 开发板的配套资料(如 百问网的《嵌入式Linux应用开发完全手册》,在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO:开发板资料》或《2.2 全系列Linux教程:在线视频与配套资料》里面可以下载到),还有参考 菜鸟教程、C语言中文网、红联的等等等等,比较广泛,侵删。进行了精髓提取,方便日后查阅。过于基础的内容不会在此提及。如有错误恭谢指出!

注:在 Github 上的原版文章日后可能会更新,在其它位置发的不会跟进。文章的 Gitee 仓库地址,Gitee 访问更流畅。

Linux 一般开发步骤

p.s 本应放在最后,刻意写在前头。

Bootloader、Linux 内核、根文件系统、APP 等等软件,需要在 Ubuntu 中编译;但是阅读、修改这些源码时,在 Windows 下会比较方便。

所以工作日常开发流程如下:

PC 端,使用 Source insight 编、改源码 —>传—> Ubuntu 端(通过 SSH 打开),对修改好的源码进行编译、制作 —>下载—> 嵌入式板端,在 Linux 板子上运行、测试。

分步来说就是:

  1. 在 Windows 上(Source insight)阅读、研究、修改,修改后,上传(推荐 FileZilla)到 Ubuntu;

  2. 在 Ubuntu 上编译、制作(推荐使用 MobaXterm 通过 SSH 远程登陆 Ubuntu);

  3. 把制作好的可执行程序下载到 嵌入式开发板 上运行、测试。

u-boot、Linux内核,在 Windows 和 Ubuntu 各存一份。根文件系统使用 buildroot (或 Busybox 或 Yocto)制作,它无需放在 Windows 上。

Linux 下的开发

  • 代码编辑:Vim、gedit(ubuntu 下)。

  • 编译工具:gcc,make,cmake(生成 makefile,网搜教程,本篇不涉及)。

  • 项目管理:git(网搜教程,本篇不涉及)。

详细资料-重要

关于 Linux Shell 命令、GCC、Makefile/CMake、GDB/GDBServer、Vim 等工具的详细使用教程和使用经验,

可见 本系类文章对应 仓库 Github 仓库 或 Gitee 仓库 中:

  • 【1 GCC & GDB & GDBServer】

  • 【1 Linux 命令速查 & Shell & Vim】

  • 【1 Makefile & CMake 教程及模板】

这几个文件夹内!

Vim 编辑器

功能:打开、新建和保存文件;文本编辑;多行、列间复制、粘贴和删除;查找和替换。

意义:开发中,尤其对于大型项目并不常用,但是在需要临时修改、现场调试和没有 GUI 形式的编辑器等等的时候,可以快速进行一些简单文本编辑。

Linux vi/vim | 菜鸟教程 (runoob.com)。

一图以蔽之

  • 一般模式/普通模式:用于按各种快捷键进行光标移动、复制、粘贴和删除等。

  • 编辑模式/插入模式:用于敲字符输入/编辑。

  • 命令行模式:用于输入保存、退出、查找和替换 等 控制命令,在 一般模式 打一个冒号再输入命令。

注:当不知道处于何种模式时,按 ESC 键返回到 一般模式。可以在 Ubuntu 中安装中文输入法。

更多可参考 vim命令大全 - 知乎 (zhihu.com)。

在 一般模式 的快捷键
  • i/a,在光标处的前/后进入 编辑模式。dw,删除一个单词;dd,删除光标所在行(d:delete) 。

  • 单击 o (字母 o)键,在当前光标所在行的下方新建一行,并进入编辑模式。

  • 单击 0(数字零) 光标移至当前行行首;$,光标移至当前行行末;%,在括号()、[]、{}间移动。

  • gg,跳到第一行,(xgg 就是跳到第x行的行首);G,跳到文件结尾。

  • ctrl + u/d 进行 半屏的前后滚动;ctrl + f/b 进行 全屏的 上下翻页。

  • 使用 v 进入可视模式,移动光标来 选定文本块内容;用 y 复制选定块到缓冲区,用 d 剪切选定块到缓冲区,用 p 粘贴缓冲区中的内容。

  • u,撤销上一步操作;ctrl + r,恢复,回退到前一个命令。

  • 针对 Ubuntu 界面来说,ctrl + "-" ,减小字号;ctrl + shift + "+",增大字号。

在 命令行模式 的命令
  • 保存,:w;退出,:q;强制执行,在命令后加!;前面的命令可以组合。文件另存为,:w <filename>。重命名当前文件,:f <filename>

  • 查找,:/pattern 从光标开始处向文件尾搜索字符串 "pattern",后按 n (在同一个方向重复上一次搜索命令)或 N (在反方向重复上一次搜索命令);从当前光标位置开始搜索,若光标在文件开头,则为全文搜索。

  • 替换,:%s/p1/p2/g 将文件中所有的 p1 均用 p2 替换;:%s/p1/p2/gc 替换时需要确认。释义,“ s“ 全称: substitute 替换;“ g“ 全称: global 全局;“ c“ 全称: confirm, 确认。

  • 纵向分屏 来 新打开一个文件 :sp <file> 或 横向分屏 :vsp <file>,此时会同屏新增一个窗口;切换这多个窗口的方法(循环移动):ctrl + w,w(先按 ctrl + w,再按键 w),在多文件编程时,切换不同的窗口很实用。让鼠标可以在多个屏幕间切换::set mouse=a;在某个窗口输入:q,为退出此窗口。

  • 跳转到第 n 行,:n。打印当前文件名和行数,:f

  • 从 a 到 b 行的内容写入 filename 文件,:a,bw <filename>

  • 在 Vim 命令行执行 Shell 命令,:!+ shell 命令

一日,一人,代码前坐禅,贤者模式,顿悟,曰:整个键盘,都是 Vim 的快捷键。

恢复文件

vi 在编辑某一个文件时,会生成一个临时文件,这个文件以 . 开头并以 .swp 结尾。正常退出该文件自动删除,如果意外退出例如忽然断电,该文件不会删除,我们在下次编辑时可以选择一下命令处理:

  • O 只读打开,不改变文件内容。

  • E 继续编辑文件,不恢复 .swp 文件保存的内容。

  • R 将恢复上次编辑以后未保存文件内容。

  • Q 退出 vi。

  • D 删除 .swp 文件。

  • 使用 vi -r <filename> 来恢复 filename 这个文件上次关闭前未保存的内容。

vim 命令行中的 选项
  • -d,Diff 模式 (同 "vimdiff", 可迅速比较两文件不同处)。

  • -R,只读模式 (同 "view")。

  • -b,二进制模式。

  • -r <filename>,恢复上次崩溃的文件 filename (Recover crashed session)。

vim 编辑器的配置

命令行键入vim -version可以看到几个 vim 的配置文件在哪,包括 系统级配置文件(对所有用户有效)system vimrc file 一般在 /etc/vim/vimrc,用户级配置文件(对当前用户有效)user vimrc file 一般在 ~/.vimrc

部分摘自 100ask,部分摘自 《嵌入式C语言的自我修养》
vim ~/.vimrc
在其中(选择性)加入如下内容:
​
" color scheme
colorscheme molokai
​
" disply incomplete commands
set showcmd
​
" set fileencodings 
set fileencodings=ucs-bom,utf-8,cp936,gb2312,gb18030,big5
set background=dark
set encoding=utf-8
set fenc=utf-8
set smartindent
set autoindent
set cul
set linespace=2
set showmatch
set lines=47 columns=90
​
" font and size
" set guifont=Andale Mono:h14
" set guifont=Monaco:hll
set guifont=Menlo:h14
​
" Softtabs, 4 spaces
" 编辑时 backspace 键设置为2个空格
set backspace=2
" 编辑时 tab 键设置为4个空格
set tabstop=4
" 设置自动对齐为4个空格
set shiftwidth=4
set shiftround
set softtabstop=4
set expandtab
set smarttab
​
" Highlight current line
au Winleave * set nocursorline
au WinEnter * set cursorline
set cursorline
​
" 底部显示光标所在行和列
set ruler
​
" 显示行号
set number
" 关闭行号为 set nonumber,即 "option" 前面加 "un" 前缀表失能此功能
​
" 搜索时不区分大小写
set ignorecase
​
" 搜索时高亮显示
set hlsearch
​
" 关闭兼容功能
set nocompatible

vim配置通过按键映射实现括号补全:

在 Vim 官网还有 很多 vim 扩展功能 .vim 文件 提供下载,放到~/.vim/plugin目录,再在~/.vimrc中对其进行配置即可使用。

更多 Vim 配置和插件可参考 Vim编辑器_~青萍之末~的博客-CSDN博客。

GCC 命令详情

编译流程

gcc 编译器可以通过 apt-get 安装 或者 在 GNU 官网下载。

要使用 gcc 等编译器或交叉编译器,应先把编译器的可执行文件放在某个目录,然后给系统环境变量加此路径(Win平台为添加环境变量,Linux 为使用 export 命令,或者在 bashrc 文件中添加,具体步骤在 “换源 和 添加系统变量” 一节 里面的 “添加系统变量” 处),对于 Make 工具同理。可以在 命令行运行 gcc -v 即可使用。

C/C++ 程序文件的编译过程图示:

gcc 基本命令
  • 预处理(-E):gcc -E main.c -o main.i,仅预处理。(通过重定向)输出到指定文件:gcc -E main.c > main.i

  • 编译(-S):gcc -S main.c -o main.s,编译到汇编文件。

  • 汇编(-c):gcc -c main.c -o main.o,只生成目标文件(机器码),不进行链接。

完成整个编译(-o filename)

  • 单文件:gcc main.c -o main,编译输出最终可执行文件,-o 后面要紧跟 输出文件名。

  • 多文件:gcc main.c sub.c add.c -o ouput,其中 main.c 里面 #include 了 sub.h 和 add.h。

  • 输出所有警告:加上 -W-Wall 选项。

文件编码指定

  • 程序文件在保存的时候就选好编码(有 ANSI、GB2312、UNICODE,和很常用的并推荐的 UTF-8),使用 记事本 或者 notepad 可以选择和转换。

  • 使用 gcc 编译器,器对于 程序文件 和 编译出的 二进制可执行程序 都默认为 UTF-8 编码。

  • 若 程序文件 的编码 不为 UTF-8 编码,则应该指定:-finput-charset=GB2312 等。

  • 对于编译出来的可执行程序,可以指定它里面的字符是以什么方式编码:-fexec-charset=GB2312 等。注意,是指定/告知 而 不是转换的意思, gcc 不能转换编码。

  • 例子:gcc -finput-charset=GB2312 -fexec-charset=UTF-8 -o test_charset_ansi test_charset_ansi.c。告知 编译器 .c 文件为 GB2312 编码,编译出的程序应为 UTF-8 编码。

  • 在代码中使用汉字这类非 ASCII 码 字符 时,要特别留意编码格式。

头文件选项

  • 对于 #include <...> 的头文件(一般都是 标准库的头文件,比如 stdio.h、stdlib.h、string.h 等) 编译器在编译时会去 gcc 默认的路径中(编译器目录里面的 include 文件夹里)寻找头文件。可以通过 echo 'main(){}'| arm-linux-gnueabihf-gcc -E -v - 命令来 列出头文件目录、库目录(LIBRARY_PATH)。

  • 对于 #include "..." 的头文件去 -I <dirname> 这个选项所指定的目录(dirname 目录)中去找(如果不加 -I 选项则默认搜 当前目录),-I <dirname> 即是将 dirname 目录加入到头文件搜索目录列表中,用户引用除了 上面 的标准库头文件 而是 自己的头文件,就用这种方式。例如 main.c 目录中有 inc 文件夹,里面有 test.h 文件,并且 main.c 中通过 #include "test.h" 调用了 test.h 文件,则命令为:gcc main.c -I inc -o main

  • 编译时寻找库文件:

    • 默认的系统目录:就是交叉编译工具链里的某个 lib 目录。

    • 自己指定添加库文件搜索目录:链接时(-L dirname)。

    • 自己指定添加某一个具体的库文件:加载库名选项(-l name),比如想链接 libabc.so,那链接时加上 -labc

    • 静态库选项(-static)等选型 略。

  • 运行时寻找库文件:(程序运行时不需要再加载头文件,因为编译时已经编译进去了)

    • 系统目录:就是板子上的 /lib、/usr/lib 目录。

    • 自己指定:用环境变量 LD_LIBRARY_PATH 指定,比如 export LD_LIBRARY_PATH=/xxx_dir

代码优化选项

  • -O 或 -O1:基本优化,使代码执行的更快。

  • -O2 或 -O3:产生尽可能小和快的代码。如无特殊要求,不建议使用 O2 以上的优化。

  • -Os:生成最小的可执行文件,适合用于嵌入式软件。

调试模式选项

  • 输出带调试信息,可以用于 GDB 单步调试来 debug:加上-g选项。

  • 产生能被 GDB 调试器使用的调试信息:gcc main.c -g -o main

  • GDB 的命令行调试指令详情略(包括运行、单步执行、加删查断点、打印变量等命令)。

下面引用 embedded-notes/linux.md at master · xiaowenxia/embedded-notes (github.com)。

gcc工具链

命令描述
Binutils由汇编器(as)产生的目标代码(*.o)是不能直接在computer上运行的,它必须经过链接器(ld)的处理才能生成可执行代码。
add2line将地址转换成文件名或行号对,以便调试程序
ar从文件中创建、修改、扩展文件
gasp汇编宏处理器
nm从目标文件列举所有变量
objcopy使用GNU BSD库把目标文件的内容从一种文件格式复制到另一种格式的目标文件中。
objdump显示目标文件信息可发编译二进制文件,也可以对对象文件进行反汇编,并查看机器代码。
readelf显示elf文件信息
ranlib生成索引以加快对归档文件的访问,并将其保存到这个归档文件中。
size列出目标模块或文件的代码尺寸。
strings打印可打印的目标代码符号(至少4个字符)
strip放弃所有符号连接,一般应用程序最终都要strip处理
C++filt链接器ld通过该命令可过滤C++符号和JAVA符号,防止重载函数冲突。
gprof显示程序调用段的各种数据

ld 交叉链接器

将多个编译后产生的过程文件连接为一个最终的可执行文件。

ld [options] 链接器脚本 -o 文件名.elf

readelf 交叉ELF文件查看器

用来查看一个可执行文件的相关信息

可以查看elf文件的运行架构,大小端等信息:

readelf -a 文件名.elf

显示程序需要的动态链接库:

readelf -d 文件名.elf

objdump 交叉反汇编器

将一个可执行文件转换为汇编下的程序

-objdump -D -S elf文件名 >目标文件

objcopy 交叉转换器

将elf格式文件转换成其他的格式

objcopy -O 目标文件格式 原ELF文件 目标文件

例子:

objcopy -O binary a.elf a.bin

Makefile 简述和模板

解决问题:针对包含超多文件的工程;自动搜索被添加目录中的所有被调用的文件;在第二次全编译时,没有修改的文件只链接而不重复编译节省时间;等等。

基本格式
目标(target):依赖(prerequisites)
[Tab]命令(command)
  • target:需要生成的目标文件。

  • prerequisites:生成该 target 所依赖的一些文件。

  • command:生成该目标需要执行的 命令行的命令。

在命令前加 "@" 符号,在 make 时不显示此条命令的执行过程,只显示结果。

举一个例子:

# 在命令行执行 make 或者 make all 即执行这里,这里是执行 hello,其描述在下面
all:hello
​
# 这是一个规则,包含 目标、依赖 和 命令
# 表示 执行 hello 命令/目标 ,所用到的 文件/原材料 有 main.o sum.o,要执行的命令为 gcc -o hello main.o sum.o
# 从 多个 源文件 来组合 生成 执行文件
hello:main.o sum.o
    gcc -o hello main.o sum.o
​
# 上面所依赖的 目标 main.o 要进行的命令
main.o:main.c
    gcc -c main.c
​
sum.o:sum.c
    gcc -c sum.c
​
# 清理,命令行键入 make clean 即可执行此
clean:
    rm -f main.o sun.o hello
变量赋值( =、:=、?=、+= )
# Makefile 中的变量是字符串。
PARA = 100ask
​
# 注,注释必须单独一行,不能写在语句后面
​
# =
# 相当于 PARA 的指针给 CURPARA,之后 PARA 的值变,CURPARA 的值会跟着变。
CURPARA = $(PARA)
​
# :=
# 仅赋值,之后 PARA 的值变,CURPARA 的值不会跟着变。
CURPARA := $(PARA)
​
# ?=
# 使用“?=”给变量设置值时,如果这个变量之前没有被设置过,那么“?=”才会起效果;如果曾经设置过这个变量,那么“?=”不会起效果。相当于函数定义时的 weak 修饰符。
​
# +=
# 这样的结果是OBJ的值为:”main.o,add.o,sub.o“。说明“+=”用作与变量的追加。
OBJ = main.o add.o
OBJ += sub.o
自动变量( $@、$^、$< )
CC = gcc
OBJ = main.o add.o sub.o
output: $(OBJ)
    $(CC) -o $@ $^
    # $@:表示规则中的目标(target),即 output
    # $^:表示规则中的所有依赖文件(All prerequisites),即 main.o add.o sub.o
​
main.o: main.c
    $(CC) -c $<
    # $<:表示规则中的第一个依赖文件(The first prerequisites),即 main.o 右边的第一个依赖,即 main.c
add.o: add.c
    $(CC) -c $<
sub.o: sub.c
    $(CC) -c $<
​
clean:
    rm $(OBJ) output
模式规则( %.x )
CC = gcc
OBJ = main.o add.o sub.o
output: $(OBJ)
    $(CC) -o $@ $^
%.o: %.c
    $(CC) -c $<
# %.o: %.c 表示如下:
# main.o 由 main.c 生成,add.o 由 add.c 生成,sub.o 由 sub.c 生成
​
clean:
    rm $(OBJ) output
伪目标
# 在目标和文件名重名时,加上这句指令,便可以正常执行。用于避免执行命令的目标和工作目录下的实际文件出现名字冲突。
.PHONY:clean
clean:
    rm $(OBJ) output
Makefile 函数

经常使用的 Makefile 函数,主要有两个(wildcard,patsubst)。函数的调用格式 $(function(空格或tab)arguments),这里 function 是函数名, arguments 是该函数的参数。

# $(wildcard 指定文件类型) 用于查找指定目录下指定类型的文件
# 这条规则表示,找到目录./src下所有后缀为.c的文件,并赋值给变量SRC。命令执行完,SRC变量的值:./src/ask.c ./src/100.c
SRC = $(wildcard ./src/*.c)
​
# $(patsubst 原模式, 目标模式, 文件列表)  用于匹配替换
# 这条规则表示,把变量 SRC 中所有后缀为.c的文件替换为.o。 命令执行完,OBJ变量的值:./src/ask.o ./src/100.o
OBJ = $(patsubst %.c, %.o, $(SRC))
​
# $(subst from,to,text)  字符串替换,在文本`text’中使用`to’替换每一处`from’。
# 结果为‘fEEt on the strEEt’
$(subst ee,EE,feet on the street)
​
# $(strip string)  去掉前导和结尾空格,并将中间的多个空格压缩为单个空格。
# $(findstring find,in)  在字符串`in’中搜寻`find’,如果找到,则返回值是`find’,否则返回值为空。
# $(filter pattern...,text)   返回在`text’中由空格隔开且匹配格式`pattern...’的字,去除不符合格式`pattern...’的字。
# $(filter-out pattern...,text)  返回在`text’中由空格隔开且不匹配格式`pattern...’的字,去除符合格式`pattern...’的字。它是函数filter的反函数。
# $(sort list)   将‘list’中的字按字母顺序排序,并去掉重复的字。输出由单个空格隔开的字的列表。
​
# 文件名函数 略
一个简易的 Makefile 模板
该 Makefile 模板 针对的 文件夹 的 树形目录结构
├── inc
│  ├── add.h
│  └── sub.h
├── Makefile
└── src
  ├── add.c
  ├── main.c
  └── sub.c
# 编译输出文件加尾缀 "_VERSION"
VERSION = 0.0.1
# 源文件 .c 文件的所在的名为 src 的目录
SOURCE = $(wildcard ./src/*.c)
# 增加一个名为 src1 的源文件所在目录
#SOURCE += $(wildcard ./src1/*.c)
​
# 引用文件 .h 文件的所在的名为 inc 的目录
INCLUEDS = -I ./inc
# 增加一个名为 inc1 的引用文件所在目录
#INCLUEDS += -I ./inc1
​
# 编译输出目标文件的文件名
TARGET    = output
# 编译输出目标文件所在的文件夹名
OUTPUTDIR = obj
# 编译器全名
CC        = gcc
​
# 以下都是固定的不用动
​
CFLAGS  = -Wall -g
OBJECT  = $(patsubst %.c, %.o, $(SOURCE))
​
$(TARGET): $(OBJECT)
    @mkdir -p $(OUTPUTDIR)/
    $(CC) $^ $(CFLAGES) -o $(OUTPUTDIR)/$(TARGET)_$(VERSION)
​
%.o: %.c
    $(CC) $(INCLUEDS) $(CFLAGES) -c $< -o $@
​
.PHONY:clean
clean:
    @rm -rf $(OBJECT) $(OUTPUTDIR)/
​
更加通用的 Makefile 模板

在对应仓库 Github 仓库 或 Gitee 仓库 中:

在文件 【1 Makefile CMake 教程 及其模板】\general_Makefile.zip 里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1199760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为ensp:rip宣告

ip全部配置好 R1 进入r1视图模式 rip network 192.168.1.0 network 1.0.0.0 R2 进入r2视图模式 rip network 192.168.2.0 network 1.0.0.0 这样就完成了宣告 display ip routing-table 查看路由表

Java基础——数组(一维数组与二维数组)

文章目录 一维数组声明初始化与赋值内存图解 二维数组声明初始化与赋值内存图解 数组练习 数组是多个相同类型的数据按一定顺序排列的集合。 说明&#xff1a; 数组是引用数据类型&#xff0c;数组的元素是同一类型的任何数据类型&#xff0c;包括基本数据类型和引用数据类型…

基于YOLOv8的输电线路异物识别算法应用

基于 YOLOv8 的输电线路异物识别算法应用 输电线路作为电力系统的重要一环&#xff0c;保证其安全稳定运行是十分必要的。由于长期暴露于室外&#xff0c;线路所面临的不安全因素繁多&#xff0c;异物入侵便是其中之一。异物可能会引起线路短路甚至诱发火灾&#xff0c;因此要加…

使用3D Touch,让你左右逢源,操作更自然

本文介绍了如何在苹果设备上使用3D Touch&#xff0c;以及哪些应用程序支持该工具。3D Touch在Apple Watch上也称为Force Touch&#xff0c;在iPhone XR上也称为Haptic Touch。 如何改变3D触摸的灵敏度 按照以下步骤调整3D Touch的灵敏度&#xff1a; 1、打开“设置”应用程…

docker安装AWVS 23.9.231005181

本文声明仅AWVS用作学习使用 将镜像文件secfa_awvs.tar复制到目标机器上。 我的百度网盘文件路径&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1frbOH4UZlMz9bMXyZs1o0g 提取码&#xff1a;na6y –来自百度网盘超级会员V6的分享 在目标机器上&#xff0c;使用以下命…

原码补码相关运算

求补码步骤 原补转换 -127为负数&#xff0c;其补码为原码01111111&#xff0c;取反10000000&#xff0c;加一&#xff0c;10000001。 例如&#xff1a; 【-1】原码 10000001 反码bai11111110 补码duzhi 11111111 【3】原码 00000011 反码 00000011 补码 00000011 【-127】…

【多线程】

文章目录 概念一、线程的生命周期图二、线程的创建方式一方式二线程API线程优先级sleep阻塞守护线程多线程并发安全问题 总结 概念 线程:一个顺序的单一的程序执行流程就是一个线程。代码一句一句的有先后顺序的执行。多线程:多个单一顺序执行的流程并发运行。造成"感官上…

算法——滑动窗口

什么是窗口&#xff1f;就是符合题目要求的区域内的数据&#xff0c;将每次符合数据的窗口内的数据记录下来&#xff0c;然后将窗口后移&#xff0c;寻找其他符合要求的数据&#xff0c;每次进入窗口和退出窗口都需要一定的要求 一、 LCR 008. 长度最小的子数组 - 力扣&#…

Git之分支与版本->课程目标及知识点的应用场景,分支的场景应用,标签的场景应用

1.课程目标及知识点的应用场景 Git分支和标签的命名规范 分支 dev/test/pre/pro(即master) dev:开发环境--windows (自己的电脑) test:测试环境--windows/linux (公司专门的测试电脑 pre:灰度环境(非常大的公司非常重要的项目) pro:正式环境 灰度环境与正式环境的服务器配置…

论文笔记:Deep Trajectory Recovery with Fine-Grained Calibration using Kalman Filter

TKDE 2021 1 intro 1.1 背景 用户轨迹数据对于改进以用户为中心的应用程序很有用 POI推荐城市规划路线规划由于设备和环境的限制&#xff0c;许多轨迹以低采样率记录 采样的轨迹无法详细说明物体的实际路线增加了轨迹中两个连续采样点之间的不确定性——>开发有效的算法以…

RK3588平台 WIFI的基本概念

一.安卓WIFI框架 Android WIFI系统引入了wpa_supplicant&#xff0c;它的整个WIFI系统以wpa_supplicant为核心来定义上层接口和下层驱动接口。Android WIFI主要分为六大层&#xff0c;分别是WiFi Settings层&#xff0c;Wifi Framework层&#xff0c;Wifi JNI 层&#xff0c; W…

ARM Linux 基础学习 / Linux Shell,必要命令全记录

编辑整理 by Staok。 本文部分内容摘自 “100ask imx6ull” 开发板的配套资料&#xff08;如 百问网的《嵌入式Linux应用开发完全手册》&#xff0c;在 百问网 imx6ull pro 开发板 页面 中的《2.1 100ASK_IMX6ULL_PRO&#xff1a;开发板资料》或《2.2 全系列Linux教程&#xf…

高级项目管理总结

目录 一、背景介绍二、思路&方案三、过程1.升维思考2.结构化3.心理、知识阶段检验4.微观 四、总结 一、背景介绍 天性对学习对考试充满敌意的我&#xff0c;转变为依赖学习谋生&#xff0c;再到后来书中自有黄金屋&#xff0c;到现在学习对我而言就如同一日三餐&#xff1…

Unity - 各向异性 - 丝绸材质

文章目录 目的环境主观美术效果的[假]丝绸基于物理的方式ProjectPBR filament web captureReferences 目的 拾遗&#xff0c;备份 环境 Unity : 2020.3.37f1 Pipeline : Builtin Rendering Pipeline 主观美术效果的[假]丝绸 非常简单 : half specualr pow(1 - NdotV, _Edg…

【STM32】TIM2的PWM:脉冲宽度调制--标准库

注意点&#xff1a; TIM_Period---->指要进行比较的值Compare TIM_Prescaler----> 指要进行分频的值【分频值/原始时钟值】 PWM是一种周期固定&#xff0c;脉宽可调整的输出波形。 https://www.cnblogs.com/brianblog/p/7117896.html 0.通用寄存器输出 1.捕获/比较通道…

CountDownLatch和CyclicBarrier详解

1. CountDownLatch 1.1 简介 CountDownLatch 是 Java 中并发包&#xff08;java.util.concurrent&#xff09;提供的一种同步工具&#xff0c;用于在多线程环境中协调多个线程之间的执行顺序。它的作用是允许一个或多个线程等待其他线程完成操作。 CountDownLatch 通过一个计…

Python基础入门例程51-NP51 列表的最大与最小(循环语句)

最近的博文&#xff1a; Python基础入门例程50-NP50 程序员节&#xff08;循环语句&#xff09;-CSDN博客 Python基础入门例程49-NP49 字符列表的长度-CSDN博客 Python基础入门例程48-NP48 验证登录名与密码&#xff08;条件语句&#xff09;-CSDN博客 目录 最近的博文&…

深度解析CompletableFuture:Java 异步世界的奇迹

目录 概述 介绍 上文我们可知&#xff1a;CompletableFuture 是 Java 8 引入用于支持异步编程和非阻塞操作的类。对于没有使用过CompletableFuture通过它这么长的名字就感觉到一头雾水&#xff0c;那么现在我们来一起解读一下它的名字。 Completable&#xff1a;可完成Futur…

【Redis】Redis-Key的使用

上一篇&#xff1a; redis-server和redis-cli https://blog.csdn.net/m0_67930426/article/details/134361885?spm1001.2014.3001.5501 官网 命令 |雷迪斯 (redis.io) 设置key set name xxxxx 查看key keys * 再设置一个key并且查看 这里查看了两个key&#xff08;name a…

Git之分支与版本

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.开发测试上线git的使用 1.1. 环境讲述 当软件从开发到正式环境部署的过程中&#xff0c;不同环境的作用…