当前位置: 首页 > news >正文

【嵌入式】——Linux系统调用编程

目录

一、进程与线程

1、进程概念

2、线程概念

3、使用进程相关命令

二、使用vi命令

1、使用gcc、make、CMake编译hallo.c

 2、使用gcc、make、CMake编译fork.c

三、Linux的“虚拟内存管理”与stm32内存映的区别

1. Linux 虚拟内存管理

2. STM32 物理内存管理

四、树莓派创建用户

总结


一、进程与线程

1、进程概念

定义:
进程是程序的一次执行实例,拥有独立的地址空间、资源(如文件描述符、内存、信号等)和系统状态。每个进程由一个唯一的**进程ID(PID)**标识。

特点:

独立性:进程间相互隔离,一个进程崩溃通常不会直接影响其他进程(通过进程间通信(IPC)机制交互)。

资源开销:创建、销毁或切换进程的开销较大,因为需要分配独立的资源(如内存页表、文件描述符表等)。

地址空间:每个进程拥有独立的虚拟地址空间(通过MMU实现隔离)。

2、线程概念

定义:
线程是进程内的执行单元,共享同一进程的地址空间和资源(如内存、文件描述符等),但拥有独立的栈、寄存器状态和程序计数器(PC)。

特点:

轻量级:创建、切换线程的开销远小于进程,因为无需分配新的地址空间。

共享资源:线程间可直接访问同一进程的全局变量、堆内存等,但也需要同步机制(如互斥锁)避免竞争。

协作性:一个线程崩溃可能导致整个进程崩溃(因为共享地址空间)。

3、使用进程相关命令

(1)在home目录下创建一个子目录

mkdir ~/homework

ps -a
kill 3273562

二、使用vi命令

1、使用gcc、make、CMake编译hallo.c

(1)gcc编译

vi hello.c
#include <unistd.h>

int main() {
    write(1, "Hello, linux!\n", 23);
    return 0;
}

(2)make

vi Makefile

编写 Makefile 

CC = gcc
CFLAGS = -Wall
TARGET = hello
SRC = hello.c

all: $(TARGET)

$(TARGET): $(SRC)
	$(CC) $(CFLAGS) -o $@ $^

clean:
	rm -f $(TARGET)

 编译

make        # 编译
./hello     # 运行

(3)CMake

编写 hello.c(同上),确保 hello.c 内容不变。

编写 CMakeLists.txt

vi CMakeLists.txt

 文件写入以下内容:

cmake_minimum_required(VERSION 3.10)
project(hello)

set(CMAKE_C_FLAGS "-Wall")
add_executable(hello hello.c)

编译及运行 

mkdir build && cd build
cmake ..    # 生成 Makefile
make        # 编译
./hello     # 运行

 2、使用gcc、make、CMake编译fork.c

fork.c

#include <stdio.h>
//#include <sys[表情]pes.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>

int main(){
pid_t pid;
int ret = 1;
int status;
pid = fork();

if (pid == -1){

	// pid == -1 表示发生了错误
	printf("can't fork, error occured\n");
	exit(EXIT_FAILURE);
}
else if (pid == 0){

	// pid == 0 表示创建了子进程
	// getpid() 返回调用进程的进程id
	// 返回子进程的进程id
	printf("child process, pid = %u\n",getpid());
	// 返回子进程的父进程,即父进程本身
	printf("parent of child process, pid = %u\n",getppid());

	// argv list第一个参数应该指向
	// 与正在执行的文件关联的文件名
	// 数组指针必须以NULL结尾
	// 指针
	char * argv_list[] = {"ls","-lart","/home",NULL};

	// execv()仅在发生错误时返回。
	// 返回值为-1
	execv("ls",argv_list);
	exit(0);
}
else{
	// 为pid返回一个正数
	// 父进程
	// getppid()返回进程的父进程id
	// 调用进程
        // 返回父进程ID的父进程
	printf("Parent Of parent process, pid = %u\n",getppid());
	printf("parent process, pid = %u\n",getpid());


		// 父进程对子进程调用waitpid()
		// waitpid()系统调用暂停
		// 调用进程直到pid指定的子进程
		// 状态改变
		// 有关所有标志或选项,请参见wait()手册
		if (waitpid(pid, &status, 0) > 0) {
			
			if (WIFEXITED(status) && !WEXITSTATUS(status))
			printf("program execution successful\n");
			
			else if (WIFEXITED(status) && WEXITSTATUS(status)) {
				if (WEXITSTATUS(status) == 127) {

					// execv failed
					printf("execv failed\n");
				}
				else
					printf("program terminated normally,"
					" but returned a non-zero status\n");			
			}
			else
			printf("program didn't terminate normally\n");		
		}
		else {
		// waitpid() failed
		printf("waitpid() failed\n");
		}
	exit(0);
}
return 0;
}

 (1)gcc

