GPIO 通用输入/输出端口,就是一些引脚,通过它们输出高低电平或者通过它们读入引脚的状态-是高电平还是低电平
上拉电阻、下拉电阻的作用在于,当GPIO引脚处于第三态(既不是输出高电平,也不是输出低电平,而是呈高阻态,即相当于没接芯片)时,
它的电平状态由上拉电阻、下拉电阻确定。
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPDAT (*(volatile unsigned long *)0x56000014)
#define GPB5_out (1<<(5*2))
GPBCON = GPB5_out; //GPB5引脚设为输出
GPBDAT &= ~(1<<5); //GPB5输出低电平
如果某个BANK的位宽被设为n,访问此BANK时,在总线上永远只会看到地址对齐的n位操作。
c语言代码点亮一个LED
@******************************************************************************
@ File:crt0.S
@ 功能:通过它转入C程序
@******************************************************************************
.text
.global _start
_start:
ldr r0, =0x56000010 @ WATCHDOG寄存器地址
mov r1, #0x0
str r1, [r0] @ 写入0,禁止WATCHDOG,否则CPU会不断重启
ldr sp, =1024*4 @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
@ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
bl main @ 调用C程序中的main函数
halt_loop:
b halt_loop
c代码
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPB5_out (1<<(5*2))
#define GPB6_out (1<<(6*2))
#define GPB7_out (1<<(7*2))
#define GPB8_out (1<<(8*2))
void wait(unsigned long dly)
{
for(; dly > 0; dly--);
}
int main(void)
{
unsigned long i = 0;
GPBCON = GPB5_out|GPB6_out|GPB7_out|GPB8_out; // 将LED1-4对应的GPB5/6/7/8四个引脚设为输出
while(1){
wait(30000);
GPBDAT = (~(i<<5)); // 根据i的值,点亮LED1-4
if(++i == 16)
i = 0;
}
return 0;
}
s3c2410/s3c2440对外引出的27跟地址线ADDR0~ADDR26的访问范围只有128MB,CPU对外还引出了8根片选信号nGCS0~nGCS7,
对应于BANK0~BANK7,当访问BANKx的地址空间时,nGCSx引脚输出低电平用来选中外接的设备,这样8个nGCSx信号总共就对应了1GB的地址空间。
s3c2410/s3c2440作为32位的CPU,可以使用的地址范围理论上达到4GB,除去用于连接外设的1GB地址空间外,
还有一部分是CPU内部寄存器地址,剩下的地址空间没有使用。
s3c2410/s3c2440的寄存器地址范围都处于0x4800000~0x5FFFFFFF
SDRAM的内部是一个存储阵列,阵列就如同表格一样,将数据“填”进去。和表格的检索原理一样,先制定一个行(Row),再制定一个列(Column),
就可以准确的找到所需要的单元格,这就是SDRAM寻址的基本原理。
BANK0~BANK5只需要设置BWSCON和BANKCONx两个寄存器;BANK6、BANK7外接SDRAM时,出BWSCON和BANKCONx外还要设置REFRESH、BANKSIZE、MRSRB6、MRSRB7等七个寄存器。
BWSCON----位宽和等待控制寄存器
BANKCONx-----BANK控制寄存器
MMU---内存管理单元,负责虚拟地址到物理地址的映射,并提供硬件机制的内存访问权限检查。
4种映射长度:段 1MB、大页 64KB、小页 4KB、极小页 1KB
ARM CPU上的地址转换涉及3个概念:虚拟地址 VA、变换后的虚拟地址 MVA、物理地址 PA
启动MMU后,CPU核对外发出虚拟地址VA;VA被转换为MVA供cache、MMU使用,再这里MVA被转换为PA;
最后使用PA读写实际设备(s3c2410/s3c2440内部寄存器或外接的设备)。
如果VA<32M,需要使用进程标示号PID(通过读CP15的C13获得)来转换为MVA。
if(VA < 32M) then
MVA = VA | (PID<<25) //VA < 32M
else
MVA = VA //VA >= 32M
使用PID生成MVA的目的是为了减少切换进程时的代价:不使用MVA而直接使用VA的话,当两个进程所使用的虚拟地址空间(VA)有重叠时,在切换进程时为了把重叠的VA映射到不同的PA上去,需要重建页表、使无效caches和TLBS等,代价非常大。使用MVA后,进程切换就省事多了,假设两个进程1,2运行时的VA都是0~32M,他们的MVA并不重叠,分别是0x02000000~0x03ffffff 0x4000000~0x05ffffff这样就不必进行重建页表等工作。
页表有一个个条目组成,每个条目存储了一段虚拟地址对应的物理地址及其访问权限,或者下一级页表的地址。
通过使用一个高速、容量相对较小的存储器来存储近期用到的页表条目(段/大页/小页/极小页描述符),以避免每次地址转换时都到主存去查找,这样可以大幅地提高性能。 --------------TLB (Translation Lookaside Buffers)
启用Cache后,CPU写数据时有写穿式(Write Through)和回写式(Write Back)
Write Through---CPU发出的写信号送到cache的同时,也写入主存。操作简单,但是由于主存慢速,降低了系统的写熟读并占用了总线时间。
Write Back------数据一般只写到cache,这样有可能出现cache中的数据得到更新而主存中的数据不变(数据陈旧)的情况,此时可在cache中设一标志地址及数据陈旧的消息,只有当cache中的数据被换出或强制进行“清空”操作时,才将原更新的数据写入主存相应的单元中。保证了cache和主存中的数据保持一致。