• 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

  • 相关阅读:
    48. Rotate Image
    83. Remove Duplicates from Sorted List
    46. Permutations
    HTML5笔记
    18. 4Sum
    24. Swap Nodes in Pairs
    42. Trapping Rain Water
    Python modf() 函数
    Python min() 函数
    Python max() 函数
  • 原文地址:https://www.cnblogs.com/hnrainll/p/2065366.html
Copyright © 2020-2023  润新知