自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(87)
  • 收藏
  • 关注

原创 Linux系统编程(七)进程间通信IPC

上面这种方法有一个缺点,就是假如 server_job 的任务执行时间太长的话,需要等待 server_job 执行完后才能继续 accept 下一个连接请求,这样效率十分低,所以可以采用多线程的方式来解决,每个进程或线程处理一个连接请求。udp 会出现丢包的问题,TTL生存周期(路由跳转个数) ,丢包是由阻塞造成的,当等待队列快满的时候会发生丢包(网络太拥塞),可以使用流量控制解决(限制发送端的速率)。多点通信(广播、多播、组播)只能用报式套接字实现,因为流式套接字是一对一的,点对点的。

2024-06-27 21:53:49 951

原创 Linux系统编程(六)高级IO

阻塞io会等待操作的完成或期待事情的到来。会被信号打断(信号会打断阻塞中的系统调用),若被打断则错误码为EINTR(假错)。操作的完成和期待事件的到来会通知阻塞的进程。

2024-03-07 20:22:05 730

原创 STM32 学习(四)中断系统

众所周知,轮询是 CPU 通过不断地查询某个外部设备的状态,如果外部设备准备好,就可以向其发送数据或者读取数据,这种方式由于CPU不断查询总线,导致指令执行受到影响,效率非常低。而与之相对应的就是中断,正常情况 CPU 会处理其他的事情,如果设备有需要 CPU 处理的事情就产生一个中断,CPU 就会停下正在做的事情来处理中断。中断的执行流程如下:STM32 中断包含很多中断源(中断通道),并且使用 NVIC 统一管理中断,由左边的地址组成的表称为,表中的内容为中断入口的地址:为。

2024-02-28 20:57:13 1697

原创 Linux系统编程(五)并发(信号、线程)

信号是软件层面的中断。信号的响应依赖于中断。信号分为标准信号和实时信号。kill -l 可以查看系统中的信号:core 文件是程序出错的现场,可以使用 gdb 对 core 文件进行调试。

2024-02-28 15:39:47 731

原创 Linux系统编程(四)进程

系统调用会复制调用进程来创建一个子进程,在父进程中 fork 返回子进程的 pid,在子进程中返回 0。fork 后子进程不继承未决信号和文件锁,资源利用量清 0。由于进程文件描述符表也继承下来的,所以可以看到父子进程的输入输出指向都是一样的,这个特性可以用于实现基本的父子进程通信。

2024-02-15 18:29:15 1017

原创 6.1810: Operating System Engineering 2023 <Lab9: mmap>

mmap(2) 系统调用能将文件或者设备映射到内存中,返回映射区域的起始地址。

2024-02-07 15:23:12 1089

原创 Linux系统编程(三)文件系统

可以通过打开的文件描述符获取文件的属性。lstat() 和 stat() 功能相同,有一点区别就是当 pathname 是一个链接文件的时候,lstat() 返回的是链接文件本身的属性,而不是链接文件指向的文件的属性。下面是 stat 结构体中的部分成员:但 st_size 仅仅是文件的属性,实际占用磁盘的块大小和个数是 st_blksize 和 st_blocks。

2024-01-25 19:30:27 1068

原创 6.1810: Operating System Engineering 2023 <Lab8 fs: File system>

在这一节,我们将为 xv6 的文件系统加入大文件和符号链接。

2024-01-22 17:05:09 869

原创 Linux系统编程(二)文件IO/系统调用IO

不同系统上的系统调用 IO 的使用方式可能不一样,为了隐藏不同系统上的细节,提出了标准 IO 给程序员调用,标准 IO 的实现是依赖于系统调用 IO 的,但是标准 IO 的可移植性更好。系统调用 IO 都是不带缓冲的 IO,而标准 IO 是带缓冲的 IO。

2024-01-18 21:31:30 889

原创 6.1810: Operating System Engineering 2023 <Lab7 lock: Parallelism/locking>

