新闻  |   论坛  |   博客  |   在线研讨会
TQ2440裸跑-SDRAM(存储控制器)
霹雳之火 | 2014-07-12 15:16:26    阅读:967   发布文章

0实验环境与实验例程

实验环境:TQ2440

实验例程:韦东山 嵌入式linux应用开发完全手册
1 原理图 tq2440板载64Msdram

TQ2440裸跑-SDRAM(存储控制器)

TQ2440裸跑-SDRAM(存储控制器)


2 数据手册



13个寄存器
3 总结

3.1 根据数据手册设置sdram的寄存器

3.2 ATPCS规则分析

ATPCS是ARM-Thumb Procedure Call Standard 的缩写, 也就是ARM,Thumb的程序调用标准.

TQ2440裸跑-SDRAM(存储控制器)

根据这张表显示, r0~r3一般用来传递函数的参数,r4~r7则用来放置局部变量. 而r12~r15则可以有特别的用途.


  •  浮点数寄存器

基本的ATPCS支持两种浮点数体系结构. FPA和AFP. FPA体系有八个可以放置单精度和双精度数的浮点寄存器. AFP体系有16个双精度寄存器.


  • 参数调用

参数调用分两种情况,参数可变的调用和参数个数固定的调用. 有以下的规则

* 小于32位的参数值会被自动扩展为32位.

* 64位的参数被当成两个32位数.

*  对于浮点数.如果芯片本身硬件上支持浮点运算,则浮点参数会放在浮点寄存器里传递. 如果硬件上不支持浮点数运算, 则转化为整型放通用寄存器传递.

* 其它类型通通转为32位整型数传递

* 对于参数可变的程序调用, 前四个参数放在r0~r3中传递,如果多于四个参则按相反的顺序进栈保存,所谓相反的顺序是指靠前参数后进栈.

* 对于固定参数的调用, 如果有可以做浮点运算的硬件部件, 各个浮点参数按顺序处理;为每个浮点参数分配FP寄存器;分配的方法是,满足该浮点参数需要的且编号最小的一组连续的FP寄存器.第一个整数参数通过寄存器R0~R3来传递,其他参数通过数据栈传递.

这是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(volatile unsigned long dly)
{
   for(; dly > 0; dly--);
}

int main(void)
{
   unsigned long i = 0;

   // LED1,LED2,LED3,LED4对应的4根引脚设为输出
   GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out;

   while(1){
      wait(30000);
      GPBDAT = (~(i<<5));       // 根据i的值,点亮LED1,2,3,4
      if(++i == 16)
         i = 0;
   }

   return 0;
}

这是反汇编文件(一部分):

ARM架构中使用R12作为子程序间的scratch寄存器 (ATPCS中规定)。可以将R12 用于保存SP,在函数返回时使用该寄存器出栈,记作ip。可简单的认为暂存SP.


R11:stack frame

stack我们都知道,每一个进程都有自己的栈。考虑进程执行时发生函数调用的场景,母函数和子函数使用的是同一个栈,在通常的情况下,我们并不需 要区分母函数和子函数分别使用了栈的哪个部分。但是,当我们需要在执行过程中对函数调用进行backtrace的时候,这一信息就很重要了。

简单的说,stack frame就是一个函数所使用的stack的一部分,所有函数的stack frame串起来就组成了一个完整的栈。stack frame的两个边界分别由FP和SP来限定。

backtrace

在程序执行过程中(通常是发生了某种意外情况而需要进行调试),通过SP和FP所限定的stack frame,就可以得到母函数的SP和FP,从而得到母函数的stack frame(PC,LR,SP,FP会在函数调用的第一时间压栈),以此追溯,即可得到所有函数的调用顺序。

TQ2440裸跑-SDRAM(存储控制器)

此图只是示例,不表示文中程序调用情况

注:好像fp的指向要往下一一格,直接指向pc的指针

300000b0 :

