volatile

工程实践_GPIO介绍

蹲街弑〆低调 提交于 2020-01-17 06:26:11
一.GPIO简介 GPIO(General-Purpose IO ports),也就是通用IO口。在嵌入式系统中常常有数量众多,但是结构却比较简单的外部设备/电路,对于这些设备/电路有的需要CPU为之提供控制手段,有的则需要被CPU用作输入信号。而且,许多这样的设备/电路只要求一位,即只要有开/关两种状态就够了,比如灯亮与灭。对于这些设备/电路的控制,使用传统的串行口或并行口都不合适。所以在微控制芯片上一般都会提供一个“通用可编程IO接口”,也就是GPIO。 GPIO接口至少有两个寄存器,即“通用IO控制寄存器”与“通用IO数据寄存器”。数据寄存器的各位都直接引到芯片外部,而对数据寄存器中每一位的作用,即每一位的信号流通方向是输入还是输出,则可以通过控制寄存器中对应位独立的加以设置。这样,有无GPIO接口也就成为微控制器区别于微处理器的一个特征。 在实际的MCU中,GPIO是有多种形式的。比如,有的数据寄存器可以按照位寻址,有些却不能按照位寻址,这在编程时就要区分了。比如传统的8051系列,就区分成可位寻址和不可位寻址两种寄存器。另外,为了使用的方便,很多MCU把glue logic等集成到芯片内部,增强了系统的稳定性能,比如GPIO接口除去两个标准寄存器必须具备外,还提供上拉寄存器,可以设置IO的输出模式是高阻,还是带上拉的电平输出,或者不带上拉的电平输出。这在电路设计中

C/C++中volatile关键字详解

拥有回忆 提交于 2020-01-17 05:18:36
1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier 。这是 BS 在 "The C++ Programming Language" 对 volatile 修饰词的说明: A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that aggressive optimizations must be avoided. volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。声明时语法: int volatile vInt; 当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。例如: 1 volatile int i=10; 2 int a = i; 3 ... 4 // 其他代码,并未明确告诉编译器,对 i

Java并发--原子变量、CAS算法

老子叫甜甜 提交于 2020-01-17 01:36:28
并发编程中的原子性问题 测试:20个线程对一个普通int变量进行++操作。 package pers . zhang . juc . part1 ; /** * @author zhang * @date 2020/1/16 - 17:52 * * 并发编程中的原子性问题 */ public class TestAtomicDemo { public static void main ( String [ ] args ) { AtomicDemo ad = new AtomicDemo ( ) ; for ( int i = 0 ; i < 20 ; i ++ ) { new Thread ( ad , "thread" + i ) . start ( ) ; } } } class AtomicDemo implements Runnable { private int serialNumber = 0 ; @Override public void run ( ) { try { Thread . sleep ( 200 ) ; } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } System . out . println ( Thread . currentThread ( ) .

keil MDK注意事项

血红的双手。 提交于 2020-01-16 14:51:58
1.MDK中的char类型的取值范围是? 在MDK中,默认情况下,char 类型的数据项是无符号的,所以它的取值范围是0~255。它们可以显式地声明为signed char 或 unsigned。因此,定义有符号char类型变量,必须用signed显式声明。我曾读过一本书,其中有一句话:“signed关键字也是很宽宏大量,你也可以完全当它不存在,在缺省状态下,编译器默认数据位signed类型”,这句话便是有异议的,我们应该对自己所用的CPU构架以及编译器熟练掌握。 关于keil MDK工程项目设置可参考:https://blog.csdn.net/ybhuangfugui/article/details/51655502,https://blog.csdn.net/ybhuangfugui/article/details/53131141 2.赋初值的全局变量和静态变量,初值被放在什么地方? unsigned int g_unRunFlag=0xA5; static unsigned int s_unCountFlag=0x5A; 这两行代码中,全局变量和静态变量在定义时被赋了初值,MDK编译环境下,你知道这个初值保存在那里吗? 对于在程序中赋初值的全局变量和静态变量,程序编译后,MDK将这些初值放到Flash中,紧靠在可执行代码的后面。在程序进入main函数前,会运行一段库代码

volatile的使用

微笑、不失礼 提交于 2020-01-16 06:51:12
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去预先假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地 重新 读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 1). 并行设备的硬件寄存器(如:状态寄存器) 2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 3). 多线程应用中被几个任务共享的变量 回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。 假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。 1). 一个参数既可以是const还可以是volatile吗?解释为什么。 2). 一个指针可以是volatile 吗?解释为什么。 3). 下面的函数有什么错误: int square(volatile int *ptr) { return *ptr * *ptr; } 下面是答案: 1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变

C++中的volatile关键字

本小妞迷上赌 提交于 2020-01-16 04:32:21
原文: http://www.cnblogs.com/Chase/archive/2010/07/05/1771700.html volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。 volatile的本意是“易变的”,不过翻译成“直接存取原始内存地址”更为合适。“易变”是因为外在因素引起的,象多线程,中断等,并不是因为用volatile修饰了的变量就是“易变”了,假如没有外因,即使用volatile定义,它也不会变化。 使用该关键字的例子如下: int volatile nVint;//当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。 对于这样的代码: volatile int i = 10; int a = i; ... //其他代码,并未明确告诉编译器,对i进行过操作 int b = i; volatile 指出 i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取

C# lock free coding sanity check

限于喜欢 提交于 2020-01-16 01:42:09
问题 UPDATED : now using a read-only collection based on comments below I believe that the following code should be thread safe "lock free" code, but want to make sure I'm not missing something... public class ViewModel : INotifyPropertyChanged { //INotifyPropertyChanged and other boring stuff goes here... private volatile List<string> _data; public IEnumerable<string> Data { get { return _data; } } //this function is called on a timer and runs on a background thread private void RefreshData() {

When do I need to use volatile in ISRs?

倾然丶 夕夏残阳落幕 提交于 2020-01-15 12:25:10
问题 I am making embedded firmware where everything after initialization happens in ISRs. I have variables that are shared between them, and I am wondering in which cases they need to be volatile. I never block, waiting for a change in another ISR. When can I be certain that actual memory is read or written to when not using volatile? Once every ISR? Addendum: This is for ARM Cortex-M0, but this isn't really a question about ISRs as much as it is about compiler optimization, and as such, the

Java多线程面试题整理

◇◆丶佛笑我妖孽 提交于 2020-01-15 09:38:38
1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒。Java在语言层面对多线程提供了卓越的支持,它也是一个很好的卖点。 2) 线程和进程有什么区别? 线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。别把它和栈内存搞混,每个线程都拥有单独的栈内存用来存储本地数据。 3) 如何在Java中实现线程? 1)java.lang.Thread 类的实例就是一个线程但是它需要调用java.lang.Runnable接口来执行, 2)由于线程类本身就是调用的Runnable接口所以你可以继承java.lang.Thread 类或者直接调用Runnable接口来重写run()方法实现线程。 3). 实现Callable接口通过FutureTask包装器来创建Thread线程 Callable接口(也只有一个方法)定义如下: public interface Callable<V> { V call() throws Exception; } public class SomeCallable<V>