zoukankan      html  css  js  c++  java
  • 第2阶段——编写uboot之编译测试以及改进(3)

    编译测试:

    1.将写好的uboot复制到linux下面

    2.make编译,然后将错误的地方修改,生成boot.bin

    (编译出错的解决方案:http://www.cnblogs.com/lifexy/p/7326172.html)

    3.通过make生成的反汇编来查看代码是否正确

    4.通过oflash烧写到板子nand flash上

    5.查看串口是否数据打印 

    发现串口无数据,发现两处错误:

    5.1在init.C中define定义 没有加大括号,没有定义volatile型


    例如:

     #define NFCONF       *((unsigned long *)0x4E000000)  

    需要改为: #define NFCONF      (*((volatile unsigned long *)0x4E000000) )


    5.2 在init.C中nand_read_addr()函数出错,代码如下:

    void nand_read_addr(unsigned int addr)
    {
       volatile int i;
       NFADDR=( addr>>0)&0xff;         //A7~A0        
       for(i=0;i<10;i++);
    NFADDR
    =( addr>>8)&0x0f; //A11~A8 for(i=0;i<10;i++);
    NFADDR
    =( addr>>12)&0xff; //A19~A12 for(i=0;i<10;i++); NFADDR=( addr>>20)&0xff; //A27~A20 for(i=0;i<10;i++); NFADDR=( addr>>28)&0xff; //A28 for(i=0;i<10;i++); }

    上面之所以错是因为nand flash是2048B一页,这里的写的一页是A11~A0,其值=4096,已经属于两页大小了

    应该改为:

    void nand_read_addr(unsigned int addr)
    {
       unsigned int col  = addr % 2048;
       unsigned int page = addr / 2048;
       volatile int i;
    NFADDR
    =(col>>0)&0xff; //A7~A0 for(i=0;i<10;i++);
    NFADDR
    =(col>>8)&0x0f; //A10~A8 for(i=0;i<10;i++);
    NFADDR
    =(page>>0)&0xff; //A18~A11 for(i=0;i<10;i++);
    NFADDR
    =(page>>8)&0xff; //A26~A19 for(i=0;i<10;i++);
    NFADDR
    =(page>>16)&0xff; //A27 for(i=0;i<10;i++); }

    优化改进(加快内核启动时间)

    1 提高CPU频率

    将CPU频率设为最大值400MHZ(内核启动时间7S变为6S,因为HCLK和PCLK频率没有改变)

    然后分频系数FCLK:HCLK:PCLK需要设置为1:4:8

    因为HCLK最高133MHZ,这里需要设置为100MHZ

    PCLK最高50MHZ,这里需要设置为50HZ

    如下图所示,得出 CLKDIVN寄存器需要等于0X5即可

    通过下图看出,提高CPU频率需要设置MPLLCON中MDIV、PDIV、SDIV

     

    通过下图得出,取400MHZ时,设置MDIV为0X5C,PDIV为0x1,SDIV为0x1

     

    所以改进代码如下:

    #define S3C2440_MPLL_400MHZ     ((0x5c<<12)|(0x01<<4)|(0x01))  //设置FCLK=400MHZ
    /*    2.设置时钟(必须设为异步总线模式)  */
       ldr r0,=CLKDIVN
       mov r1,#5                                  /*FCLK:HCLK:PCLK=1:4:8*/
       str r1,[r0]
       mrc p15, 0, r1, c1, c0                 /* 读出控制寄存器 */
       orr  r1, r1, #0xc0000000               /* 设置为“asynchronous bus mode” */
       mcr   p15, 0, r1, c1, c0, 0               /* 写入控制寄存器 */
    
       ldr r0,=MPLLCON
       ldr r1,= S3C2440_MPLL_400MHZ      //使用复杂的数不能用mov,需要用ldr
       str r1,[r0]
    2.开启ICAHE(内核启动时间6S变为1.5S)
    CAHE介绍:

    通过高速缓存存储器来加快对内存的数据访问,在CAHE中有ICAHE(指令缓存)和DCAHE(数据缓存)
    ICAHE: 指令缓存,用来存放执行这些数据的指令
    DCAHE:用来存放数据,需要开启MMU才能开启DCAHE
    在没开启ICAHE之前,CPU读取SDRAM地址数据时,每次都需要先访问一次地址值,在读数据.
    当开了ICAHE后,第一次读取SDRAM地址数据时,ICAHE发现缓存里没有这个地址数据,然后将SDRAM中需要读取的那部分一大块内存数据都复制在缓存中,后面陆续读取数据就不会再访问SDRAM了,直到CPU没有找到地址数据后ICAHE再从SDRAM中重新复制 

    通过CP15协处理器来开启ICAHE

     (CP15协处理器操作用法:  http://www.cnblogs.com/lifexy/p/7203786.html)

    从上面链接中可以找到ICAHE控制位在CP15的寄存器C1中位12(如下图), 然后通过MRS和MSR向该位12置1,开启ICAHE

     

    所以代码如下(放在SDRAM初始化之前)

       mrc p15, 0, r0, c1, c0, 0                     //将 CP15 的寄存器 C1 的值读到 r0 中
       orr r0, r0, #(1<<12)                          //将r0中位12置1     
       mcr p15,0, r0,c1,c0,0                         //开启ICAHE
  • 相关阅读:
    Docker & ASP.NET Core (3):发布镜像
    Docker & ASP.NET Core (2):定制Docker镜像
    Docker & ASP.NET Core (1):把代码连接到容器
    Redis五大数据类型的常用操作
    centos安装Redis
    SpringBoot进阶教程(五十一)Linux部署Quartz
    mybatis在xml文件中处理转义字符
    org.apache.ibatis.builder.IncompleteElementException: Could not find result map java.lang.Integer
    SpringBoot进阶教程(五十)集成RabbitMQ---MQ实战演练
    浅谈RabbitMQ Management
  • 原文地址:https://www.cnblogs.com/lifexy/p/7337497.html
Copyright © 2011-2022 走看看