Microcontroller和Microprocessor啥区别?
Microcontroller就是我们说的微控制器,或者说单片机,通常包括CPU和其它parts,包括程序存储器(只读存储器或者闪存), 数据存储器(随机存储器), IO, Clock等在一起。CPU通常计算能力没那么强,而且比较便宜。
Microprocessor就是我们说的微处理器,通常只包括一个计算能力很强的CPU,比较贵。它会连到外设和其它parts。
Microcontroller把CPU和memory/IO/clock这些部件集成在一个芯片上。这样做的好处有:
- Lower cost (one part replaces many parts)
- More reliable (fewer packages, fewer interconnects)
- Better performance
- Faster (信号都在一个板子上)
- Lower RF signature
注意:
https://zhuanlan.zhihu.com/p/126269758
MCU也就是单片机中几乎都是用哈佛结构,譬如广泛使用的51单片机、典型的STM32单片机(核心是ARM Cortex-M系列的)都是哈佛结构。原因1)是哈佛结构更加稳定安全,2)速度会更快一些,3)MCU的指令和数据需求量都不大,配置不高,所以内存往往使用SRAM而不使用DRAM,这样就导致它更适合哈佛结构。
PC和服务器芯片(譬如Intel AMD那些出的),ARMCortex-A系列嵌入式芯片(譬如核心是ARM CortexA8的三星S5PV210,譬如华为的麒麟970等手机芯片)等都是冯诺依曼结构。这些系统都需要大量内存,所以工作内存都是DRAM,因为他们更适合使用冯诺依曼系统。
CPU
ARM 是ARM公司开发,包括Coretx-M, Cortex-R 和 Cortex-A
Cortex-M: 定位是中低端市场,也就是我们的单片机,也叫微控制器,我们最常用的STM32F103就是Cortex-M3的内核。
Coretx-R: 定位高端实时系统,比如说医疗、工业、汽车、基带等等领域。适合做microprocessor?
Cortex-A: 定位是通用市场,典型的就是平板电脑、手机、数字电视、机顶盒、服务器、打印机等领域。大家手机里装的就是Cortex-A。
注意:Cortex-M不带MMU,所以不能跑Linux,只能跑RTOS或bare metal。
带MMU的是:Cortex-A系列、ARM9、ARM11系列;
不带MMU的是:Cortex-M系列……(STM32是M系列,没有MMU,不能运行Linux,只能运行一些UCOS、FreeRTOS等等)。
AVR: 是ATMEL公司开发,更便宜。像Arduino UNO的MCU就是ATmega328 (Atmel的芯片)。
What is difference between ARM and AVR?
AVR and ARM comes under the family of micro-controller. But ARM can be used as both Microcontroller or as Microprocessor. ARM micro-controller and AVR micro-controller differs from each other in terms of different architecture and different sets of instruction, speed, cast, Memory, Power Consumption, Bus Width etc.
ARC: 是Synopsys开发的高端嵌入式应用处理器。
微控制器 MicroController和开发板
STM32 是意法半导体 STMicroelectronics开发,基于Cortex-M。我的理解是STM32 microcontroller 在Cortex-M之上还集成了Flash和SRAM memory等。适合用于消费类、工业控制、机器人、医疗设备、汽车等应用程序。比ESP32具有更多的通用性。
ESP32 是乐鑫科技Espressif公司开发(好像是国货?),基于Tensilica processor(这个是Cadence开发的CPU,不是ARM)。通常用于物联网设备,家庭自动化,Wi-Fi控制,更多是作为一个蓝牙、WiFi的中继功能。
MSP430 是德州仪器TI开发,16位低功耗单片机,适合低功耗嵌入式设备。有专门的TI CCS调试软件跟它配套。
Raspberry Pi加粗样式
Arduino: Arduino社区支持8位的AVR系列MCU(来自Atmel),以及32位的ARM Cortex-M系列和ESP系列MCU。像Arduino UNO的MCU就是ATmega328 (Atmel的芯片)。
关于ARM
- AMBA (Advanced Microcontroller Bus Architecture) 是高级微处理器总线架构
- AMBA 用到的总线有
AHB (Advanced High-performance Bus) 高级高性能总线
ASB (Advanced System Bus) 高级系统总线----用的很少
APB (Advanced Peripheral Bus) 高级外围总线
AXI (Advanced eXtensible Interface) 高级可拓展接口 - AHB主要是针对高效率、高频宽及快速系统模块所设计的总线,它可以连接如微处理器、芯片上或芯片外的内存模块和DMA等高效率模块;
APB主要用在低速且低功率的外围,可针对外围设备作功率消耗及复杂接口的最佳化;APB在AHB和低带宽的外围设备之间提供了通信的桥梁,所以APB是AHB或ASB的二级拓展总线 ;
AXI:高速度、高带宽,管道化互联,单向通道,只需要首地址,读写并行,支持乱序,支持非对齐操作,有效支持初始延迟较高的外设,连线非常多; - AHB与AXI、APB的区别与联系
AHB是先进的高性能总线,AXI是先进的可扩展接口,APB是高级外围总线;
AHB和APB都是单通道总线,不支持读写并行;而AXI是多通道总线,总共分为五个通道,能够实现读写并行;
AHB和AXI都是多主/从设备,且通过仲裁机制实现总线控制权的分配;而APB是单主设备多从设备,其主设备就是APB桥,不具有仲裁机制;
在数据操作方面,AHB和AXI支持突发传输,APB不支持;此外,AXI支持数据的非对齐操作,AHB不支持; - PC值=当前程序执行位置+8;
当突然发生中断的时候,保存的是PC-8+4 = PC-4 (即下一条指令的地址)。
中断和轮询
- 如果IO任务频繁发生,可以考虑轮询,这样CPU效率比较高,而且实现简单。
- 如果IO任务偶尔发生,可以考虑中断,这样可以有low-power,因为CPU大部分时间可能在睡觉。
- 如果IO任务需要马上响应,可以考虑中断。
关于中断: - 基于时钟的中断,优先级要很高
- https://www.zhihu.com/question/27933543
非阻塞式轮询,请加等待。//不加等待的话, CPU就会满负荷
不想加等待,请用阻塞式调用。//加了阻塞,CPU可以调度其他进程
同时轮询多个事件,用异步事件处理机制。//只有异步处理机制能够在短时间内处理庞大的请求数量而且不过分占用资源,多线程/多进程机制是无法做到的。 - 有的资料说轮询实时性更好,有的说中断实时性更好。我的想法是中断应该是实时性更好一些。特别是如果轮询中有等待或阻塞的话。
Cache invalidate vs Cache flush:
A cache invalidate simply marks the cache contents as invalid. So the next time you access data, you will get what is in memory.
A cache flush writes back data from cache into memory.
These two will differ only when memory contents get out of sync with cache contents, which will happen only when you have DMA or a 2nd processor writing to the same memory location.
Some examples:
- DMA transfer data from DDR memory to HW buffer.
DDR buffer should be flushed before DMA. Driver buffer is non cacheable so no need for invalidation. - DMA transfer data from HW buffer to DDR (HW received data and want to make it available for CPU)
DDR buffer should be invalidated before or after (look NOTE below for details) DMA transfering to prevent CPU to use ‘old’ data from cache. Flushing of HW buffer is redundant. - DMA transfer from DDR into another region of DDR.
‘Source’ buffer should be flushed, ‘Destination’ buffer should be invalidated. So valid data is in memory for DMA before transfer, and CPU doesn’t take a ‘dirt’ from cache after DMA did it’s job.
https://blog.itpub.net/70005277/viewspace-2790455/
CPU需要进行DMA写操作,也就是把内存中的buffer A写入到设备的FIFO A里面,那么有可能cache里面的数据还没有完全写入到内存的buffer A中,那这时候启动DMA的话,最终传递到设备FIFO A的数据其实不是CPU想写的,因为还有一部分数据早 潜伏在cache A中没有 sync到内存里。这个场景有点类似,我们拷贝内存到U盘,马上拔出,然后发现U盘没有东西。
我们来看一下DMA读的情况,CPU想把设备的FIFO B的数据读到内存buffer B中。那如果在开启DMA传输的时候没有去把内存buffer B的相应的cache invalid的话,那么DMA把数据从FIFO B到了内存Buffer B之后,CPU去读这个内存Buffer B的数据,那么会把之前的 残留在cache line的内容 先读到了CPU,那CPU其实是没有读到最新的FIFO B的数据的。
总结:
DMA写,需要flush cache line。
DMA读,需要invalid cache line。
嵌入式系统提高可靠性方法:
- 加Lock for race condition
- 加Watch dog及早发现错误。可以加一个专门的watch dog task,优先级设很高。
关于阻塞/非阻塞/同步/异步 IO模型:
我认为异步就是用回调函数。
比较好的链接有:
https://www.cnblogs.com/f-ck-need-u/p/7624733.html
https://www.junmajinlong.com/coding/IO_Model/
同步通信和异步通信
不要跟上面的同步/异步 IO搞混了。
这里的同步通信是指通信双方有时钟同步,异步通信是指通信双方没有时钟同步,靠发送数据帧里面的开始/终止 flag来同步
同步串行通信协议: SPI,SATA
异步串行通信协议: I2C (数据帧有起始/终止位), UART(双方协商波特率), CAN(从隐性到显性的下降沿可以用作同步,有硬同步和重同步两种)
串行通信和异步通信
大部分都是串行通信,好像只有打印机的通信是异步的?
下面这个表不错,来自https://blog.csdn.net/qq_18677445/article/details/102469255
SPI: SPI通讯接口的扩展常用于高速的或大数据容量的功能外设拓展,譬如WiFi、Ethernet、SD/TF卡、大容量高速数据存储器等。与I2C通讯接口相比, 虽然SPI通讯接口的拓扑需要占用更多个I/O引脚用于片选或握手信号,但SPI接口的时钟频率远高于I2C。此外,SPI通讯接口支持全双工通讯,但I2C是半双工的。 我们直到SD/TF卡的存储器容量可以按千兆字节(即GB)来计量,而NOR结构型FlashROM的存储容量仅以MB计量,两者的存取速度相差很大(后者速度更快), 而且这两类存储器都采用SPI或QSPI等接口。大容量存储器不使用I2C通讯接口的另一个原因是,I2C的总线寻址和大容量存储器的地址管理会造成数据存取过程中地址信息的传输将占用大量时间, 数据的存取效率极地。
SPI虽然仅支持主从通讯模式,但数据传输速度几乎是I2C的1000倍。
I2C: 音视频设备、视觉传感器和点阵图形显示器接口中常用I2C或SMBus作为这些设备的参数配置通讯接口。好像I2C和SPI不同的地方还有I2C有应答机制(发送后的第9个周期要收到应答?),而SPI没有。
注意: SPI 只可能有一个master,可以有多个slave。
I2C可以有多个master和多个slave。
关于锁
- spinlock主要用于多核之间的同步,semaphore/mutex/disable interrupt主要用于同一个核上面不同task之间的同步
- spinlock可以用于interrupt handler,semaphore/mutex不可以,semaphore/mutex是基于busy/wait,task会sleep,没有办法唤醒。
- spinlock在多核里面是真正的自旋锁,在单核可以抢占的系统里面就相当于disable interrupt。在单核非抢占的系统里面spinlock没有意义,因为没有谁唤醒它,所以单核非抢占系统里面spinlock()实际上是空。
- 自旋锁实际上是忙等锁
https://blog.csdn.net/jfkidear/article/details/11254133
当锁不可用时,CPU一直循环执行“测试并设置”该锁直到可用而取得该锁,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。因此,只有在占用锁的时间极短的情况下,使用自旋锁才是合理的。当 临界区很大或有共享设备的时候,需要较长时间占用锁,使用自旋锁会降低系统的性能。 - 自旋锁可能导致系统死锁
https://blog.csdn.net/jfkidear/article/details/11254133
引发这个问题最常见的情况是 递归使用一个自旋锁,即如果一个已经拥有某个自旋锁的CPU 想第二次获得这个自旋锁,则该CPU 将 死锁。此外,如果进程获得自旋锁之后再阻塞,也有可能导致 死锁的发生。copy_from_user()、copy_to_user()和 kmalloc()等函数都有可能引起阻塞,因此在自旋锁的占用期间不能调用这些函数。 - **排它锁(mutex)**只能允许一个读或写。
**读写锁(rwlock)**允许多读和一写。
rcu允许多读和多写。其中多读之间没有锁,多写之间有锁。
//from Linux设备驱动开发详解:基于最新的Linux4.0内核/Linux设备驱动开发详解:基于最新的Linux4.0内核.pdf
rcu可以看作读写锁的高性能版本,相比读写锁,RCU的优点在于既允许多个读执行单元同时访问被保护的数据,又允许多个读执行单元和多个写执行单元同时访问被保护的数据。但是,RCU不能替代读写锁,因为如果写比较多时,对读执行单元的性能提高不能弥补写执行单元同步导致的损失。因为使用RCU时,写执行单元之间的同步开销会比较大,它需要延迟数据结构的释放,复制被修改的数据结构,它也必须使用某种锁机制来同步并发的其他写执行单元的修改操作。
**顺序锁(seqlock)**是对读写锁的一种优化,若使用顺序锁,读执行单元不会被写执行单元阻塞,也就是说,读执行单元在写执行单元对被顺序锁保护的共享资源进行写操作时仍然可以继续读,而不必等待写执行单元完成写操作,写执行单元也不需要等待所有读执行单元完成读操作才去进行写操作。但是,写执行单元与写执行单元之间仍然是互斥的,即如果有写执行单元在进行写操作,其他写执行单元必须自旋在那里,直到写执行单元释放了顺序锁。
对于顺序锁而言,尽管读写之间不互相排斥,但是如果读执行单元在读操作期间,写执行单元已经发生了写操作,那么,读执行单元必须重新读取数据,以便确保得到的数据是完整的。所以,在这种情况下,读端可能反复读多次同样的区域才能读到有效的数据。
个人理解。用读写锁的时候,读写是互斥的,即写的时候是不能读的,读的时候也是不能写的。而用顺序锁的时候,读写不互斥,即写的时候可以读,读的时候也可以写。但如果读执行单元在读操作期间,写执行单元已经发生了写操作,那么,读执行单元必须重新读取数据,以便确保得到的数据是完整的。
7.自旋锁和互斥体选用的3项原则。
//from Linux设备驱动开发详解:基于最新的Linux4.0内核/Linux设备驱动开发详解:基于最新的Linux4.0内核.pdf
a)当锁不能被获取到时,使用互斥体的开销是进程上下文切换时间,使用自旋锁的开销是等待获取自旋锁(由临界区执行时间决定)。若临界区比较小,宜使用自旋锁,若临界区很大,应使用互斥体。
b)互斥体所保护的临界区可包含可能引起阻塞的代码,而自旋锁则绝对要避免用来保护包含这样代码的临界区。因为阻塞意味着要进行进程的切换,如果进程被切换出去后,另一个进程企图获取本自旋锁,死锁就会发生。
c)互斥体存在于进程上下文,因此,如果被保护的共享资源需要在中断或软中断情况下使用,则在互斥体和自旋锁之间只能选择自旋锁。当然,如果一定要使用互斥体,则只能通过mutex_trylock()方式进行,不能获取就立即返回以避免阻塞。
关于sensor传感器系统的设计
https://www.linkedin.com/advice/1/how-do-you-design-implement-camera-sensor#write-the-software
- sensor的选型(low power consumption, cost, resolution, pixel size, dynamic range, sensitivity, noise, and compatibility with your camera platform,还有电气属性和接口协议等。
- firmware design (sensor side)
包括sensor’s basic functions, such as initialization, configuration, power management, exposure control, gain control, readout, and data transfer. You need to follow the sensor’s programming guide, which provides instructions and examples on how to write the firmware and use the sensor’s registers, timers, interrupts, and other features. - software design (host side)
The software is the high-level software that runs on the camera’s main processor or system-on-chip (SoC). It interacts with the sensor’s firmware through an interface, such as I2C, SPI, or MIPI CSI. It performs tasks such as image processing, compression, encoding, storage, display, and transmission. The software is usually written in C, C++, or Python, and uses libraries and frameworks that support image processing, such as OpenCV, GStreamer, or TensorFlow. You need to follow the camera’s software development kit (SDK), which provides APIs and documentation on how to write the software and use the camera’s hardware and software resources.
Bare Metal vs RTOS
什么时候用Bare Metal:
- Bare metal firmware development thrives in real-time systems where accurate timing and responsiveness are essential.
- Bare metal firmware development is especially beneficial in resource-restricted situations, such as embedded systems with confined memory and processing capacity.
- Bare metal firmware development is a good solution for unique or highly specialized hardware platforms. These platforms frequently need low-level modification and control since they could have distinctive features, user interfaces, or communication protocols.
MQTT vs Websocket
都是基于TCP长链接。MQTT好像更适合于短消息的发送。
通信可靠性
- 连接可靠 - ACK机制
- 传输可靠 - heartbeat
关于纠错码
- Checksum 只能查出1-bit的错误,CRC可以查出2-bit的错误。
- ECC 呢?
关于SPI, I2C, UART和USB。
- SPI, I2C和UART都是串行。 SPI和I2C是同步,因为有CLK信号来同步。UART是异步,因为没有CLK信号,靠的是波特率。
USB好像也是串行异步,不过USB的音频传输好像可以自己生成时钟来同步? - SPI一般要4根线(片选,数据发送/接收,时钟),I2C一般要2根线(数据和时钟)。UART一般2根线(数据发送和接收)。注意:可能还有根地线。
USB 2.0 有4根线: 一对差分线(D+、D-)传送信号,另一对(VBUS、电源地)传送+5V的直流电。USB 3.0有8根线,除VBUS、电源地之外,其余3对均为数据传输线路。其中保留了D+与D-这两条兼容USB 2.0的线路,新增了SSRX与SSTX专为USB 3.0所设的线路。 - 一般主控SoC作为SPI的“主”,而外设作为SPI的“从”。
- 假设发送一个8bit的字节,UART是从低位到高位发送,SPI和I2C都是从高位到低位发送。
- SPI没有开始位,结束位和应答位,效率比SPI高。
- SPI 4种工作模式
from https://www.bilibili.com/video/BV1UG411L7pH/?vd_source=607d67fdd1e8f6a823c13fec42a1374d
关于ARM
1.在Linux里面,ARM处理器分为7种工作模式。
·用户模式(usr):大多数应用程序运行在用户模式下,当处理器运行在用户模式下时,某些被保护
的系统资源是不能访问的。
·快速中断模式(fiq):用于高速数据传输或通道处理。
·外部中断模式(irq):用于通用的中断处理。
·管理模式(svc):操作系统使用的保护模式。
·数据访问中止模式(abt):当数据或指令预取中止时进入该模式,可用于虚拟存储及存储保护。
·系统模式(sys):运行具有特权的操作系统任务。
·未定义指令中止模式(und):当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件
仿真。
ARM Linux的系统调用实现原理是采用swi软中断从用户(usr)模式陷入管理模式(svc)。
21. 在Linux里面,x86处理器包含4个不同的特权级,称为Ring 0~Ring 3。在Ring0下,可以执行特权级指令,对
任何I/O设备都有访问权等,而Ring3则被限制很多操作。
22. 内核空间和用户空间这两个名词用来区分程序执行的两种不同状态,它们使用不同的地址空间。
Linux只能通过系统调用和硬件中断完成从用户空间到内核空间的控制转移
关于DMA
关于CPU context switch:
https://mdnice.com/writing/9af582fd2cd84c098c4a615b03fb2135
有哪些类型的 cpu context switch?
根据触发条件的不同,主要有三种类型的上下文切换:
多任务处理 Multitasking
中断信号处理 Interrupt handling
用户态和内核态切换 User and kernel mode switching: 系统调用
系统调用触发的 CPU 上下文切换,也经常被称为 “特权模式切换”(privileged mode switch),与多任务 multitasking 进程切换触发的 CPU 上下文切换,有很多不同点:
系统调用触发的 CPU 上下文切换,切换前后执行的是用一个进程,而多任务 multitasking 进程切换触发的 CPU 上下文切换,切换前后执行的是不同的进程;
多任务 multitasking 进程切换触发的 CPU 上下文切换,涉及到用户空间的资源包括虚拟内存,栈和全局变量 (virtual memory, stacks and global variables),也涉及到内核空间的资源,比如内核栈和寄存器 (kernel stacks and registers),其状态数据比系统调用涉及的状态数据要大很多;
系统统调用触发的 CPU 上下文切换,相对于多任务处理触发的 CPU 上下文切换,因为其状态数据更小,其成本也要小很多。
几个名词不要混淆
- RCU: read-copy-update (RCU) is a synchronization mechanism that avoids the use of lock primitives while multiple threads concurrently read and update elements that are linked through pointers and that belong to shared data structures (e.g., linked lists, trees, hash tables).
linux内核中有一种叫做RCU(Read-Copy Update)数据共享策略跟COW十分相似,唯一不同在于RCU的新旧数据替换同过特定的回调(callback)机制被动执行,而不是由写操作进程自助完成。 - COW: Copy-on-write (CoW) is a resource management technique in Linux that allows the parent and child processes to share the same memory pages. It facilitates multiple processes to share the same memory pages until one process modifies them. Upon modification, the operating system creates a duplicate copy of the original page, which is exclusively granted to the modifying process, while the other processes continue to share the original page.
COW的本质就是,在并发的环境中,如果想要更新某个对象,首先将它拷贝一份,在这个拷贝的对象中进行修改,最后把指向原对象的指针指回更新好的对象。
个人理解:RCU是Linux里面的一种数据共享策略,COW是一种非常经典的优化思想,在很多方面上都有具体的应用。
//from Linux设备驱动开发详解:基于最新的Linux4.0内核/Linux设备驱动开发详解:基于最新的Linux4.0内核.pdf
例如Linux OS利用COW思想实现lazy copy以节省资源提高性能 (比如说新建进程或线程就可以用copy-on-write 的策略优化,也就是并不真正复制父进程的内存空间,而是等到需要写操作时才去复制。所以 Linux 中新建进程和新建线程都很迅速),java中利用COW思想实现集合的读写分离的并发策略(CopyOnWriteArrayList & CopyOnWriteArraySet),以提高性能且保证并发安全,redis中的数据持久化策略都使用了cow思想,Kafka中利用COW思想实现消息Map,避免更新key-value的时候阻塞住高频的读操作,实现无锁的效果,优化线程并发的性能,等等。 - Zero copy:
https://www.junmajinlong.com/coding/IO_Model/
网络数据一定要从kernel buffer复制到app buffer再复制到send buffer吗?
不是。如果进程不需要修改数据,就直接发送给TCP连接的另一端,可以不用从kernel buffer复制到app buffer,而是直接复制到send buffer。这就是零复制技术。
零复制的概念是避免将数据在内核空间和用户空间进行拷贝。主要目的是减少不必要的拷贝,避免让CPU做大量的数据拷贝任务。
零拷贝技术有:
a) MMAP
b) sendfile()
c) splice()
d) tee() - RDMA:
某些硬件可以完成TCP/IP协议栈的工作,数据可以不经过socket buffer,直接在app buffer和硬件之间传输数据,RDMA技术就是在此基础上实现的。 - Cache write through:
- Cache write back:
几个信号的区别:
CTRL + Z: SIGSTOP NO.19 Suspends a process by sending it the SIGSTOP signal, which the program cannot intercept. This keeps the program in the background, allowing it to be resumed later.
CTRL + C: SIGINT No.2 In the Linux terminal, Ctrl + Z suspends a process, while Ctrl + C forcefully terminates a process
**CTLR + **: SIGQUIT No.3 类似SIGINT?
CTRL + S: No Signal
CTRL + Q: No Signal
kill a task: SIGTERM NO.15
UNIX/Linux/Mac OS 系统中,Ctrl+D 代表输入结束。//但是对应什么信号?
SIGINT SIGTERM SIGKILL是什么区别?
https://www.jianshu.com/p/f6dfbf51c541
a. SIGINT SIGTERM SIGKILL都是结束/终止进程
b. SIGINT信号为ctrl+c发送出来的信号,该信号只能结束前台进程,信号被当前进程树接收到,也就是说,不仅当前进程会收到信号,它的子进程也会收到;
c. SIGTERM可以被阻塞,kill不加任何参数的时候发送的就是这个信号,只有当前进程收到信号,子进程不会收到。如果当前进程被kill了,那么它的子进程的父进程将会是init,也就是pid为1的进程;
d. SIGKILL是不能被捕获的,程序收到这个信号后,一定会退出。这就是kill -9一定能保证将程序杀死的原因。
关于中断:
参考https://mp.weixin.qq.com/s/pe9dgVLt0qK9lToHwmLXXg
关于短时间内来多个中断,后面的中断能否保存下来的问题。我的理解是保存不了。
有两个做法:
- 在进入中断的时候关闭中断,这样以后来的中断都不会被处理了。当然,中断处理程序执行时间要短,这里我们可以用中断上半部和下半部来加以优化。上半部就是处理比较及时的事情,下半部处理比较耗时的操作。
- 在进入中断的时候,先清除当前的中断标识位,然后去做处理,如果在处理过程中又有中断产生了,中断标志位就会置位,那在退出中断后又会重新进入中断。这样,就可以起到缓存 1 个中断的目的,相当于有一个buff,可以处理2次中断。
注意:一般不会有什么cache来保存进入第一个中断后,接下来的中断。目前没有芯片实现缓存,中断只有已触发标志和已清除标志,并没有触发了几次的信息。缓存是软件的思想,CPU部分不会考虑这么低级的事情。
注意:软中断和软件中断完全是两个东西。https://zhuanlan.zhihu.com/p/360683396
1)软中断(softIRQ),即中断下半部机制。ISR运行时间不易过长,linux将中断中的一部分逻辑推后执行,这就是softIRQ,它完全由软件实现;
2)软件中断(Software Interrupt),从软件中断指令而来。在32位x86中,为了实现linux用户态到内核态的切换,linux使用软中断指令“int 0x80”来触发异常,切换CPU特权级,实现系统调用。
关于CS, IP 和 PC:
CS: code segment代码段寄存器。
IP: instruction pointer指令指针寄存器。
PC: programme counter程序计数器。
代码段CS的偏移量在 IP 寄存器中。CS:IP 就等于PC的值。
数据段DS的偏移量会放在通用寄存器中。
Acronym
ALSA: Advanced Linux Sound Architecture
ASIC:
COW: Copy on write
DCE: digital communication device?
DTE: digit terminal device?
GPIO:
I2C:
IDT: interrupt driven table
OTP: one-time programming
RCU: read-copy-update
SPI: Serial Peripheral Interface
UART: