arm9代码分析启动main.c-u球体育app下载

单片机 > 单片机程序设计 > 详情

arm9代码分析启动main.c

发布时间:2025-02-27 发布时间:
|

  1 #define    global_clk        1

  2 

  3 #include

  4 #include

  5 #include “def.h”

  6 #include “option.h”

  7 #include “2440addr.h”

  8 #include “2440lib.h”

  9 #include “2440slib.h”

 10 #include “mmu.h”

 11 #include “profile.h”

 12 #include “memtest.h”

 13 

 14 //extern置于变量或函数之前,以标示变量或函数的定义在别的文件中

 15 extern char image$$ro$$limit[];

 16 extern char image$$ro$$base[];

 17 extern char image$$rw$$limit[];

 18 extern char image$$rw$$base[];

 19 extern char image$$zi$$limit[];

 20 extern char image$$zi$$base[];

 21 //ro是程序中的指令和常量;ro就是readonly,

 22 //rw是程序中的已初始化变量; rw就是read/write,   

 23 // zi是程序中的未初始化的变量;zi就是zero;

 24 //|image$$ro$$limit|:表示ro区末地址后面的地址,即rw数据源的起始地址

 25  //|image$$rw$$base|:rw区在ram里的执行区起始地址,也就是编译器选项rw_base指定的地址

 26  //|image$$zi$$base|:zi区在ram里面的起始地址

 27  //|image$$zi$$limit|:zi区在ram里面的结束地址后面的一个地址

 28  

 29 void isr_init(void);

 30 void haltundef(void);

 31 void haltswi(void);

 32 void haltpabort(void);

 33 void haltdabort(void);

 34 void clearmemory(void);

 35 

 36 void clk0_enable(int clock_sel);   

 37 void clk1_enable(int clock_sel);

 38 void clk0_disable(void);

 39 void clk1_disable(void);

 40 

 41 //extern置于变量或函数之前,以标示变量或函数的定义在别的文件中

 42 extern void lcd_tft_init(void);

 43 extern void lcd_tft_test( void ) ;

 44 extern void test_touchpanel(void) ;

 45 extern void test_adc(void) ;

 46 extern void keyscan_test(void) ;

 47 extern void rtc_display(void) ;

 48 extern void test_irda_tx(void) ;

 49 extern void playmusictest(void) ;

 50 extern void recordtest( void ) ;

 51 extern void test_iic(void) ;

 52 extern void test_sdi(void) ;

 53 extern void camera_test( void ) ;

 54 

 55 //volatile影响编译器编译的结果,指出volatile变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化。

 56 volatile u32 downloadaddress;

 57 

 58 //void (*restart)(void),定义一个指针,指针名为restart,指针指向函数,函数的返回类型为void

 59 // (void (*)(void))0×0,将0×0强制转换,使其符合等号左边的类型。

 60 void (*restart)(void)=(void (*)(void))0×0;

 61 

 62 volatile unsigned char *downpt;

 63 volatile u32 downloadfilesize;

 64 volatile u16 checksum;

 65 volatile unsigned int err=0;

 66 volatile u32 totaldmacount;

 67 

 68 volatile int isusbdsetconfiguration;

 69 

 70 int download_run=0;

 71 u32 tempdownloadaddress;

 72 int menuused=0;

 73 

 74 extern char image$$rw$$limit[];

 75 u32 *pmagicnum=(u32 *)image$$rw$$limit;

 76 int consolenum;

 77 

 78 /*在全局变量之前,加上关键字static,全局变量就被定义成为一个全局静态变量。

 79 1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)

 80 2)初始化:未经初始化的全局静态变量会被程序自动初始化为0

 81 3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地将从定义之处开始到文件结尾*/

 82 static u32 cpu_freq;

 83 static u32 upll;

 84 

 85  /*在函数的返回类型前加上关键字static,函数就被定义成为静态函数。

 86 函数的定义和声明默认情况下是extern的,但静态函数只是在声明它的文件当中可见,不能被其他文件使用。*/

 87 static void cal_cpu_bus_clk(void)

 88 {

 89     u32 val;

 90     u8 m, p, s;

 91     val = rmpllcon;

 92     m = (val>>12)&0xff;   // m=92=mdiv

 93     p = (val>>4)&0x3f;     // p=1=pdiv

 94     s = val&3;                  // s=1=sdiv

 95 

 96     //(m 8)*fin*2 不要超出32位数!

 97    /* 按照手册上面的计算,fout=2*m*fin/(p*2s),其中fin=12mhz。但m、p、s与上面的不一样。公式中m=mdiv 8,p=pdiv 2,s=sdiv

 98     (1<

 99    fin、fclk在option.h中定义,fin=12000000,经计算fclk=400mhz*/

100     fclk = ((m 8)*(fin/100)*2)/((p 2)*(1<

101     val = rclkdivn;

102     m = (val>>1)&3;//m=2=hdivn

103     p = val&1;        // p=1=pdivn

104     val = rcamdivn;

105    // 由于之前没有设置过camdivn寄存器,所以是默认值

106    s=0x0000_0000,其最后两位00,代表没移位之前的camdivn[9][8]

107     s = val>>8;

108     switch (m) {

109     case 0:

110         hclk = fclk;

111         break;

112     case 1:

113         hclk = fclk>>1;

114         break;

115     case 2:

116         if(s&2)

117             m=2,camdivn[9]=0,表示fclk:hck=1:4

118             hclk = fclk>>3;

119         else

120             hclk = fclk>>2;

121         break;

122     case 3:

123         if(s&1)

124             hclk = fclk/6;

125         else

126             hclk = fclk/3;

127         break;

128     }

129     if(p)

130         //p=1,表示hclk:pclk=1:2

131         pclk = hclk>>1;

132     else

133         pclk = hclk;

134     if(s&0×10)

135         cpu_freq = hclk;

136     else

137       // s=0,表示cpu频率等于fclk频率

138         cpu_freq = fclk;

139    // upllcon在main函数里没有设置,但在2440init里有设置

140     val = rupllcon;

141     m=56=mdiv

142     m = (val>>12)&0xff;

143     p=2=pdiv

144     p = (val>>4)&0x3f;

145     s=2=sdiv

146     s = val&3;

147    //upll的计算方法,同mpll一样,经计算知,upll=48mhz

148     upll = ((m 8)*fin)/((p 2)*(1<

149     /*根据2440init里clkval的值,clkdivn[3]=divn_upll=0

150     rclkdivn&8=0,所以uclk=upll=48mhz*/

151     uclk = (rclkdivn&8)?(upll>>1):upll;

152 }

153 

154 void temp_function() { uart_printf(“ please input 1-11 to select test!!! ”); }

155 

156    /* 定义一个结构体,没有结构体类型名称,但其结构体变量为cmdtip[],为一个数组。

157     结构体成员:

158            有一个指针,名为fun。其指向一个函数,函数的返回类型为void。

159            有一个指针,名为tip,其指向字符型。

160            函数的函数名就像数组名一样,其本身就是指针,代表函数的入口地址*/

161 struct {

162     void (*fun)(void);

163     char *tip;

164 }cmdtip[] = {

165                 { temp_function, “please input 1-11 to select test” } ,

166                 { buzzer_pwm_test, “test pwm” } ,

167                 { rtc_display, “rtc time display” } ,

168                 { test_adc, “test adc” } ,

169                 { keyscan_test, “test interrupt and key scan” } ,

170                 { test_touchpanel, “test touchpanel” } ,

171                 { lcd_tft_test, “test tft lcd” } ,

172                 { test_iic, “test iic eeprom” } ,

173                 { playmusictest, “uda1341 play music” } ,

174                 { recordtest, “uda1341 record voice” } ,

175                 { test_sdi, “test sd card” } ,

176                 { camera_test, “test cmos camera”},

177                 { 0, 0}                       

178             };


  1 void main(void)

  2 {

  3     char *mode;

  4     int i;

  5     u8 key;

  6     u32 mpll_val = 0 ;

  7     //u32 divn_upll = 0 ;

  8    /*#if如果给定条件为真,则编译下面代码,直到出现#else、#elif或#endif为止;否则就不编译。

  9    ads10在option.h定义,ads10=1,这段没有任何作用*/

 10     #if ads10  

 11 //    __rt_lib_init(); //for ads 1.0

 12     #endif

 13   /*s3c2440有130个管脚。可以通过软件配置每个管脚的功能来满足系统及外设的要求。所以在程序开始之前,你必须定义每个管脚的配置。

 14     端口初始化,设置gpa/b/c/d/e/f/g/h/j相应的管脚,extint0/1/2/3*/  

 15     port_init();

 16    /*设置中断服务程序,初始化。

 17     把所有中断设置为irq模式,屏蔽所有中断请求*/

 18     isr_init();

 19     i = 2 ;    //don’t use 100m!

 20     switch ( i ) {

 21     case 0:    //200

 22         key = 12;

 23         mpll_val = (92<<12)|(4<<4)|(1);

 24         break;

 25     case 1:    //300

 26         key = 13;

 27         mpll_val = (67<<12)|(1<<4)|(1);

 28         break;

 29     case 2:    //400

 30       // 设置时钟分频比的值,fclk:hclk:pclk

 31         key = 14;

 32      //  设置fclk的值,mdiv=92,pdiv=1,sdiv=1

 33         mpll_val = (92<<12)|(1<<4)|(1);

 34         break;

 35     case 3:    //440!!!

 36         key = 14;

 37         mpll_val = (102<<12)|(1<<4)|(1);

 38         break;

 39     default:

 40         key = 14;

 41         mpll_val = (92<<12)|(1<<4)|(1);

 42         break;

 43     }

 44     //init fclk=400m, so change mpll first

 45     /*此函数在2440lib.c中定义。改变mpllcon的值,mpll的值影响fclk。

 46     但是设置mpll,在2440init.s已经完成了,也是fclk=400mhz*/

 47     changempllvalue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

 48     /*设置mpllcon后,得到fclk的值。再设置clkdivn,得到hclk、pclk的值此函数在2440lib.c中定义。使得fclk:hclk:pclk=1:4:8。如果fclk:hclk!=1:1,还要执行,

        mmu_setasyncbusmode()。同2440init.s一样*/

 49     changeclockdivider(key, 12);

 50    //计算fclk、hclk、pclk、uclk、cpu_freq

 51     cal_cpu_bus_clk();

 52     consolenum = 0;    // uart 1 select for debug.

 53     //uart初始化。此函数定义在2440lib.c

 54     uart_init( 0,115200 );

 55     /*s3c2440共有三个uart。在2440lib.c的静态变量whichuart=consolenum。在此选择uart0*/

 56     uart_select( consolenum );

 57    //蜂鸣声

 58     beep(2000, 100);

 59    // 发送字节的函数

 60     uart_sendbyte(‘ ’);

 61    // 显示字符串的函数

 62     uart_printf(“ ”);

 63     uart_printf(“               tq2440 test program ”);

 64     uart_printf(“                www.embedsky.net ”);

 65 //    uart_printf(“      build time is: %s  %s ”, __date__ , __time__  );

 66     uart_printf(“ ”);

 67 

 68   /*指针变量,本质上是一个变量,只是它是存放地址的变量,指针的类型代表的是它所指向的变量的类型。因此就有了指向整型、字符型、浮点型等其他类型的指针,但实际上所有类型的

 69     指针变量存放的都是int型的地址。因此从本质上不同类型的指针变量并没有区别。到底声明不同类型的指针变量的背后是什么?其实声明不同类型的指针变量即是规定了该变量结合指针

 70     运算符时读取内存中的字节数,同样在指针移动和指针的运算(加、减),在内存中移动的最小字节数。rmisccr在2440addr中定义。

72     其原型为 #define rmisccr (*(volatile unsigned *)0×56000080)。0×56000080为寄存器misccr的地址值。

 73     *(volatile unsigned *)0×56000080 含义:因为()优先级高于*,所以先执行(volatile unsigned *)0×56000080 这个表示将0×56000080强制转化为指针类型,指针指向的

 74     类型是unsigned,指针存放的地址为0×56000080。也就是说指针指向寄存器misccr。然后在执行()外面的*,表示取出指针所指向的值。整个表达式,就是取出寄存器misccr中存放

 75     的值。但rmisccr的值改变,寄存器misccr中的值也随着改变。清零misccr[3],即use usb1 as device*/

 76     rmisccr=rmisccr&~(1<<3); // usbd is selected instead of usbh1

 77     //清零misccr[13],即usb port1 suspend mode=normal mode

 78     rmisccr=rmisccr&~(1<<13); // usb port 1 is enabled.

 79 

 80     rdsc0 = 0x2aa;

 81     rdsc1 = 0x2aaaaaaa;

 82     //enable nand, usbd, pwm timer, uart0,1 and gpio clock,

 83     //the others must be enabled in os!!!

 84     rclkcon = 0xfffff0;

 85 

 86    //内存存储管理。裸奔暂时用不上

 87    mmu_init();    //

 88 

 89     isr_startaddress=0x33ff_ff00

 90    // 将值(0x33ff_ff00 0xf0)的值,载入到pisr_swi的地址中(0x33ff_ff00 0×8)  

 91     pisr_swi=(_isr_startaddress 0xf0);    //for psos

 92 

 93     gpb5=nled1,gpb6=nled2,gpb7=nled3,gpb8=nled4

 94    // led2、3亮   

 95     led_display(0×66);

 96 

 97     mode=”dma”;

 98 

 99     //将gph9设置为input,其值为10时,管脚功能是clkout0

100     clk0_disable();

101    // 将gph10设置为input,其值为10时,管脚功能是clkout1

102     clk1_disable();

103     mpll_val = rmpllcon;

104 

105     lcd_tft_init() ;        // lcd initial

106     download_run=1; //the default menu is the download & run mode.

107 

108     while(1)

109     {

110         u8 idx;

111         uart_printf(“ please select function : ”);   

112         for(i=0; cmdtip[i].fun!=0; i )

113             uart_printf(“%d : %s ”, i, cmdtip[i].tip);

114         idx = uart_getintnum_gj() ;   

115         if(idx

116         {

117             (*cmdtip[idx].fun)();

118             delay(20);

119             uart_init( 0,115200 );

120         }   

121     }         

122 

123 }



 1 void isr_init(void)

 2 {

 3     /*pisr_undef在2440addr.h中定义。

 4     _isr_startaddress在option.h中定义。_isr_startaddress=0x33ff_ff00*/

 5     #define pisr_undef (*(unsigned *)(_isr_startaddress 0×4))//取出undef中断服务程序地址中的内容

 6     //(unsigned)haltundef中haltundef为函数名,其代表函数的入口地址。

 7     //这条语句的意思就是将haltundef函数的入口地址放到undef中断程序服务地址中。

 8     pisr_undef=(unsigned)haltundef;

 9     pisr_swi  =(unsigned)haltswi;

10     pisr_pabort=(unsigned)haltpabort;

11     pisr_dabort=(unsigned)haltdabort;

12     //所有的中断都设置为irq模式

13     rintmod=0×0;      // all=irq mode

14     bit_allmsk=0xffff_ffff//在2440addr.h中定义

15     //屏蔽所有的中断的请求,这些中断就是intmod中的那些中断

16     rintmsk=bit_allmsk;      // all interrupt is masked.

17 }

18 

19 void haltundef(void)

20 {

21     uart_printf(“undefined instruction exception!!! ”);

22     while(1);

23 }

24 

25 void haltswi(void)

26 {

27     uart_printf(“swi exception!!! ”);

28     while(1);

29 }

30 

31 void haltpabort(void)

32 {

33     uart_printf(“pabort exception!!! ”);

34     while(1);

35 }

36 

37 void haltdabort(void)

38 {

39     uart_printf(“dabort exception!!! ”);

40     while(1);

41 }

42 

43 void clearmemory(void)

44 {

45     int memerror=0;

46     u32 *pt;

47     uart_printf(“clear memory (%xh-%xh):wr”,_ram_startaddress,heapend);

48 

49     pt=(u32 *)_ram_startaddress;

50     while((u32)pt < heapend)

51     {

52         *pt=(u32)0×0;

53         pt ;

54     }

55     if(memerror==0)uart_printf(“o.k. ”);

56 }

57 

58 void clk0_enable(int clock_sel)   

59 {    // 0:mpllin, 1:upll, 2:fclk, 3:hclk, 4:pclk, 5:dclk0

60     rmisccr = rmisccr&~(7<<4) | (clock_sel<<4);

61     rgphcon = rgphcon&~(3<<18) | (2<<18);

62 }

63 void clk1_enable(int clock_sel)

64 {    // 0:mpllout, 1:upll, 2:rtc, 3:hclk, 4:pclk, 5:dclk1   

65     rmisccr = rmisccr&~(7<<8) | (clock_sel<<8);

66     rgphcon = rgphcon&~(3<<20) | (2<<20);

67 }

68 void clk0_disable(void)

69 {

70     rgphcon = rgphcon&~(3<<18);    // gph9 input

71 }

72 void clk1_disable(void)

73 {

74     rgphcon = rgphcon&~(3<<20);    // gph10 input

75 }



『本文转载自网络,u球体育app下载的版权归原作者所有,如有侵权请联系删除』

热门文章 更多
stm32cubemx新建工程 基本io配置过程
网站地图