中断处理

一次由缺页中断引发的旅程

匆匆过客 提交于 2019-12-01 18:38:28
综述 首先,啥是页,这是针对内存来说的,现代操作系统将内存分成许许多多的 页 (逻辑上),一页的大小默认是4KB(Linux)。操作系统在运行程序时,不会一次性将程序所需的页都加载到内存中(没有这个必要)。 所以当操作系统运行程序所要用到页没有加载到 物理内存 时,就会触发一个来自CPU的 缺页 错误,操作系统捕捉到这个错误,然后将对应的页加载到物理内存中。 上面的概述涉及到几个概念:页、物理内存、中断。 页和段 除了将内存划分成页之外,其实还可以划分成段,一段内存就存放程序所需要的全部数据和指令。这种情况下是不会产生缺少数据或者指令的情况的。不过却会引发一个新的问题:内存碎片和内存不足。如下图所示: 当然也有办法解决,就是 内存交换 ,将python程序占用的256M先写到硬盘上,再从硬盘上读回内存,不过是从接着已占用的512M写。这样我们就可以空间连续的256M来加载新的程序X了。看来很完美,不需要页的 出场了,实际上大家都知道,硬盘的访问速度相比内存来说,慢了可是几个数量级。频繁的读写磁盘,性能肯定上不去的,所以才有页的出现。 异常和中断 程序不仅简单的执行指令,更多的还需要和外部的输入输出打交道。另一方面,程序在运行过程中,还会遇到各种上异常情况,比如除0,位溢出,甚至我们自己也可以让程序招聘异常 异常,其实是一个硬件和软件组合在一起的处理过程,异常的前半生:发生和捕捉

ARM中断深入分析几点

强颜欢笑 提交于 2019-12-01 17:20:22
ARM中断深入分析几点 1.程序发生中断后,是如何跳转到中断程序里面的? 2.执行完中断后,如何返回到原来被打断的地方接着执行呢? 3.ARM处理器的流水线结构对中断返回地址的计算有什么影响? 4.ARM7,ARM9处理器流水线结构一个是3级一个是5级,为什么中断返回地址是相同的? 5.ARM启动后是SVC模式,发生中断后进入什么模式? 6.发生中断后,哪些事情是需要ARM自动完成?哪些是需要编程实现的?   读书留痕,思考留果 1.程序发生中断后,是如何跳转到中断程序里面的?   首先要执行完当前指令!然后自动完成以下事情:   CPSR---->SPSR_irq(IRQ模式)(逆过程不能自动完成)   PC-4 ----> R14_irq   PC <---- 0X00000018(irq中断向量表的入口地址) 程序员需要补充做的事情有: R0----R12,和LR的值入栈。 用户处理函数放在irq中断向量表的入口地址,以供跳转。 2.执行完中断后,如何返回到原来被打断的地方接着执行呢?   恢复R0--R12,出栈;   R14-4 ----> PC   SPSR_irq---->CPSR 3.ARM处理器的流水线结构对中断返回地址的计算有什么影响?   pc始终指向当前正在执行指令的下两条指令处(PC-8).执行完当前的,就变为PC-4。保存的就是PC-4. 4.ARM7

单片机成长之路(51基础篇) - 026 基于stm89c52之单片机看门狗

早过忘川 提交于 2019-12-01 17:09:50
基于stc89c52的看门狗,代码如下: main.c 1 #include "stc89c5x_Quick_configuration.h"    // 自定义头文件 2 #include "data.h" 3 #include "bsp_gpio.h" 4 #include "bsp_wdt.h" 5 6 void init_OS_Time(void){ 7 DATA.Time.Time_Interrupt = 1; // 设置步长 8 DATA.Time.Interrupt_count = 0; // 设置单位步数 9 DATA.Time.Time_s = 0; // 时间 s 10 DATA.Time.Time_h = 0; // 时间 h 11 DATA.Time.Time_day = 0; // 时间 日 12 DATA.Time.Time_month = 0; // 时间 月 13 DATA.Time.Time_year = 0; // 时间 年 14 } 15 16 void main(void){ 17 init_OS_Time(); 18 init_WDT(); 19 while(1){ 20 ; 21 } 22 } bsp_wdt.h 1 #ifndef __BSP_WDT_H_ 2 #define __BSP_WDT_H_ 3 4 /*-----------

stm32串口收发导致的死机

