arm 裸奔经验

来源:互联网 发布:c语言中文网 编辑:程序博客网 时间:2024/05/01 08:18

 

    由于自己买的开发板的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

我就写点lcd.c文件了主要显示的语句,子函数就不写了,如果谁需要给我发邮件:本人油箱 linsheng_111@163.com

本程序主要功能就是先刷三种颜色的屏,在显示我的照片.