xv6 文件系统软件层次如下:通过路径树我们可以找到相应的文件:fd(文件描述符)是进程用来标识其打开的文件的手段,每个进程有自己的文件打开表,并且系统会维护一个全局文件打开表(系统中所有打开的文件都保存在这个全局文件打开表中)。

2024-01-16 19:28:51 925

原创 Linux系统编程(一)标准IO

不同系统上的系统调用 IO 的使用方式可能不一样,为了隐藏不同系统上的细节,提出了标准 IO 给程序员调用,标准 IO 底层其实还是调用了系统调用 IO,但是标准 IO 的可移植性更好

2024-01-10 17:46:06 1090

原创 6.1810: Operating System Engineering 2023 <Lab6: Multithreading>

在多 CPU 或者单 CPU 多线程并发的场景中,对临界资源(或者说共享资源)的访问如果不加以限制,可能会引发一些严重的问题,比如当两个线程同时对一个共享数据写的时候,这个共享数据的值就会变为最后一个写的内容,并且会覆盖前一个写的内容。这时候,就有人引入了一些并发控制(concurrency control)技术来避免并发场景中的这些问题。,锁提供了互斥性,保证了在任何时刻只能有一个线程持有它。

2024-01-04 20:48:55 901

原创 STM32 学习(三)OLED 调试工具

在进行单片机开发时,有很多调试方法,如下图:其中 OLED 就是一种比较好用的调试工具:OLED 硬件电路如下,左边为四引脚型的电路,SCL 和 SDA 为的通信引脚,可以接到单片机上的 I2C 引脚或者 GPIO 口模拟的 I2C 通信。右边为七引脚型的电路,D0、D1、RES、DC、CS 为通信协议的引脚。

2024-01-03 20:26:54 634

原创 STM32 学习(二)GPIO

GPIO(General Purpose Input Output)即通用输入输出口。

2024-01-02 22:55:53 3653 3

原创 STM32 学习(一)新建工程

第二种启动模式中,系统存储器中存放了一部分Bootloader程序,该程序可以接收串口的数据,然后刷新到主闪存中,这样就可以使用串口下载程序。

2023-12-28 11:38:37 702

原创 6.1810: Operating System Engineering 2023 <Lab5: cow: Copy-on-write fork>

当用户键入一个字符时,UART 硬件会引发一个中断,从而激活 xv6 的陷阱处理程序(trap handler)。上半部分是通过系统调用调用的,如 read 和 write 希望设备执行I/O,然后程序会等待操作(如 read 和 write 操作)执行完成;最终设备执行完 I/O 后会发起一个中断,然后执行中断处理程序,中断处理程序可以唤醒等待 I/O 操作的进程,这部分就是中断下半部。来自设备的中断也是 trap 的一种,内核陷阱处理程序识别设备引发的中断并调用驱动程序的中断处理程序;

2023-12-26 18:31:58 158

原创 6.1810: Operating System Engineering 2023 <Lab3: page tables>

一些系统调用将数据放到用户空间和内核空间之间的只读区域(即内核和用户都可以访问,但是用户只能读页面),从而绕过内核实现加速。第三个参数为一个地址,用来返回结果,将结果存储到位中(每页使用一位,其中第一页对应于最低有效位)。在 rv32 和 rv64 中,int 类型都是 32 位,而 long 和 指针类型在 rv32 中是 32 位,在 rv64 则是 64 位。这是打印 pid = 1 的进程的页表,首先打印页表地址,然后递归打印页表项和对应的物理地址。首先我们需要定义 PTE_A,即访问位,查阅。

2023-12-06 22:35:12 326 1

原创 6.1810: Operating System Engineering 2023 <Lab4 traps: Traps>

trap 的一般流程为:首先 trap 会使控制转移到内核,内核保存寄存器和一些其他状态信息;然后内核执行适当的处理程序(如系统调用的实现或设备驱动程序);最后内核恢复保存的状态,并且从 trap 返回到原来执行的位置继续执行。在 xv6 中,这三种情况被统称为 trap,系统调用、异常、设备中断以同样的方式进入内核。

2023-12-06 22:34:48 194

