当前位置:  编程技术>移动开发
本页文章导读:
    ▪在已经响应UITapGestureRecognizer的UIView中明晰的响应UIButton点击事件        在已经响应UITapGestureRecognizer的UIView中清晰的响应UIButton点击事件今天码代码。。发现我自己在UIScrollView的UIButton老是不响应,开始以为是委托的问题,后来找了半天发现是我已经响应了UITapGest.........
    ▪ 入门级ARM汇编授命        入门级ARM汇编指令无论是体系结构还是指令集,大家或多或少都应该对X86汇编有些了解,而对于嵌入式领域已被广泛采用的ARM 处理器,了解的可能并不多。如果你有兴趣从事嵌入式方面的开发,那.........
    ▪ S5PV210学习札记——Nand配置       S5PV210学习笔记——Nand配置S5PV210的Nand flash跟2440和6410的Nand flash配置差不多,不同的是S5PV210的功能更加强大,尤其是S5PV210的硬件ECC(本文不涉及S5PV210中Nand ECC配置)。整体上来讲,S5PV210的Nand.........

[1]在已经响应UITapGestureRecognizer的UIView中明晰的响应UIButton点击事件
    来源: 互联网  发布时间: 2014-02-18
在已经响应UITapGestureRecognizer的UIView中清晰的响应UIButton点击事件

今天码代码。。发现我自己在UIScrollView的UIButton老是不响应,开始以为是委托的问题,后来找了半天发现是我已经响应了UITapGestureRecognizer

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                action:@selector(tapButton:)];
    [cba addGestureRecognizer:singleTap];
    [singleTap release];


如果要清晰响应UIButton那就需要下面这段代码:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    UIView* touchedView = [touch view];
    if([touchedView isKindOfClass:[UIButton class]]) {

       return NO;
    }

    return YES;
}




    
[2] 入门级ARM汇编授命
    来源: 互联网  发布时间: 2014-02-18
入门级ARM汇编指令

无论是体系结构还是指令集,大家或多或少都应该对X86汇编有些了解,而对于嵌入式领域已被广泛采用的ARM 处理器,了解的可能并不多。如果你有兴趣从事嵌入式方面的开发,那么了解一些RISC 体系结构和ARM汇编的知识还是有必要的。这里,我们找出了这两种体系结构最明显的不同之处,并对此进行介绍,让大家对于RISC体系结构的汇编有一个基本的了解。首先,我们就来看一看基于RISC的ARM的体系结构。

基于RISC 的ARM CPU
ARM是一种RISC体系结构的处理器芯片。和传统的CISC体系结构不同,RISC 有以下的几个特点:
◆ 简洁的指令集——为了保证CPU可以在高时钟频率下单周期执行指令,RISC指令集只提供很有限的操作(例如add,sub,mul等),而复杂的操作都需要由这些简单的指令来组合进行模拟。并且,每一条指令不仅执行时间固定,其指令长度也是固定的,这样,在译码阶段就可以对下一条指令进行预取。
◆ Load-Store 结构——这个应该是RISC 设计中比较有特点的一部分。在RISC 中,CPU并不会对内存中的数据进行操作,所有的计算都要求在寄存器中完成。而寄存器和内存的通信则由单独的指令来完成。而在CSIC中,CPU是可以直接对内存进行操作的,这也是一个比较特别的地方。
◆ 更多的寄存器——和CISC 相比,基于RISC的处理器有更多的通用寄存器可以使用,且每个寄存器都可以进行数据存储或者寻址。
当然,作为RISC 领域最成功的处理器,ARM也遵从上面的特点。这里,我们不妨来看一看在user 模式下,ARM处理器的体系结构,这对于我们了解其汇编语言是有好处的。而其它模式下只是有一些寄存器分组略有不同,大家可以在ARM的手册上查到。这里要说明的是,尽管ARM处理器也支持16位指令,不过在下文中,我们都假定ARM处理器在32 位模式下工作。