同前面编译过程一样,只需要换下文件内容即可

(2)make

更改Makefile ,其余过程一样

CC = gcc
CFLAGS = -Wall
TARGET = fork
SRC = fork.c

all: $(TARGET)

$(TARGET): $(SRC)
	$(CC) $(CFLAGS) -o $@ $^

clean:
	rm -f $(TARGET)

创建 CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(fork)

set(CMAKE_C_FLAGS "-Wall -Wextra")  # 启用警告
add_executable(fork fork.c)       # 生成可执行文件

 编译和运行

mkdir build && cd build
cmake ..     # 生成 Makefile
make         # 编译
./fork      # 运行

三、Linux的“虚拟内存管理”与stm32内存映的区别

1. Linux 虚拟内存管理

核心机制

地址空间虚拟化:

每个进程拥有独立的 虚拟地址空间(32位系统通常为4GB,64位系统更大),与物理内存分离。

通过 MMU(内存管理单元) 和 页表 动态映射到物理内存或磁盘(Swap)。

关键功能:

分页(Paging):内存按固定大小(如4KB)分页,物理内存和虚拟页通过页表关联。

按需加载:程序启动时仅加载必要页,其他页在访问时触发 缺页异常,由内核动态加载。

内存保护:不同进程的地址空间隔离,防止非法访问(如写只读页会触发段错误)。

Swap 机制:将不活跃的页换出到磁盘,扩展可用内存。

优势
多进程隔离:进程无法直接访问其他进程或内核的内存。

大地址空间:程序可使用的内存远超物理内存大小。

内存共享:动态库、文件映射(mmap)等可被多个进程共享。

2. STM32 物理内存管理

核心机制

直接物理内存访问

程序直接操作 物理地址(无虚拟地址层),通常通过 内存映射(Memory Map) 访问外设寄存器或静态分配的RAM。

典型场景:

外设寄存器映射到固定地址(如 0x40000000)。

静态分配的全局变量位于链接脚本定义的RAM区域。

关键特点

无内存隔离:所有代码共享同一物理地址空间,需开发者自行保证安全性。

确定性访问:无分页/缺页机制,访问延迟固定。

无 Swap:仅使用片上RAM或外部扩展RAM,无法利用磁盘。

四、树莓派创建用户

为了使其它人也能够连接树莓派,我们需要创建他们的用户并赋予权限

1、切换到Root用户

sudo -i

2、创建新用户

useradd -m 新用户名

3、设置密码

passwd 新用户名

4、将新用户加入到sudo用户组

adduser newname sudo

5、拷贝数据

cp -R /home/旧用户名/* /home/新用户名/

6、查看用户所属组

id 新用户名

7、更改文件所属

sudo chown 新用户名:所属组(group)  /home/新用户名/*

8、修改shell为bin/bash

usermod -s /bin/bash arslantech

创建用户完成

总结

        对linux的vi命令有了更深入的了解,同时学习到了多种编译方式,初步接触make和CMake编译方式,可能存在部分错误。

http://www.dtcms.com/a/112159.html

相关文章:

  • Appium 自动化测试从入门到精通
  • 我与数学建模之波折
  • One API:LLM API 管理 分发系统,github 24.2K Star!
  • 算法设计与分析5(动态规划)
  • Go+Gin实现多文件上传
  • Linux: 系统内核中的信号
  • 【NLP 53、投机采样加速推理】
  • 【CMake】《CMake构建实战:项目开发卷》笔记-Chapter8-生成器表达式
  • LIO-SAM跑自己的数据集
  • 局域网:电脑或移动设备作为主机实现局域网访问
  • MyBatis操作数据库(1)
  • linux安装redis
  • PyTorch使用(7)-张量常见运算函数
  • AIGC实战——CycleGAN详解与实现
  • NVIDIA AgentIQ 详细介绍
  • 从Keep-Alive到页面关闭:解决Vue和React生命周期函数不触发的实战技巧
  • 相干光信号处理的一些基础知识
  • Spring依赖注入最佳实践:应对接口多实现的挑战
  • Centos7.9怎样安装Mysql 5.7
  • MySQL数据库如何在线修改表结构及字段类型?
  • FreeRTOS/任务创建和删除的API函数
  • HTML表单属性1
  • 线程同步与互斥(上)
  • 计算机通识
  • NB-IoT单灯控制器:智慧照明的“神经末梢”
  • 蓝桥杯嵌入式第15届真题-个人理解+解析
  • 【系统】换硬盘不换系统,使用WIN PE Ghost镜像给电脑无损扩容换硬盘
  • Python3.13安装教程-2025最新版超级详细图文安装教程(附所需安装包环境)
  • PhotoShop学习04
  • 详解大模型四类漏洞