原创 6.1810: Operating System Engineering 2023 <Lab2 syscall: System calls>

这部分也要实现一个系统调用,可以返回一个结构体给用户,结构体里面包含了正在使用的进程个数,以及当前的空闲内存,这部分主要注意的地方就是内核空间的内存用户是访问不了的,所以需要使用 copyout 函数将用户空间的结构体拷贝到用户空间上,然后把结构体在用户空间上的地址返回即可。当机器上电,它会运行一个存储在只读内存中的引导程序(boot loader),引导程序会把 xv6 内核搬运到内存中,然后,在机器模式下,cpu 执行 xv6 的。一个进程最重要的内核状态包括它的页表,它的内核栈,和它的运行状态。

2023-12-01 22:27:38 394

原创 6.1810: Operating System Engineering 2023 <Lab1 util: Unix utilities>

使用 pipe() 系统调用初始化一个管道,两个文件描述符放到数组里面,第一个文件描述符用于读,第二个用于写。这里先关掉了标准输出描述符 1,然后使用 open 打开 out 文件,因为 open 会选择最小的可使用的文件描述符,所以文件 out 对应的文件描述符为 1,再使用 exec 执行 echo程序,echo 程序就会把写到到标准输出上的内容写到文件 out 里。close() 系统调用会关闭对应的文件描述符,而 dup() 会复制一个文件描述符,被复制的文件描述符和原来的描述符指向相同的文件。

2023-11-15 22:30:05 263

原创 RISC-V处理器设计(五)—— 在 RISC-V 处理器上运行 C 程序

前面我们使用 verilog 完成了一个 risc-v cpu 的设计,但 cpu 最终也是为了程序服务的,不能执行程序的 cpu 没有任何意义。所以这一节我们要研究如何在自己设计的 cpu 上运行 C 程序。

2023-11-08 15:34:56 3145 3

原创 RISC-V处理器设计(四)—— Verilog 代码设计

从6月底刚开始接触 risc-v 架构,到现在完成了一个 risc-v cpu 的设计,并且成功移植了 rt-thread nano 到本 cpu 上运行,中间经过了 4个多月的时间,遇到了数不清的问题,也想过放弃,但好在最后还是坚持下来了,并且最终项目也得到了 gitee 的推荐,可以说是功夫不负有心人把。

2023-11-06 20:21:13 3961 5

原创 程序从编译到运行

编译一个 C 程序从可以分为四个阶段:预处理 --> 编译(生成汇编代码)--> 汇编 --> 链接。下面以大家最熟悉的 hello world 程序为例,编译器为 linux 下的 gcc。执行该文件可以打印 hello world:下面我们把几个步骤分开执行来理解每个步骤所完成的工作。

2023-10-31 11:19:03 591

原创 &((type *)0)->member的用法

计算结构体成员的偏移量,结构体变量的某成员的地址等于该结构体变量的基址加上结构体成员变量在结构体中的偏移量。而 (type*)0 就是假设地址 0 处存放的是一个 type 类型的结构体变量,这样的话这个结构体变量的基址就是 0,所以。在遍历链表的时候,我们只需要用到 rt_list_t 结构体,找到对应的结构体后,我们再通过 rt_list_t 结构体及其偏移计算出 rt_thread 结构体的地址,是不是很灵活!另外,在 linux 内核中,链表也是用这种方式实现的。

2023-09-13 15:22:37 627

原创 x86 汇编手册快速入门

本指南描述了 32 位 x86 汇编语言编程的基础知识,包括寄存器结构,数据表示,基本的操作指令(包括数据传送指令、逻辑计算指令、算数运算指令),以及函数的调用规则。

2023-08-30 17:25:36 1743

原创 Linux内核学习(十三)—— 设备与模块(基于Linux 2.6内核)

并不是所有设备驱动都表示物理设备。有些设备驱动是虚拟的,仅仅提供访问内核功能而已。这种设备被称为 ”伪设备“ (pseudo device),如内核随机数发生器(/dev/random)、空设备(/dev/null)等。

2023-08-29 14:47:51 1221

