ARM9 code analysis starts MAIN.C

Publisher:梦幻微笑Latest update time:2016-12-30 Source: eefocusKeywords:ARM9 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

  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 is placed before a variable or function to indicate that the definition of the variable or function is in another file

 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 is an instruction and constant in the program; RO is readonly,

 22 //RW is an initialized variable in the program; RW is read/write,   

 23 // ZI is an uninitialized variable in the program; ZI is zero;

 24 //|Image$$RO$$Limit|: indicates the address after the end address of the RO area, that is, the starting address of the RW data source

 25 //|Image$$RW$$Base|: The starting address of the execution area of ​​the RW area in RAM, that is, the address specified by the compiler option RW_Base

 26 //|Image$$ZI$$Base|: The starting address of the ZI area in RAM

 27 //|Image$$ZI$$Limit|: The address after the end address of the ZI area in RAM

 28  

 29 void Isr_Init(void);

 30 void HaltUndef(void);

 31 void HaltSwi(void);

 32 void HaltPabort(void);

 33 void HaltAbort(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 is placed before a variable or function to indicate that the definition of the variable or function is in another file

 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 affects the results of compiler compilation, indicating that volatile variables may change at any time. Operations related to volatile variables should not be compiled and optimized.

 56 volatile U32 downloadAddress;

 57 

 58 //void (*restart)(void), defines a pointer named restart, which points to a function whose return type is void

 59 // (void (*)(void))0×0, force conversion of 0×0 to conform to the type on the left side of the equal sign.

 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 /*Add the keyword static before the global variable, and the global variable will be defined as a global static variable.

 79 1) Location in memory: static storage area (static storage area exists during the entire program execution)

 80 2) Initialization: Uninitialized global static variables will be automatically initialized to 0 by the program

 81 3) Scope: Global static variables are not visible outside the file where they are declared. Exactly from the point of definition to the end of the file*/

 82 static U32 cpu_freq;

 83 static U32 UPLL;

 84 

 85 /*Add the keyword static before the return type of the function, and the function will be defined as a static function.

 86 Function definitions and declarations are extern by default, but static functions are only visible in the file in which they are declared and cannot be used by other files. */

 87 static void cal_cpu_bus_clk(void)

 88 {

 89 U32 selections;

 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 Do not exceed 32 digits!

 97 /* According to the calculation in the manual, Fout=2*m*Fin/(p*2s), where Fin=12MHz. But m, p, s are different from the above. In the formula, m=MDIV+8, p=PDIV+2, s=SDIV

 98 (1<

 99 FIN, FCLK are defined in option.h, FIN=12000000, calculated 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 // Since the CAMDIVN register has not been set before, it is the default value

106 s=0x0000_0000, the last two digits 00 represent CAMDIVN[9][8] before shifting

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, indicating 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, indicating 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, indicating that the CPU frequency is equal to the FCLK frequency

138         cpu_freq = FCLK;

139 // UPLLCON is not set in the Main function, but is set in 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 //The calculation method of UPLL is the same as MPLL. After calculation, we know that UPLL=48MHz

148     UPLL = ((m+8)*FIN)/((p+2)*(1<

149 /*According to the value of CLKVAL in 2440init, CLKDIVN[3]=DIVN_UPLL=0

150 rCLKDIVN&8=0, so UCLK=UPLL=48MHz*/

151     UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;

152 }

153 

154 void Temp_function() { Uart_Printf(“\nPlease input 1-11 to select test!!!\n”); }

155 

156 /* Define a structure without a structure type name, but its structure variable is CmdTip[], which is an array.

157 Structure members:

158 There is a pointer named fun, which points to a function whose return type is void.

159 There is a pointer named tip, which points to a character type.

160 The function name of a function is like an array name, which is itself a pointer and represents the entry address of the function*/

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 If the given condition is true, compile the following code until #else, #elif or #endif appears; otherwise do not compile.

  9 ADS10 is defined in option.h, ADS10=1, this section has no effect*/

 10     #if ADS10  

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

 12     #endif

 13 /*S3C2440 has 130 pins. The function of each pin can be configured by software to meet the requirements of the system and peripherals. So before the program starts, you must define the configuration of each pin.

 14 Port initialization, set the corresponding pins of GPA/B/C/D/E/F/G/H/J, EXTINT0/1/2/3*/  

 15     Port_Init();

 16 /*Set interrupt service routine and initialize.

 17 Set all interrupts to IRQ mode and shield all interrupt requests*/

 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 // Set the clock division ratio, FCLK:HCLK:PCLK

 31         key = 14;

 32 // Set the value of 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 /*This function is defined in 2440lib.c. Changing the value of MPLLCON, the value of MPLL affects FCLK.

 46 But setting MPLL has been completed in 2440init.s, and FCLK=400Mhz*/

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

 48 /*After setting MPLLCON, get the value of FCLK. Then set CLKDIVN to get the value of HCLK and PCLK. This function is defined in 2440lib.c. Make FCLK:HCLK:PCLK=1:4:8. If FCLK:HCLK!=1:1, execute again.

        MMU_SetAsyncBusMode(). Same as 2440init.s*/

 49     ChangeClockDivider(key, 12);

 50 //Calculate FCLK, HCLK, PCLK, UCLK, cpu_freq

 51     cal_cpu_bus_clk();

 52     consoleNum = 0;    // Uart 1 select for debug.

 53 //UART initialization. This function is defined in 2440lib.c

 54     Uart_Init( 0,115200 );

 55 /*S3C2440 has three UARTs. In the static variable whichUart=consoleNum of 2440lib.c, select UART0 here*/

 56     Uart_Select( consoleNum );

 57 //Beep

 58     Beep(2000, 100);

 59 // Function to send bytes

 60     Uart_SendByte(‘\n’);

 61 // Function to display string

 62     Uart_Printf(“<***************************************>\n”);

 63     Uart_Printf(“               TQ2440 Test Program\n”);

 64     Uart_Printf(“                www.embedsky.net\n”);

 65 //    Uart_Printf(“      Build time is: %s  %s\n”, __DATE__ , __TIME__  );

 66     Uart_Printf(“<***************************************>\n”);

 67 

 68 /*A pointer variable is essentially a variable, but it is a variable that stores an address. The type of the pointer represents the type of the variable it points to. Therefore, there are pointers to integers, characters, floating-point types, and other types, but in fact all types

 69 Pointer variables store int addresses. Therefore, there is no difference between different types of pointer variables. What is behind declaring different types of pointer variables? In fact, declaring different types of pointer variables is to specify the variable in combination with the pointer.

 70 operator, and also the minimum number of bytes moved in memory during pointer movement and pointer operations (addition and subtraction). rMISCCR is defined in 2440addr.

72 Its prototype is #define rMISCCR (*(volatile unsigned *)0×56000080). 0×56000080 is the address value of register MISCCR.

 73 *(volatile unsigned *)0×56000080 Meaning: Because () has a higher priority than *, (volatile unsigned *)0×56000080 is executed first. This means that 0×56000080 is forced to be converted to a pointer type. The pointer points to

 74 The type is unsigned, and the address of the pointer is 0×56000080. That is, the pointer points to the register MISCCR. Then the * outside the execution () indicates to take out the value pointed to by the pointer. The whole expression is to take out the value stored in the register MISCCR.

 75. However, when the value of rMISCCR changes, the value in register MISCCR also changes. Clear MISCCR[3], that is, use USB1 as device*/

 76     rMISCCR=rMISCCR&~(1<<3); // USBD is selected instead of USBH1

 77 // Clear MISCCR[13], that is, 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 //Memory storage management. Naked streaking is not used for the time being

 87    MMU_Init();    //

 88 

 89     ISR_STARTADDRESS=0x33ff_ff00

 90 // Load the value (0x33ff_ff00+0xf0) into the address of 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 are on   

 95     Led_Display(0×66);

 96 

 97     mode=”DMA”;

 98 

 99 //Set GPH9 to input. When its value is 10, the pin function is CLKOUT0

100     Clk0_Disable();

101 // Set GPH10 to input. When its value is 10, the pin function is 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(“\nPlease select function : \n”);   

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

113             Uart_Printf(“%d : %s\n”, 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 is defined in 2440addr.h.

 4 _ISR_STARTADDRESS is defined in option.h. _ISR_STARTADDRESS=0x33ff_ff00*/

 5 #define pISR_UNDEF (*(unsigned *)(_ISR_STARTADDRESS+0×4))//Get the content of UNDEF interrupt service routine address

 6 //(unsigned)HaltUndef, where HaltUndef is the function name, represents the entry address of the function.

 7 //This statement means to put the entry address of HaltUndef function into the UNDEF interrupt program service address.

 8 pISR_UNDEF=(unsigned)HaltUndef;

 9     pISR_SWI  =(unsigned)HaltSwi;

10     pISR_PABORT=(unsigned)HaltPabort;

11 pISR_DABORT=(unsigned)HaltDabort;

12 //All interrupts are set to IRQ mode

13     rINTMOD=0×0;      // All=IRQ mode

14 BIT_ALLMSK = 0xffff_ffff // defined in 2440addr.h

15 //Shield all interrupt requests, these interrupts are those in INTMOD

16     rINTMSK=BIT_ALLMSK;      // All interrupt is masked.

17 }

18 

19 void HaltUndef(void)

20 {

21     Uart_Printf(“Undefined instruction exception!!!\n”);

22     while(1);

23 }

24 

25 void HaltSwi(void)

26 {

27     Uart_Printf(“SWI exception!!!\n”);

28     while(1);

29 }

30 

31 void HaltPabort(void)

32 {

33     Uart_Printf(“Pabort exception!!!\n”);

34     while(1);

35 }

36 

37 void HaltAbort(void)

38 {

39     Uart_Printf(“Dabort exception!!!\n”);

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(“\b\bO.K.\n”);

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 }


Keywords:ARM9 Reference address:ARM9 code analysis starts MAIN.C

Previous article:Design of infrared digital image acquisition alarm system
Next article:Introduction to STM32 input capture

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号