链接地址 机器码            汇编                              注释
300000b0:   e1a0c00d    mov   ip, sp;ip指r12,将当前调用函数的堆栈保存
300000b4:   e92dd800    stmdb   sp!, {fp, ip, lr, pc};sp=sp-4*4

;将fp寄存器和sp共用得到母函数的SP和FP,这里保存的fp指向main函数的pc

;lr保存调用函数的下一条指令的地址

;pc保存当前函数的入口地址,在回溯调用函数时很有用

300000b8:   e24cb004    sub   fp, ip, #4   ; 0x4 ;fp指r11,减4后fp指向wait函数的pc

显然通过回溯可以得到wait被main调用,main被启动函数调用


300000bc:   e24dd004    sub   sp, sp, #4   ; 0x4,sp减1,准备局部变量i入栈
300000c0:   e50b0010    str   r0, [fp, #-16];将实参值入栈
300000c4:   e51b3010    ldr   r3, [fp, #-16]
300000c8:   e3530000    cmp   r3, #0   ; 0x0
300000cc:   0a000003    beq   300000e0
300000d0:   e51b3010    ldr   r3, [fp, #-16]
300000d4:   e2433001    sub   r3, r3, #1   ; 0x1
300000d8:   e50b3010    str   r3, [fp, #-16]
300000dc:   eafffff8    b   300000c4
300000e0:   e89da808    ldmia   sp, {r3, fp, sp, pc};局部变量到r3,fp到fp,ip到sp,lr到pc

                                                                       ;将R12用于保存SP,在函数返回时使用该寄存器出栈,记作ip,

300000e4 :
300000e4:   e1a0c00d    mov   ip, sp;ip指r12
300000e8:   e92dd800    stmdb   sp!, {fp, ip, lr, pc} ;fp一般指r11,保存调用者的寄存器
300000ec:   e24cb004    sub   fp, ip, #4   ; 0x4
300000f0:   e24dd004    sub   sp, sp, #4   ; 0x4; sp减1,准备局部变量i入栈

                                                                            ;根据ATPCS,数据为满递减类型
300000f4:   e3a03000    mov   r3, #0   ; 0x0  保存的是i的值
300000f8:   e50b3010    str   r3, [fp, #-16]    ;将i的值放入堆栈(局部变量)
300000fc:   e3a03456    mov   r3, #1442840576   ; 0x56000000
30000100:   e2833010    add   r3, r3, #16   ; 0x10
30000104:   e3a02b55    mov   r2, #87040   ; 0x15400
30000108:   e5832000    str   r2, [r3]      ;设置GPBCON
3000010c:   e3a00c75    mov   r0, #29952   ; 0x7500
30000110:   e2800030    add   r0, r0, #48   ; 0x30 通过r0传递实参r0=30000
30000114:   ebffffe5    bl   300000b0 ;跳转到wait,下条指令地址保存在lr中
30000118:   e3a02456    mov   r2, #1442840576   ; 0x56000000
3000011c:   e2822014    add   r2, r2, #20   ; 0x14
30000120:   e51b3010    ldr   r3, [fp, #-16]
30000124:   e1a03283    mov   r3, r3, lsl #5
30000128:   e1e03003    mvn   r3, r3
3000012c:   e5823000    str   r3, [r2]
30000130:   e51b3010    ldr   r3, [fp, #-16]
30000134:   e2833001    add   r3, r3, #1   ; 0x1
30000138:   e50b3010    str   r3, [fp, #-16]
3000013c:   e3530010    cmp   r3, #16   ; 0x10
30000140:   1afffff1    bne   3000010c
30000144:   e3a03000    mov   r3, #0   ; 0x0
30000148:   e50b3010    str   r3, [fp, #-16]
3000014c:   eaffffee    b   3000010c


4 问题及解决方法: tftp下载出现checksum bad 错误原因 请看链接:linux下tftp下载出现checksum bad 错误原因

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客