原创 Linux内核学习(十二)—— 页高速缓存和页回写(基于Linux 2.6内核)

Linux 内核实现了一个被叫做的磁盘缓存,它主要用来减少对磁盘的 I/O 操作。它是通过把磁盘中的数据缓存到中,把对磁盘的访问变为对物理内存的访问。临时局部原理(temporal locality):如果在第一次访问数据时缓存它,那么就极有可能在短时间内再次访问到,因为程序内存在着循环;并且其相邻的数据也可能在短时间内被访问到,因为程序内存放的数据有很多是连续的(如数组)。

2023-08-28 11:25:43 496

原创 Linux内核学习(十一)—— 进程地址空间(基于Linux 2.6内核)

进程地址空间由进程可寻址并且允许进程使用的虚拟内存组成, 每个进程都有一个 32 位或 64 位的平坦(flat)地址空间,空间的具体大小取决于体系结构。术语 “平坦(flat)” 指的是地址空间范围是一个独立的连续空间。每个进程都有唯一的这种平坦地址空间,一个进程的地址空间与另一个进程的地址空间即使有相同的内存地址,实际上也彼此互不相干。相对地,能与其他进程共享它们的地址空间的进程,被称为线程。

2023-08-27 21:52:51 572

原创 Linux内核学习(十)—— 块 I/O 层(基于Linux 2.6内核)

系统中能够固定大小数据片(chunks)的硬件设备称作,这些固定大小的数据片就称作。最常见的块设备为硬盘,其他的还有软盘驱动器、闪存等,它们都是以安装文件系统的方式使用的。另一种基本的设备类型是。字符设备按照的方式被,像串口和键盘就属于字符设备。对于这两种类型的设备,它们的区别在于是否可以随机访问数据。内核对块设备的管理需要有一个专门提供服务的子系统,对字符设备的管理则不需要。

2023-08-26 16:19:48 752

原创 Linux内核学习(九)—— 虚拟文件系统(基于Linux 2.6内核)

虚拟文件系统(VFS)作为内核子系统,为用户空间程序提供了文件和文件系统相关的接口。通过虚拟文件系统,程序可以利用标准的 Unix 系统调用对不同的文件系统(甚至不同介质上的文件系统)进行读写操作。

2023-08-25 17:12:57 449

原创 Linux内核学习(八)—— 内存管理(基于Linux 2.6内核)

内核把作为内存管理的基本单位。尽管处理器的最小可寻址单位通常为字或字节,但是,通常以页为单位进行处理。MMU 以页为单位来管理系统中的页表。从虚拟内存的角度来看,页就是最小单位。大多数 32 位体系结构支持 4KB 的页,而 64 位体系结构一般会支持 8KB 的页。内核用结构表示系统中的每个page 结构与物理页相关,而并非与虚拟页相关。内核用这一结构来管理系统中所有的页,因为内核需要知道一个页是否空闲。

2023-08-24 16:19:35 438

原创 Linux内核学习(七)—— 定时器和时间管理(基于Linux 2.6内核)

系统定时器是一种可编程硬件芯片,能以固定频率产生定时器中断,它所对应的中断处理程序负责更新系统时间,也负责执行需要周期性运行的任务。

2023-08-23 11:17:50 381

原创 Linux内核学习(六)—— 中断(基于Linux 2.6内核)

中断使得硬件得以发出通知给处理器。中断随时都可以产生,如键盘敲击就会触发中断,通知操作系统有按键按下。不同设备对应的中断不同,而每个中断都通过一个唯一的数字标识。这些中断值通常被称为中断请求(IRQ)线。每个 IRQ 线都会关联一个数值量。异常与中断不同,它在产生时必须考虑与处理器时钟同步,异常也常常被称为。在处理器执行到错误指令时候(如除数为0),或者是在执行期间出现特殊情况(如缺页),这些异常需要通过内核来处理,处理器就会产生一个异常。

2023-08-21 17:00:00 703 1

原创 Linux内核学习(四)—— 系统调用(基于Linux 2.6内核)

