中断处理

NRF24L01模块----6通道通讯测试

偶尔善良 提交于 2019-11-30 02:50:49
一、MCU与NRF24L01通讯 采用SPI通讯协议,速率最大为10M,与普通SPI元器件稍有不同的是,多了一个CE引脚,用来开启接收、发送,以及使器件进入待机模式。具体看IC DATASHEET说明。 写寄存器指令格式为 :1、SPI写寄存器地址 + 0x20 2、SPI写参数 读寄存器指令格式为 :1、SPI写寄存器地址 2、SPI读参数 但少数几个指令,只需写入一个参数,如: 读STATUS寄存器 : 不能使用NOP指令,读取出来参数不正确。 应使用读普通寄存器的方式,STATUS寄存器地址为0x07; 二、数据的发送 当设置芯片的寄存器,“CE”引脚需要为低电平。 用到以下几个寄存器: 1、将接收端地址写入发送地址寄存器“ TX_ADDR ” 2、将接收端地址写入PIPE0通道地址寄存器“ RX_ADDR_P0 ”,开启自动应答后,PIPE0将接收接收端的应答信号。 3、使能“EN_AA”寄存器开启自动应答,使能“ EN_RXADDR ”中PIPE0对应的bit。 4、设置重发寄存器“ SETUP_RETR ”,设置重发次数以及时间间隔。 5、设置发送频道的频率“ RF_CH ”,以及发送功率、速率“ RF_SETUP ” 6、设置配置寄存器“ CONFIG ”,开启中断以及设置发送。 如果以上寄存器设置完毕,拉低“CE”将需要发送的数据通过“ WR_TX_PLOAD

STM32驱动NRF24L01

烈酒焚心 提交于 2019-11-30 02:46:55
前言: 为了方便查看博客,特意申请了一个公众号,附上二维码,有兴趣的朋友可以关注,和我一起讨论学习,一起享受技术,一起成长。 1. 简介 NRF24L01是 nordic 的无线通信芯片,它具有以下特点: 1) 2.4G 全球开放的 ISM 频段(2.400 - 2.4835GHz),免许可证使用; 2)最高工作速率 2Mbps,高校的 GFSK 调制,抗干扰能力强; 3) 125 个可选的频道,满足多点通信和调频通信的需要; 4)内置 CRC 检错和点对多点的通信地址控制; 5)低工作电压(1.9~3.6V),待机模式下状态为 26uA;掉电模式下为 900nA; 6)可设置自动应答,确保数据可靠传输; 7)工作于EnhancedShockBurst 具有Automatic packet handling,Auto packet transaction handling ,可以实现点对点或是 1 对 6 的无线通信,速度可以达到 2M(bps),具有可选的内置包应答机制,极大的降低丢包率。 8)通过 SPI 总线与单片机进行交互,最大通信速率为10Mbps; 1.1 结构框图 如图右侧为六个控制和数据信号,分别为 CSN、 SCK、 MISO、 MOSI、 IRQ、 CE。 信号线 功能 CSN 芯片的片选线, CSN 为低电平芯片工作 SCK 芯片控制的时钟线(SPI 时钟)

并发编程之线程创建到销毁、常用API

五迷三道 提交于 2019-11-30 01:49:29
  在前面一篇介绍了线程的生命周期【 并发编程之多线程概念 】,在本篇将正式介绍如何创建、中断线程,以及线程是如何销毁的。最后,我们会讲解一些常见的线程API。 线程创建   Java 5 以前,实现线程有两种方式:扩展java.lang.Thread类,实现java.lang.Runnable接口。这两种方式都是都是直接创建线程,而每次new Thread都会消耗比较大的资源,导致每次新建对象时性能差;而且线程缺乏统一管理,可能无限制新建线程,相互之间竞争,很可能占用过多系统资源导致死机或OOM。同时,new Thread的线程缺乏更多功能,如定时执行、定期执行、线程中断。   Java 5开始,JDK提供了4中线程池(newFixedThreadPool、newCachedThreadPool、newScheduledThreadPool、newSingleThreadExecutor)来获取线程。这样做的好处是:可以重用已经存在的线程,减少对象创建、消亡的开销,性能佳;而且线程池可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。通过特定的线程池也可以实现定时执行、定期执行、单线程、并发数控制等功能。 创建线程的代码实现 扩展java.lang.Thread类 自定义一个类继承java.lang.Thread 重写Thread的run()

线程池

