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

你可能感兴趣的:(ARM)