图1:user模式下ARM处理器体系结构
从图1中我们看到,在user 模式下,ARM CPU 有16个数据寄存器,被命名为r0~r15(这个要比x86的多一些)。r13~r15有特殊用途,其中:
◆ r13 - 指向当前栈顶,相当于x86的esp,这个东西在汇编指令中要用sp 表示
◆ r14 - 称作链接寄存器,指向函数的返回地址。用lr表示,这和x86将返回地址保存在栈中是不同的
◆ r15 - 类似于x86的eip,其值等于当前正在执行的指令的地址+8(因为在取址和执行之间多了一个译码的阶段),这个用pc表示
另外,ARM处理器还有一个名为cspr的寄存器,用来监视和控制内部操作,这点和x86 的状态寄存器是类似的。具体的内容就用到再说了。

ARM 指令集
ARM处理器可以支持3种指令集——ARM,Thumb和Jazelle。
采用那种指令集,由cspr中的标志位来决定。大体说来:
◆ ARM——这是ARM自身的32 位指令集
◆ Thumb ——这是一个全16 位的指令集,在16 位外部数据总线宽度下,这个指令集的效率要比32 位的ARM指令高一些。
◆ Jazelle ——这是一个8位指令集,用来加速Java字节码的执行
整个ARM指令集由数据处理指令、分支指令、Load-Store指令、程序中断指令和一些系统控制指令构成,除了Load-Store指令外,其他部分和x86指令集是比较类似的。但和x86相比,ARM指令最显著的特点它们都是32-bit 定长的。另外,由于arm是基于RISC指令集的,所以CPU只处理在寄存器中的数据并通过独立的load-store指令在内存和寄存器之间进行数据的传递。
在使用方面,ARM指令的格式也要比Intel的复杂些。一般说来,一条ARM指令有如下的形式:
{S} [Rd], [Rn], [Rm]
其中:
* {S} —— 加上这个后缀的指令会更新cpsr 寄存器
* [Rd] —— 目的寄存器
* [Rn]/[Rm] —— 源寄存器
一般来说,arm 指令有3个操作数,其中Rm寄存器在执行指令前可以进入桶形移位器进行移位操作,而Rn则会直接进入ALU 单元。如果一条arm 指令只有2 个操作数,那么源寄存器按照Rm 来处理。例如,一条加法指令:
add r0, r1, #1
就会把r1+1的结果存放到r0中。
在熟悉了基本的汇编格式后,读者就可以自行去查询基本的ARM汇编指令了,下面,我们找出ARM中比较有特色部分——Load-Store指令结构,它是CPU 和内存进行通信的一个重要媒介。

Load-Store 指令体系
由于ARM CPU并不直接处理内存中的数据,这个指令体系就担起了在寄存器和内存之间交换数据的重要媒介。它要比x86 的内存访问机制复杂一些。该指令体系分成3 类:
◆ 单寄存器传输(这是与x86 最为相像的)
◆ 多寄存器传输
◆ 交换指令

