zoukankan      html  css  js  c++  java
  • arm 裸奔经验

    由于自己买的开发板的norflash坏了,板子剩下了nandflash了,还想玩开发板,就开始我的裸奔了,开始去了解nandflash启动原理,arm2410是从nandflash前4k空间复制到arm内部4kRAM空间当中运行.知道原理以后我写裸奔程序都不超过4k程序,就可以做跑马灯,rs232驱动,rtc程序是足够了.一开始 我用的软件是ads1.2,只能抄写别人 程序,程序当中有一个init2410.s里面有一大堆的汇编语言,看的我眼花撩乱,我也只能硬着头皮看下去,基本上能看懂了个大概. .s文件主要功能就是程序的开始和对中断向量进行描述,同时想main()函数跳转,跳到c语言当中运行.后来我做跑马灯时候,我把.s文件压缩成3句话,把没有用的语句都删了.一般的初试化函数都在2410lib.c文件当中,里面有串口初试化,端口初始化,等其他初始化.裸奔中我觉的最有成就感的是外部中断的实现和3.5寸lcd显示我的相册.先说一下我外部中断的实现.

    b HandlerUndef ;handler for Undefined mode
    b HandlerSWI ;handler for SWI interrupt
    b HandlerPabort ;handler for PAbort
    b HandlerDabort ;handler for DAbort
    b .  ;reserved
    b HandlerIRQ ;handler for IRQ interrupt
    b HandlerFIQ ;handler for FIQ interrupt

    上面是中断向量表.

    IsrIRQ 
    sub sp,sp,#4       ;reserved for PC
    stmfd sp!,{r8-r9}  
    ldr r9,=INTOFFSET
    ldr r9,[r9]
    ldr r8,=HandleEINT0
    add r8,r8,r9,lsl #2
    ldr r8,[r8]
    str r8,[sp,#8]
    ldmfd sp!,{r8-r9,pc}

    普通中断表的指针.

    InitStacks
    ;Don't use DRAM,such as stmfd,ldmfd......
    ;SVCstack is initialized before
    ;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
    mrs r0,cpsr
    bic r0,r0,#MODEMASK
    orr r1,r0,#UNDEFMODE|NOINT
    msr cpsr_cxsf,r1  ;UndefMode
    ldr sp,=UndefStack
    orr r1,r0,#ABORTMODE|NOINT
    msr cpsr_cxsf,r1  ;AbortMode
    ldr sp,=AbortStack

    orr r1,r0,#IRQMODE|NOINT
    msr cpsr_cxsf,r1  ;IRQMode
    ldr sp,=IRQStack
    orr r1,r0,#FIQMODE|NOINT
    msr cpsr_cxsf,r1  ;FIQMode
    ldr sp,=FIQStack

    bic r0,r0,#MODEMASK|NOINT
    orr r1,r0,#SVCMODE
    msr cpsr_cxsf,r1  ;SVCMode
    ldr sp,=SVCStack
    ;USER mode has not be initialized.
    mov pc,lr
    ;The LR register won't be valid if the current mode is not SVC mode.
    中断的栈问题

       AREA RamData, DATA, READWRITE

            ^   _ISR_STARTADDRESS
    HandleReset     #   4
    HandleUndef     #   4
    HandleSWI       #   4
    HandlePabort    #   4
    HandleDabort    #   4
    HandleReserved  #   4
    HandleIRQ       #   4
    HandleFIQ       #   4

    ;Don't use the label 'IntVectorTable',
    ;The value of IntVectorTable is different with the address you think it may be.
    ;IntVectorTable
    HandleEINT0     #   4
    HandleEINT1     #   4
    HandleEINT2     #   4
    HandleEINT3     #   4
    HandleEINT4_7   #   4
    HandleEINT8_23  #   4
    HandleRSV6      #   4
    HandleBATFLT    #   4
    HandleTICK      #   4
    HandleWDT       #   4
    HandleTIMER0    #   4
    HandleTIMER1    #   4
    HandleTIMER2    #   4
    HandleTIMER3    #   4
    HandleTIMER4    #   4
    HandleUART2     #   4
    HandleLCD       #   4
    HandleDMA0      #   4
    HandleDMA1      #   4
    HandleDMA2      #   4
    HandleDMA3      #   4
    HandleMMC       #   4
    HandleSPI0      #   4
    HandleUART1     #   4
    HandleRSV24     #   4
    HandleUSBD      #   4
    HandleUSBH      #   4
    HandleIIC       #   4
    HandleUART0     #   4
    HandleSPI1      #   4
    HandleRTC       #   4
    HandleADC       #   4

            END
    中断具体表.

    static void __irq KeyISR(void)
    {
    U8 key ;

    rGPGCON = rGPGCON & (~((3<<22)|(3<<6))) | ((0<<22)|(0<<6)) ;  //GPG11,3 set input
    rGPFCON = rGPFCON & (~((3<<4)|(3<<0))) | ((0<<4)|(0<<0)) ;  //GPF2,0 set input
    if(rINTPND==BIT_EINT8_23)
    {
      ClearPending(BIT_EINT8_23);
      if(rEINTPEND&(1<<11))
      {
       //puts("Interrupt eint11 occur...");
       rEINTPEND |= 1<< 11;
      }
      if(rEINTPEND&(1<<19))
      {
       //puts("Interrupt eint19 occur...");  
       rEINTPEND |= 1<< 19;
      }
    }
    else if(rINTPND==BIT_EINT0)
    {
      //puts("Interrupt eint0 occur...");
      ClearPending(BIT_EINT0);
    }
    else if(rINTPND==BIT_EINT2)
    {
      //puts("Interrupt eint2 occur...");
      ClearPending(BIT_EINT2);
    }

    //查询按键键值
    key = Key_Scan() ;
    if( key != 0xff )
      printf( "Interrupt occur... K%d is pressed!\n", key ) ;

    //Beep( 2000, 3000 ) ;

    //重新初始化IO口
    rGPGCON = rGPGCON & (~((3<<12)|(3<<4))) | ((1<<12)|(1<<4)) ;  //GPG6,2 set output
    rGPGDAT = rGPGDAT & (~((1<<6)|(1<<2)));  //GPG6,2 output 0
    rGPECON = rGPECON & (~((3<<26)|(3<<22))) | ((1<<26)|(1<<22));  //GPE13,11 set output
    rGPEDAT = rGPEDAT & (~((1<<13)|(1<<11)));  //GPE13,11 output 0
    rGPGCON = rGPGCON & (~((3<<22)|(3<<6))) | ((2<<22)|(2<<6)) ;  //GPG11,3 set EINT
    rGPFCON = rGPFCON & (~((3<<4)|(3<<0))) | ((2<<4)|(2<<0)) ;  //GPF2,0 set EINT
    }
    中断子函数,有四个中断源;实际上是三个中断源,在第三个中断分出了两个中断.中断可能初学者看的迷迷糊糊.好了中断就讲在这里.

    现在讲关于lcd显示动态的相册,由于照片的数据结构一定大于4k空间,所以在nandflash纯裸奔是不可能的.这个问题困饶我了很久,后来根据wince和linux启动的原理,我用bootloader(vivi)来启动我lcd裸奔程序,然后固化到nandflash当中即ce区或则是 kernel区.

       Lcd_Port_Init();
        puts("linshenghuan");
        Lcd_Init();
        Lcd_EnvidOnOff(1);  //turn on vedio

    DelayMs();
    Lcd_ClearScr(0x00);  //fill all screen with some color
    DelayMs();
    Lcd_ClearScr(0xF1F1); 
    DelayMs();
    Lcd_ClearScr(0x1F1F); 
    DelayMs();
      Lcd_ClearScr(0x00);
      Paint_Bmp( 0,0,240,320, xyx_240_320 ) ;  //paint a bmp

  • 相关阅读:
    Appium环境搭建-精简版
    Capability配置简介
    Appium简介
    MonkeyRunner 综合实践
    怎么将织梦图集模型编辑器改为文章编辑器?
    dedecms调用日期格式化形式大全
    让织梦内容页arclist标签的当前文章标题加亮显示
    DedeCMS中channelartlist自增参数global.itemindex
    织梦中在线显示pdf文件的方法
    如何修改DEDECMS文章标题长度
  • 原文地址:https://www.cnblogs.com/hnrainll/p/2065366.html
Copyright © 2011-2022 走看看