ぃ、小莉子 提交于 2019-11-29 22:27:47
第一.线程的含义 在 Java 中,如果每个请求到达就创建一个新线程,创建和销毁线程花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。 如果在一个 Jvm 里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足为了解决这个问题,就有了线程池的概念, 线程池的核心逻辑是提前创建好若干个线程放在一个容器中。如果有任务需要处理,则将任务直接分配给线程池中的线程来执行就行,任务处理完以后这个线程不会被销毁, 而是等待后续分配任务。同时通过线程池来重复管理线程还可以避免创建大量线程增加开销。 第二.线程池的优势 1. 降低创建线程和销毁线程的性能开销 2. 提高响应速度,当有新任务需要执行是不需要等待线程创建就可以立马执行 3. 合理的设置线程池大小可以避免因为线程数超过硬件资源瓶颈带来的问题 第三.线程池的API 只需要直接使用Executors 的工厂方法,就可以使用线程池: newFixedThreadPool: 返回一个固定数量的线程池,线程数量不变,当有一个任务的提交时,若线程池 空闲,则立即执行,若没有,则会被暂缓在一个任务队列中,等待有空闲的线程去执行。 public class ExecutorsTest implements Runnable{ public static void main(String[]

CPU上下文切换

风流意气都作罢 提交于 2019-11-29 16:51:42
进程在竞争 CPU 的时候并没有真正运行,为什么还会导致系统的负载升高呢?CPU 上下文切换就是罪魁祸首。 我们都知道,Linux 是一个多任务操作系统,它支持远大于 CPU 数量的任务同时运行。当然,这些任务实际上并不是真的在同时运行,而是因为系统在很短的时间内,将 CPU 轮流分配给它们,造成多任务同时运行的错觉。 而在每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好CPU 寄存器和程序计数器(Program Counter,PC)。 CPU 寄存器,是 CPU 内置的容量小、但速度极快的内存。而程序计数器,则是用来存储 CPU 正在执行的指令位置、或者即将执行的下一条指令位置。它们都是 CPU 在运行任何任务前,必须的依赖环境,因此也被叫做 CPU 上下文 。 知道了什么是 CPU 上下文,我想你也很容易理解 CPU 上下文切换 。 CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来, 然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。 而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度执行时再次加载进来。这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。 根据任务的不同 ,CPU

IO模型(epoll)--详解-01

主宰稳场 提交于 2019-11-29 15:35:32
写在前面   从事服务端开发,少不了要接触网络编程。epoll作为linux下高性能网络服务器的必备技术至关重要,nginx、redis、skynet和大部分游戏服务器都使用到这一多路复用技术。   本文会从网卡接收数据的流程讲起,串联起CPU中断、操作系统进程调度等知识;再一步步分析阻塞接收数据、select到epoll的进化过程;最后探究epoll的实现细节。目录: 一、从网卡接收数据说起 二、如何知道接收了数据? 三、进程阻塞为什么不占用cpu资源? 四、内核接收网络数据全过程 五、同时监视多个socket的简单方法 六、epoll的设计思路 七、epoll的原理和流程 八、epoll的实现细节 九、结论 一、从网卡接收数据说起   下图是一个典型的计算机结构图,计算机由CPU、存储器(内存)、网络接口等部件组成。了解epoll本质的第一步,要从硬件的角度看计算机怎样接收网络数据。    下图展示了网卡接收数据的过程。在①阶段,网卡收到网线传来的数据;经过②阶段的硬件电路的传输;最终将数据写入到内存中的某个地址上(③阶段)。这个过程涉及到DMA传输、IO通路选择等硬件有关的知识,但我们只需知道:网卡会把接收到的数据写入内存。 二、如何知道接收了数据?   了解epoll本质的第二步,要从CPU的角度来看数据接收。要理解这个问题,要先了解一个概念——中断。   计算机执行程序时

Java基础知识笔记-14-并发

你。 提交于 2019-11-29 15:13:02
Java基础知识笔记-14-并发 14 并发 读者可能已经很熟悉操作系统中的多任务(multitasking): 在同一刻运行多个程序的能力。 例如,在编辑或下载邮件的同时可以打印文件。今天,人们很可能有单台拥有多个CPU的计算机,但是,并发执行的进程数目并不是由CPU数目制约的。操作系统将CPU的时间片分配给每一个进程,给人并行处理的感觉。 多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务。通常,每一个任务称为一个线程(thread), 它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序(multithreaded)。 那么,多进程与多线程有哪些区别呢? 本质的区别在于每个进程拥有自己的一整套变量,而线程则共享数据。这听起来似乎有些风险,的确也是这样,在本章稍后将可以看到这个问题。然而,共享变量使线程之间的通信比进程之间的通信更有效、更容易。此外,在有些操作系统中,与进程相比较,线程更“ 轻量级”,创建、撤销一个线程比启动新进程的开销要小得多。 在实际应用中,多线程非常有用。例如,一个浏览器可以同时下载几幅图片。一个Web服务器需要同时处理几个并发的请求。图形用户界面(GUI)程序用一个独立的线程从宿主操作环境中收集用户界面的事件。本章将介绍如何为Java应用程序添加多线程能力。 1 什么是线程 这里从察看一个没有使用多线程的程序开始

DMA简介

好久不见. 提交于 2019-11-29 15:05:14
注意: 个人整理,有误无责。 0. CPU控制的数据传输方式介绍 由CPU控制的数据传输方式有两种:查询、中断。 0.1 查询方式    查询方式是由程序控制的,如果CPU中执行的程序需要进行数据传输,CPU查询外设状态,如果外设准备好,那么进行数据传输。 0.2 中断方式    当外设需要与CPU进行数据交换的时候,外设向CPU发出中断请求,CPU中断当前执行的程序,相应外设的数据传输请求。当外设的数据传输结束后,CPU继续执行被中断的程序. 上面两种方式,数据都需经过CPU来传递,下面介绍DMA控制的数据传递。 1. DMA介绍    DMA方式,Direct Memory Access,也称为成组数据传送方式,有时也称为直接内存操作。DMA方式在数据传送过程中,没有保存现场、恢复现场之类的工作。    由于CPU根本不参加传送操作,因此就省去了CPU取指令、取数、送数等操作。内存地址修改、传送字 个数的计数等等,也不是由软件实现,而是用硬件线路直接实现的。所以DMA方式能满足高速I/O设备的要求,也有利于CPU效率的发挥。 (参考自百度) 2. 工作原理    直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传 输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。   

深入研究 Java Synchronize 和 Lock 的区别与用法

偶尔善良 提交于 2019-11-29 14:12:38
在分布式开发中,锁是线程控制的重要途径。Java为此也提供了2种锁机制,synchronized和lock。做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方。 我们先从最简单的入手,逐步分析这2种的区别。 一、synchronized和lock的用法区别 synchronized:在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要锁的对象。 lock:需要显示指定起始位置和终止位置。一般使用ReentrantLock类做为锁,多个线程中必须要使用一个ReentrantLock类做为对象才能保证锁的生效。且在加锁和解锁处需要通过lock()和unlock()显示指出。所以一般会在finally块中写unlock()以防死锁。 用法区别比较简单,这里不赘述了,如果不懂的可以看看Java基本语法。 二、synchronized和lock性能区别 synchronized是托管给JVM执行的,而lock是java写的控制锁的代码。在Java1.5中,synchronize是性能低效的。因为这是一个重量级操作,需要调用操作接口,导致有可能加锁消耗的系统时间比加锁以外的操作还多。相比之下使用Java提供的Lock对象,性能更高一些。但是到了Java1.6,发生了变化

Java中断机制

泄露秘密 提交于 2019-11-29 13:20:50
中断的原理 Java中断机制是一种协作机制,中断并不能直接终止另一个线程,而需要被中断的线程自己处理中断。 java.lang.Thread类提供了几个方法来操作这个中断状态,这些方法包括: public static boolean interrupted() 测试当前线程是否已经中断。线程的中断状态由该方法清除。 public boolean isInterrupted() 测试线程是否已经中断。线程的中断状态不受该方法的影响。 public void interrupt() 中断线程 线程1通过调用interrupt方法将线程2的中断状态置为true,2可以在合适的时候调用interrupted或isInterrupted来检测状态并做相应的处理。 类库中的有些类的方法也可能会调用中断: 如FutureTask中的cancel方法,如果传入的参数为true,它将会在正在运行异步任务的线程上调用interrupt方法, 如果正在执行的异步任务中的代码没有对中断做出响应,那么cancel方法中的参数将不会起到什么效果; 又如ThreadPoolExecutor中的shutdownNow方法会遍历线程池中的工作线程并调用线程的interrupt方法来中断线程, 所以如果工作线程中正在执行的任务没有对中断做出响应,任务将一直执行直到正常结束。 thread.stop():