丶灬走出姿态 提交于 2019-12-01 16:58:21
stm32串口收发导致的死机 很久以前有偶尔遇到过串口死机的情况,那是当时的我写出来的代码自己都觉得有问题,也就没注意。用了stm32做项目以后也就没遇到过了,今天做了个高压测试,每5ms定时发送一次,结果挂了,而且仿真只能看到程序在乱飞。这回认真做了测试分析,得到以下结论。 我认为之所以导致死机的原因是串口中断没办法及时处理外设缓存的数据。因此,在使用串口应注意: 串口中断中,不管是什么数据,先收了再说。 条件允许的话,串口中断设置为抢占优先级。 同等级中断函数中,尽量不占用过多的时间。 来源: https://www.cnblogs.com/wcw12580/p/11694449.html

icm20948

与世无争的帅哥 提交于 2019-12-01 13:49:16
简介: icm20948由两个裸片(die)构成,QFN封装(3x3x1mm 24PIN)。一个die集成3轴陀螺仪,3轴加速计和一个DMP,另一个die集成旭化成的AK09913的3轴磁力计。它支持以下功能: 1.512字节的FIFO(FIFO的大小根据DMP功能集而定) 2.运行时校准功能 3.增强的FSYNC功能,可改善类似EIS(视频防抖)应用的时序 陀螺仪可编程量程范围:±250dps ±500dps ±1000dps ±2000dps 加速计可编程量程范围:±2g ±4g ±8g ±16g 这两个传感器的灵敏度初始化(工厂校准)降低了产线的校准要求。 其他关键功能,片上16位ADC,可编程数字滤波器,内嵌的温度传感器以及可编程中断。设备功能接口有I2C和SPI,VDD操作电压范围1.71V到3.6V以及一个独立的数字IO供电,VDDIO从1.71V到1.95V。 与设备上的寄存器进行通信是通过I2C(高达100KHZ-标准或400KHZ-快速),或者高达7MHZ的SPI。 应用场景: 1.智能手机和平板 2.可穿戴传感器 3.IoT场景 4.无人机 功能: 1.陀螺仪: ① 输出X,Y和Z轴方向的角速度,可编程范围±250dps ±500dps ±1000dps ±2000dps以及集成的16位ADC ② 自定义的ODR;自定义的低通滤波 ③ 自检 ④输出数据率:

【TencentOS tiny】深度源码分析(2)——调度器

百般思念 提交于 2019-12-01 13:43:37
温馨提示:本文不描述与浮点相关的寄存器的内容,如需了解自行查阅(毕竟我自己也不懂) 调度器的基本概念 TencentOS tiny 中提供的任务调度器是基于优先级的全抢占式调度,在系统运行过程中,当有比当前任务优先级更高的任务就绪时,当前任务将立刻被 切出 ,高优先级任务 抢占 处理器运行。 TencentOS tiny 内核中也允许创建相同优先级的任务。相同优先级的任务采用时间片轮转方式进行调度(也就是通常说的分时调度器),时间片轮转调度仅在当前系统中 无更高优先级就绪任务 的情况下才有效。 为了保证系统的实时性,系统尽最大可能地保证高优先级的任务得以运行。任务调度的原则是一旦任务状态发生了改变,并且当前运行的任务优先级小于优先级队列中任务最高优先级时,立刻进行任务切换(除非当前系统处于中断处理程序中或禁止任务切换的状态)。 调度器是操作系统的 核心 ,其主要功能就是 实现任务的切换 ,即从就绪列表里面 找到 优先级最高的任务,然后去 执行 该任务。 启动调度器 调度器的启动由 cpu_sched_start 函数来完成,它会被 tos_knl_start 函数调用,这个函数中主要做两件事,首先通过 readyqueue_highest_ready_task_get 函数获取当前系统中处于最高优先级的就绪任务,并且将它赋值给指向当前任务控制块的指针 k_curr_task

STM32之串口DMA接收不定长数据