在现代操作系统中,内核提供了用户进程与内核进行交互的一组接口,这些接口在应用程序和内核之间扮演了使者的角色。这些接口保证了系统的稳定可靠,避免应用程序肆意妄行。

2023-08-20 15:41:15 375

原创 开发一个RISC-V上的操作系统(八)—— 抢占式多任务(Preemptive Multitasking)

在第五节的内容中,我们实现了协作式多任务,这一节我们要实现的是抢占式多任务。

2023-08-13 21:09:08 727

原创 开发一个RISC-V上的操作系统(七)—— 硬件定时器(Hardware Timer)

生活离不开对时间的管理,操作系统也是一样。时钟节拍(Tick)操作系统中最小的时间单位。Tick的单位(周期)由硬件定时器的周期决定(通常为1~100ms)。Tick周期越小,系统精度越高,但开销越大。

2023-08-13 18:34:33 686

原创 开发一个RISC-V上的操作系统(六)—— 中断(interrupt)和异常(exception)

一般来说,异常为当前执行的指令发生了“不正常的情况”,如除法指令的除数为0、缺页异常等等,异常发生后会跳转执行异常处理程序,视情况决定是否跳回发生异常的指令继续执行,如缺页异常在执行完缺页处理程序后会跳转到原指令继续执行,而非法指令引起的异常则不会跳回原指令继续执行。而中断则是在当前执行流中发生了某个外部事件,需要暂停当前执行流去处理这个外部事件,和异常一样,处理完后也要视情况决定是否返回原执行流继续执行,但是中断一般是跳回发生中断的下一条指令继续执行,除了某些多周期指令被中断后需要重新执行,如除法指令

2023-08-09 18:09:22 2602

原创 FPGA学习——触发器(FF)

触发器,英文名称,简称FF,,因此它的输出具有两个稳定状态——状态0和状态1。触发器有很多类型,如RS触发器、D触发器、JK触发器、T触发器等。

2023-07-31 10:25:27 3208

原创 开发一个RISC-V上的操作系统(五)—— 协作式多任务

那么,什么是多任务呢?百度百科是这样解释的:当多任务操作系统使用某种任务调度策略允许两个或更多任务并发共享一个处理器时,事实上处理器在某一时刻只会给一件任务提供服务。因为任务调度机制保证不同任务之间的切换速度十分迅速,因此给人多个任务同时运行的错觉。因此,多任务可以看作多个任务函数的执行流,但光有多个任务还不够,还要实现任务的并发执行​。

2023-07-30 10:48:58 881

原创 FPGA学习——查找表(LUT)

按照输入端口个数的不同,查找表又可具体细分为LUT2、LUT3 .... 等等,随着输入的增加,表项页必须以2的指数次幂增加。查找表的实现方式很多,当表项比较少的情况下,可以用多路复用器实现;当表项比较多的时候,可以利用RAM等大规模的存储单元实现。查找表的表项是可以配置的,也就是说我们可以用上述的两端口LUT2实现任意的两输入电路,进一步分析,但“万能”的前提是需要消耗更多的资源,因此查找表是一种。,英文全称 Look Up Table。

2023-07-29 17:30:13 2512

四路并行MDF FFT的FPGA实现

基于FPGA的FFT计算架构主要分为四种类型:顺序架构、并行架构、流水架构和阵列架构。流水结构是利用时间并行的计算方法,将重复的计算过程分解为多级进行计算,各级之间以流水的方式在时间上并行计算。 MDF架构是SDF架构的并行版本。最初的MDF架构由多个SDF架构通过变换电路连接而成。一般来说,MDF由多个相互连接的SDF路径组成,每个路径负责管理一个并行输入流。这种设计有助于有效利用寄存器的继承,节省了内存资源。 四路并行基2-DIF MDF FFT的具体架构如图 7所示,可以看到四路并行MDF FFT架构是SDF FFT的并行版本,从单个通道变为了4个通道。在前8个阶段,每个通道都相当于单个SDF在运行,每个通道的数据互不影响,在最后两阶段一起处理四路数据,输出最终结果。

2023-08-14

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除