单寄存器传输
先看第一个,很简单:把单一的数据传入(LDR) 或传出(STR)寄存器,对内存的访问可以是DWORD(32-bit), WORD(16-bit)和BYTE(8-bit)。指令的格式如下:
DWORD:
Rd, addressing1
WORD:
H Rd, addressing2 无符号版
SH Rd, addressing2 有符号版
BYTE:
B Rd, addressing1 无符号版
SB Rd, addressing2 有符号版
addressing1 和addressing2 的分类下面再说,现在理解成某种寻址方式就可以了。
在单寄存器传输方面,还有以下三种变址模式,他们是:
◆ preindex
这种变址方式和x86的寻址机制是很类似的,先对寄存器进行运算,然后寻址,但是在寻之后,基址寄存器的内容并不发生改变,例如:
ldr r0, [r1, #4]
的含义就是把r1+4 这个地址处的DOWRD 加载到r0,而寻址后,r1 的内容并不改变。
◆ preindex with writeback
这种变址方式有点类似于++i的含义,寻址前先对基地址寄存器进行运算,然后寻址. 其基本的语法是在寻址符[]后面加上一个"!" 来表示.例如:
ldr r0, [r1, #4]!
就可以分解成:
add r1, r1, #4
ldr r0, [r1, #0]
◆ postindex
自然这种变址方式和i++的方式就很类似了,先利用基址寄存器进行寻址,然后对基址寄存器进行运算,其基本语法是把offset 部分放到[]外面,例如:
ldr r0, [r1], #4
就可以分解成:
ldr r0, [r1, #0]
add r1, r1, #4
如果你还记得x86 的SIB 操作的话,那么你一定想ARM是否也有,答案是有也没有。在ss上面提到的addressing1 和addressing2的区别就是比例寄存器的使用,addressing1可以使用[base, scale, 桶形移位器]来实现SB 的效果,或者通过[base,offset](这里的offset 可以是立即数或者寄存器)来实现SI 的效果,而addressing2则只能用后者了。于是每一种变址方式最多可以有3 种寻址方式,这样一来,最多可以有9种用来寻址的指令形式。例如:
ldr r0, [r1, r2, LSR #0x04]!
ldr r0, [r1, -#0x04]
ldr r0, [r1], LSR #0x04
每样找了一种,大概就是这个意思。到此,单寄存器传输就结束了,掌握这些足够应付差事了。下面来看看多寄存器传输吧。

多寄存器传输
说得很明白,意思就是通过一条指令同时把多个寄存器的内容写到内存或者从内存把数据写到寄存器中,效率高的代价是会增加系统的延迟,所以armcc 提供了一个编译器选项来控制寄存器的个数。指令的格式有些复杂:
<寻址模式> Rn{!}, {r^}
我们先来搞明白寻址模式,多寄存器传输模式有4 种:
也就是说以A开头的都是在Rn的原地开始操作,而B开头的都是以Rn的下一个位置开始操作。如果你仍然感到困惑,我们不妨看个例子。
所有的示例指令执行前:
mem32[0x1000C] = 0x04
mem32[0x10008] = 0x03
mem32[0x10004] = 0x02
mem32[0x10000] = 0x01
r0 = 0x00010010
r1 = 0x00000000
r3 = 0x00000000
r4 = 0x00000000
1) ldmia r0!, {r1-r3} 2) ldmib r0!, {r1-r3}
执行后: 执行后:
r0 = 0x0010001C r0 = 0x0010001C
r1 = 0x01 r1 = 0x02
r2 = 0x02 r2 = 0x03
r3 = 0x03 r3 = 0x04
至于DA 和DB 的模式,和IA / IB 是类似的,不多说了。
最后要说的是,使用ldm 和stm指令对进行寄存器组的保护是很常见和有效的功能。配对方案:
stmia / ldmdb
stmib / ldmda
stmda / ldmib
stmdb / ldmia
继续来看两个例子:
执行前:
r0 = 0x00001000
r1 = 0x00000003
r2 = 0x00000002
r3 = 0x00000001
执行的指令:
stmib r0!, {r1-r3}
mov r1, #1 ; These regs have been modified
mov r2, #2
mov r3, #3
当前寄存器状态:
r0 = 0x0000100C
r1 = 0x00000001
r2 = 0x00000002
r3 = 0x00000003
ldmia r0!, {r1-r3}
最后的结果:
r0 = 0x00001000
r1 = 0x00000003
r2 = 0x00000002
r3 = 0x00000001
另外,我们还可以利用这个指令对完成内存块的高效copy:
loop
ldmia r9!, {r0-r7}
stmia r10!, {r0-r7}
cmp r9, r11
bne loop
说到这里,读者应该对RISC的Load-Store体系结构有一个大概的了解了,能够正确配对使用指令,是很重要的。


    
[3] S5PV210学习札记——Nand配置
    来源: 互联网  发布时间: 2014-02-18
S5PV210学习笔记——Nand配置

S5PV210的Nand flash跟2440和6410的Nand flash配置差不多,不同的是S5PV210的功能更加强大,尤其是S5PV210的硬件ECC(本文不涉及S5PV210中Nand ECC配置)。整体上来讲,S5PV210的Nand flash配置还是非常简单的。

其实,配置一个模块往往需要以下几个步骤:

(1)根据原理图,理清模块的接线方式,对于Nand flash来说,就是看看Nand flash接到了哪些GPIO上,然后把对应的GPIO配置为Nand功能即可。

(2)阅读S5PV210手册,掌握相关模块控制器的功能、操作方式及寄存器配置。

(3)阅读模块芯片手册,掌握模块的访问控制时序。

我们按照以上步骤进行配置,首先是模块GPIO的配置,我的开发板是TQ210,Nand flash芯片是K9K8G08U0B,接线方式如下图:


其中:

(1)Xm0FRnB0~Xm0FRnB3,Xm0FCLE,Xm0FALE,Xm0FWEn,Xm0FREn这八根脚连接到了MP0_3上,查看MP0_3控制寄存器可知,需将MP0_3CON配置为0x22222222;

(2)Xm0CSn2~Xm0CSn5四根脚连接到了MP0_1的2~5脚上,故MP0_1CON的8~23位应该配置为0x3333;

(3)Xm0DATA0~Xm0DATA7这八根脚连接到了MP0_6上,故MP0_6应该配置为0x22222222;

这样,GPIO配置好了,接下来我们配置下Nand flash的控制寄存器,大体浏览下Nand flash的寄存器功能后我们可以发现,如果不使用ECC功能可以只配置NFCONF和NFCONT两个寄存器,我们的Nand flash是SLC型Nand,Page大小为2048,写入地址需要5个周期(这些从Nand flash芯片手册上很容易找到),故NFCONF应该配置如下:

NFCONF=(3<<23)|(1<<12)|(2<<8)|(0<<4)|(1<<1); //依次为:禁止ECC,TACLS,TWPRH0,TWPRH1,SLC、2K、5周期。

其中TACLS、TWPRH0和TWPRH1需要阅读手册来确定,韦东山老师讲述了确定方式,但是,我配置时完全按照手册上的最小时间设置时没有能够正常访问,我是自己尝试出来的,先将三个参数都设置为7,然后慢慢减小,最后测试出来设置为1、2、0,但是这样不一定是最稳定的,一般来讲,数值略大一些会更稳定,但是为了不影响访问效率,这个值也不能设太大,先按照最小情况设置,当发现有读取错误或其他不稳定现象时再适当提高参数值。

然后就是NFCONT寄存器,NFCONT的配置就更简单了,我们不设置ECC,只需要设置0位和1位就可以了:

NFCONT = (1<<1)|(1<<0);//禁止片选,使能Nand

这样,Nand flash的初始化函数就出来了:

void nand_init(){
    NFCONF = (3<<23)|(1<<12)|(2<<8)|(0<<4)|(1<<1);
    NFCONT = (1<<0)|(1<<1);

    MP0_1CON &= ~(0xffff<<8);
    MP0_1CON |= 0x3333<<8;
    MP0_3CON = 0x22222222;
    MP0_6CON = 0x22222222;

    nand_reset();
}
至于nand_reset,通常是Nand flash配置完成之后就进行一次reset,这样使Nand flash恢复到最初状态。

这样,Nand flash初始化好了,但是要访问Nand flash还需要按照时序对其操作,Nand方式启动时只需要实现Nand flash的读操作,为此,这里只列举一下几个读相关的操作:

(1)Nand flash reset

static void nand_reset(){
    nand_select_chip();
    nand_cmd(0xff);
    nand_wait();
    nand_deselect_chip();
}
(2)Nand flash写地址

static void nand_addr(unsigned long page_addr, unsigned long page_offset){
    NFADDR = (page_offset>>0) & 0xFF;
    NFADDR = (page_offset>>8) & 0x7;
    NFADDR = (page_addr) & 0xFF;
    NFADDR = (page_addr>>8) & 0xFF;
    NFADDR = (page_addr>>16) & 0x07;
}
(3)Nand flash读ID

void nand_read_id(char id[]){
    int i;

    nand_select_chip();
    nand_cmd(0x90);

    NFADDR = 0;

    for (i = 0; i < 5; i++)
        id[i] = nand_read();

    nand_deselect_chip();
}
(4)Nand flash读页数据

void nand_read_page(unsigned char* buf, unsigned long page_addr){
    int i;
    nand_select_chip();
    nand_cmd(0);
    nand_addr(page_addr, 0);
    nand_cmd(0x30);
    nand_wait();
    for(i = 0; i != PAGE_SIZE; ++i){
        *buf++ = nand_read();
    }
    nand_deselect_chip();
}
上面是几个比较重要的Nand flash读相关的操作函数,到这里,您自己补充一下引用到的小函数就可以正常的进行Nand flash操作了,我把我写的代码上传到我的CSDN资源里,如果需要的话可以拿去参考。另外,如果需要编写Nand flash写操作的代码可以参考一下本人博客中6410的Nand flash配置部分和Nand flash的芯片手册,原理都是相通的。


    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3