风流意气都作罢 提交于 2019-12-01 13:37:59
STM32之串口DMA接收不定长数据 引言 在使用stm32或者其他单片机的时候,会经常使用到串口通讯,那么如何有效地接收数据呢?假如这段数据是不定长的有如何高效接收呢? 同学A:数据来了就会进入串口中断,在中断中读取数据就行了! 中断就是打断程序正常运行,怎么能保证高效呢?经常把主程序打断,主程序还要不要运行了? 同学B:串口可以配置成用DMA的方式接收数据,等接收完毕就可以去读取了! 这个同学是对的,我们可以使用DMA去接收数据,不过DMA需要定长才能产生接收中断,如何接收不定长的数据呢? DMA简介 题外话:其实,上面的问题是很有必要思考一下的,不断思考,才能进步。 什么是DMA DMA :全称Direct Memory Access,即直接存储器访问 DMA 传输将数据从一个地址空间复制到另外一个地址空间。CPU只需初始化DMA即可,传输动作本身是由 DMA 控制器来实现和完成。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。这样的操作并没有让处理器参与处理,CPU可以干其他事情,当DMA传输完成的时候产生一个中断,告诉CPU我已经完成了,然后CPU知道了就可以去处理数据了,这样子提高了CPU的利用率,因为CPU是大脑,主要做数据运算的工作,而不是去搬运数据。DMA 传输对于高效能嵌入式系统算法和网络是很重要的。 在STM32的DMA资源 STM32F1系列

Executor线程池原理详解

时光怂恿深爱的人放手 提交于 2019-12-01 11:31:29
线程池 线程池的目的就是减少多线程创建的开销,减少资源的消耗,让系统更加的稳定。在web开发中,服务器会为了一个请求分配一个线程来处理,如果每次请求都创建一个线程,请求结束就销毁这个线程。那么在高并发的情况下,就会有大量线程创建和销毁,这就会降低系统的效率。线程池的诞生就是为了让线程得到重复使用,减少了线程创建和销毁的开销,减少了线程的创建和销毁自然的就提高了系统的响应速度,与此同时还提高了线程的管理性,使线程可以得到统一的分配,监控和调优。 线程创建和销毁为什么会有开销呢,因为我们java运行的线程是依赖于计算机内核的核心线程的。java创建的线程是用户层的线程,要依赖于线程调度去是用内核层的线程来执行,在执行销毁的时候会通过TSS在用户层和核心层的切换,这个切换就是很大的一笔开销。具体结构如下图: 线程实现方式 线程主要通过实现Runnable或者Callable接口来实现.Runnable与Callable的区别在于后者有返回值,但是前者没有返回值。 public interface Runnable { public abstract void run(); } publuic interface Callable<V>{ V call() throws Exception; } 下面我们来看一下测试代码: package com.test.excutor; import

AQS(队列同步器)

纵然是瞬间 提交于 2019-12-01 10:24:05
目录导引 :   一、简介   二、源码解析(JDK8)   三、运用示例 一、简介   1、volatile    volatile修饰的共享变量可以保证可见性和有序性(禁止指令重排序)。    2、CAS:   CAS的原理很简单,包含三个值当前内存值(V)、预期原来的值(A)以及期待更新的值(B),   如果内存位置V的值与预期原值A相匹配,那么处理器会自动将该位置值更新为新值B,返回true。否则处理器不做任何操作,返回false。   要实现这个需求,java中提供了Unsafe类,它提供了三个函数,分别用来操作基本类型int和long,以及引用类型Object public final native boolean compareAndSwapObject (Object obj, long valueOffset, Object expect, Object update); public final native boolean compareAndSwapInt (Object obj, long valueOffset, int expect, int update); public final native boolean compareAndSwapLong (Object obj, long valueOffset, long expect, long

从0开始学FreeRTOS-(任务调度)-4

岁酱吖の 提交于 2019-12-01 10:20:53
大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! 前言 FreeRTOS 是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了 FreeRTOS ,则避免不了对任务的管理,在多个任务运行的时候,任务切换显得尤为重要。而任务切换的效率会决定了系统的稳定性与效率。 FreeRTOS 的任务切换是干嘛的呢, rtos 的实际是永远运行的是具有最高优先级的运行态任务,而那些之前在就绪态的任务怎么变成运行态使其得以运行呢,这就是我们 FreeRTOS 任务切换要做的事情,它要做的是找到最高优先级的就绪态任务,并且让它获得cpu的使用权,这样,它就能从就绪态变成运行态,这样子,整个系统的实时性就会很好,响应也会很好,而不会让程序阻塞卡死。 要知道怎么实现任务切换,那就要知道任务切换的机制,在不同的 cpu(mcu) 中,触发的方式可能会不一样,现在是以Cortex-M3为例来讲讲任务的切换。为了大家能看懂本文,我就抛转引玉一下, 引用《Cortex-M3权威指南-中文版》的部分语句(如涉及侵权,请联系杰杰删除) SVC 和 PendSV SVC(系统服务调用,亦简称系统调用)和 PendSV ( Pended System Call ,可悬起系统调用),它们多用于在操作系统之上的软件开发中。 SVC 用于产生系统函数的调用请求。例如