First of all, I would like to state that the debugging software I use is ADS1.2. After we have written the program, we need to compile and link it. Select the MAKE button in ADS1.2, and an Errors and Warnings dialog box will appear. The results of the compilation and linking will be displayed in this column. If there are no errors, you should be able to see Image component sizes at the end of the file, followed by the number of bytes of each item, Code, RO Data, RW Data, ZI Data, and Debug, and finally a statistical data of them:
Code 163632, RO Data 20939, RW Data 53, ZI Data 17028
Tatal RO size (Code+ RO Data) 184571 (180.25kB)
Tatal RW size(RW Data+ ZI Data) 17081(16.68 kB)
Tatal ROM size(Code+ RO Data+ RW Data) 184624(180.30 kB)
The number of bytes following this is based on the user's different programs. The following will use the above data as an example to explain the calculation of those variables.
In the Debug Settings of ADS, there is a column called Linker/ARM Linker. In the output option, there is an RO base option. There should be an address below it. In my case, it is 0x0c100000. The RW base address behind it is 0x0c200000. Then in the Options option, there is Image entry point, which is the entry address of the initial program. In my case, it is 0x0c100000.
With the above information, we can fully understand how these variables come from:
|Image$$RO$$Base| = Image entry point = 0x0c100000 ; indicates the starting address where the program code is stored
|Image$$RO$$Limit|=Program code starting address+code length+1=0x0c100000+Statal RO size+1
= 0x0c100000 + 184571 + 1 = 0x0c100000 +0x2D0FB + 1
= 0x0c12d0fc
|Image$$RW$$Base| = 0x0c200000 ; specified by RW base address
|Image$$RW$$Limit| = |Image$$RW$$Base| + RW Data 53 = 0x0c200000+0x37 (multiples of 4, 0 to 55, a total of 56 units)
=0x0c200037
|Image$$ZI$$Base| = |Image$$RW$$Limit| + 1 =0x0c200038
|Image$$ZI$$Limit| = |Image$$ZI$$Base| + ZI Data 17028
=0x0c200038 + 0x4284
=0x0c2042bc
It can also be calculated from:
|Image$$ZI$$Limit| = |Image$$RW$$Base| +TatalRWsize(RWData+ZIData) 17081
=0x0c200000+0x42b9+3 (must be a multiple of 4)
=0x0c2042bc
Original address http://blog.csdn.net/yyt7529/archive/2009/06/05/4245604.aspx
For simple applications, you do not need to write a .scf file. Instead, select "Simple" on the "Output" page. Then fill in the starting addresses of "RO Base" and "RW Base". On the "Lay Out" page, fill in Object/Symble: Startup.o, Section: Start. Write the startup file: Startup.s.
In the "Option" page, fill in the starting address in "Image Entry Point".
-------------------------------------------------- ----------------------------------
The structure of Scatter-Load Description File:
The "+RW" in the ".scf" file corresponds to the "READWRITE" in the ".s" source file.
"+ZI" in the ".scf" file corresponds to "NOINIT" in the ".s" source file.
"+RO" in the ".scf" file corresponds to "READONLY" in the ".s" source file.
In the ".s" source file there is:
AREA area_name CODE/DATA,READONLY/NOINIT/READWRITE
END
".scf" example
Contents Notes
ROM_LOAD 0x80000000
{ ;Name of Load Region, Start Address for Load Region and Maximum size of Load Region (omitted)
ROM_EXEC 0x80000000 0x20000
{ ; Off-chip storage area, starting from 0x80000000, up to 0x20000 bytes.
Startup.o(Vector,+First); The Vector segment of the Startup module is placed at the front. Note 1
*(+RO); All code and read-only data in all other modules are placed here.
}
IRAM 0x40000000 0x00004000
{ ; On-chip RAM area, starting from 0x40000000, up to 0x4000 bytes
Startup.o(MyStacks,+first); specifies that MyStacks in Startup.o is placed first.
Startup.o(+RW,+ZI); Other +RW/+ZI sections in Startup.o. Note 1
os_cpu_a.o(+RW,+ZI)
}
STACKS 0x40004000 UNINIT
{ ; The top of the on-chip 16K RAM stores segments that do not need to be initialized by the "C library".
Stack.o(+ZI) Note 2
}
ERAM 0x80040000
{
*(+RW,+ZI)
}
HEAP +0 UNINIT
{; "+0" means continuing from the end of the previous section "ERAM" and continuing to arrange the storage area.
Heap.o(+ZI) Note 3
}
}
The following is a sample of the source files referenced in the scf file: "Startup.s"
code 32
area Vectors,CODE,READONLY
entry
...
end Note 1: A segment named "Vectors" will be generated in "Startup.o", and the segment attribute is "READONLY"
"Stack.s"
area Stacks, DATA, NOINIT
export StackUsr
StackUsr SPACE 1
end Note 2: A segment named "Stacks" will be generated in "Stack.o" with the attribute "NOINIT", which corresponds to "+ZI" in the scf file. This segment does not need to be initialized or can be initialized to "0".
"Heap.s"
area Heap,DATA,NOINIT
export bottom_of_heap
bottom_of_heap SPACE 1
end Note 3: The segment named "Heap" in "Heap.o".
It is best to add a Maximum parameter to each Region in the Scatter file. In this way, when compiling, if the actual space used is larger than the Maximum Size, there will be an Error: 16220E: Excution region xxx size (xxx bytes) exceeds limit (xx bytes). If the address is repeated, there will be an Error: 16221E: Excution region xxx overlaps with excution region xxx. There may not be an Error when the first address of the previous Region + Maximum > the first address of the next Region. An Error will only occur when an allocated memory is overlapped.
Region's "UNINIT" and other parameters should be placed before the "Maximum size" parameter.
In a region, RAM is not allocated in the order listed. To make variables used in assembly have fixed positions, you can put ".o" generated by all assembly files in the same region. For example:
IRAM1 0x40000000
{
startup.o(+RW,+ZI)
ASMSourceCode1.o(+RW,+ZI)
ASMSourceCode2.o(+RW,+ZI)
}
IRAM2 +0
{
CSourceCode1.o(+RW,+ZI)
CSourceCode2.o(+RW,+ZI)
}
In this way, the addresses of variables defined in all assemblies are relatively concentrated.
If there is only one assembly file such as startup.s, it can also be like this:
IRAM 0x40002000 0x1000
{
startup.o (Mystack,+first)
*(+RW,+ZI)
}
Use a "+first" to force Mystack in startup.s to be placed at position 0x40002000.
Select "Image map" in "Edit -> DebugRel Settings...->ARM Linker". After compiling, detailed memory allocation will be displayed in the Error & Warnings window. If you specify an output file name in "List file name", the list will be directly saved in the specified file for multiple studies.
-------------------------------------------------- ----------------------------------
About JTAG interface:
P1.20/TRACESYNC should be pulled up with a resistor to disable the TRACE function. PINSEL2 must be initialized at the beginning of the program.
JTAG
Note
1,2/VDD3.3V
P1.31/nTRST, input 3/nTRST, output There are pull-up resistors in EasyJTAG.
P1.28/TDI, input 5/TDI, output There is a pull-up resistor in EasyJTAG.
P1.30/TMS, input 7/TMS, output There is a pull-up resistor in EasyJTAG.
P1.29/TCK, input/output 9/TCK, input/output There is a pull-up resistor in EasyJTAG.
P1.26/RTCK, input 11/RTCK, output P1.26 is connected to an external pull-down resistor.
P1.26 has an internal pull-up resistor, so the pin will be high when measured. However, during reset, its pull-up resistor does not work, only the external pull-down resistor works, P1.26 = 0V, so after power-on, D3~D0 of PINSEL2 will be 0x04 (B0100), and JTAG is valid.
If P1.26 is connected to 3.3V and then reset, D3~D0 of PINSEL2 will be 0x00 and JTAG will be invalid.
P1.27/TDO, output 13/TDO, input There is a pull-up resistor in EasyJTAG.
nRESET, input 15/nRST, output There is a pull-up resistor in EasyJTAG.
4,6,8,10,12,14,16,18,20/GND
17,19/NC
The G18 control board uses LPC2114, and the program will not be loaded correctly every time Axd is run. The reasons are as follows:
One time, there was already an Axd running, so when I opened the second Axd, the program would not be loaded correctly.
Another time I recompiled it and it was fine.
The above two times are not strange, but the following are strange:
In "Config Target -> Config -> Easy JTag Setup", randomly click the options in "Halt Mode" twice, then click "OK" all the way, and "Reload the last Image?" will appear, click "Yes". Sometimes the correct program will be loaded, but sometimes it will not be successful. To check whether it has been successfully loaded, just press "Ctrl-D" to display the Disassembly window, and you can see whether the program in the chip is correct.
Select "Reload Images" in "Option -> Config Interface -> Session File -> Session file Options". Every time you start Axd, you will be prompted with "The processor ARM_1 already has image(s) loaded. Continue the operation will replace the currently loaded images(s).... Do you wish to continue?" Select "Yes". Sometimes the program can be loaded successfully.
Of course, in "Easy JTag Setup -> Aux Option" check "Erase Flash when need".
The fixed program has a statement to disable the JTag debug port (a statement to operate PINSEL2). When it fails to connect, I use LPC2000 Flash Utility to erase the Flash. It works occasionally.
Note that when using LPC2000 Flash Utility, you must reset the circuit first, then click "OK".
Of course, the most fundamental solution is to set the computer parallel port to "EPP" mode. All other places can be set to "Default".
-------------------------------------------------- ----------------------------------
Valid user codes:
ARM uses "the sum of all 32-bit data in the vector table is 0" as the condition for valid user code. This only applies when using on-chip program memory. There is no such limitation for off-chip program memory.
C language programs usually require a section of assembly code for initialization, usually stored as "Startup.s", which usually implements the following tasks:
1. Make a good interrupt vector table
2. Initialize the external bus controller/stack/target board basic modules.
3. "__user_inital_stackheap" for library functions.
4. Infinite loop "__rt_div0: B __rt_div0" when the divisor is zero.
5. Support encryption function statements.
6. Define stack space: AREA MyStacks, DATA, NOINIT, ALIGN = 2
To define the starting address of the stack: IrqStackSpace SPACE ...
And the head of the stack: StackIrq DCD IrqStackSpace + Length*4. Because the stack grows downwards.
The initialization program related to the target board can be placed in a file named "Target.c".
1. Define interrupt processing entry: void IRQ_Exception(void), void FIQ_Exception(void), void Timer0_Exception(void).
2. Initialize the vector interrupt controller.
3. remap, system clock, real-time clock, memory acceleration.
-------------------------------------------------- ----------------------------------
Delay in C language:
__asm{
nop;
nop;}
That's it.
Note for C compilers: The priority of "==" is indeed higher than that of "&", so for anything involving logic, use "()" to confirm the priority to avoid low-level errors.
-------------------------------------------------- ----------------------------------
Operation of timer:
void Timer0Init(uint8 VICSlot, uint32 fdiv)
{
T0PR = 0; //Prescaling = 0
T0PC = 0; //Prescalar Counter
T0TC = 0; //T0 Counter
T0MR0 = Fpclk / fdiv; //Counting cycle
T0MCR = 0x03; //When the count reaches T0MR0, the interrupt is set, the counter is reset and continues to run.
T0CCR = 0x00; //No capture mode
T0TR = 0xffffffff; // Clear interrupt
T0TCR = 0x01; //Run
if(VICSlot <= 15){
*((uint32*)(&VICVectAddr0 + VICSlot)) = (uint32)Timer0_Exception;
*((uint32*)(&VICVectCntl0 + VICSlot)) = 0x20 | 0x04;
VICIntEnable = 1 << 0x04;
}
}
Notice:
1. In "*((uint32*)(&VICVectAddr0 + VICSlot)) = ...", &VICVectAddr0 is used as the base address and VICSlot is used as the offset. Since (uint32*) has been used to declare that this is a pointer to uint32, each change in the offset means that the address has changed by 4 bytes. When the base address and the offset are added, the system automatically multiplies VICSlot by 4. If you write "... + 4 * VICSlot" in the program, it is wrong.
2. Be sure to use "Fpclk / fdiv" to set the delay to 1/fdiv seconds. This parameter cannot be in uS. If "Fpclk * us / 1000000" is used, multiplication overflow will occur during calculation, which is difficult to avoid and there is no warning, so it cannot be used.
-------------------------------------------------- ----------------------------------
Setting the I2C duty cycle:
I2SCLH = (Fpclk / fi2c + 1) / 2;
I2SCLL = (Fpclk / fi2c) / 2;
Wonderful! No matter "Fpclk / fi2c" is odd or even, the unilateral "Fpclk / fi2c + 1" makes the total I2C cycle "Fpclk / fi2c = I2SCLH + I2SCLL" methodically error-free.
I2C must work in interrupt mode. Because: "When the "SI" flag is reset, no serial interrupt is requested, and there is no stretching of the serial clock on the SCL line."
I2C information is at http://www.semiconductors.philips.com/acrobat/various/8xC552_562OVERVIEW_2.pdf.
-------------------------------------------------- ----------------------------------
Macro application:
In the process of setting up on-chip peripherals such as I2C, UART, T0, T1, SPI, some setting values need to be calculated based on Fpclk. I hate using ARM to do division, so I use macros to implement it, and the division can be completed at compile time.
First, the initialization routines for all on-chip peripherals are named "void _xxxInit();". The reason for adding an "_" before the formal function name is to distinguish it from the macro so as not to write the function by mistake. Because the macro name is the same as the function name, it is just all capitalized and there is no "_" in front of it. For example:
#define TIMER0INIT(VICSlot,ms) _Timer0Init(VICSlot,Fpclk/100*ms/10);
void _Timer0Init(uint8 VICSlot,uint32 ClockCycle);
In the function, just set "T0MR0 = ClockCycle".
Note that the expression in the macro cannot be written as "Fpclk*ms/1000". If it is written like this, when mS is too large, for example, mS=1000, Fpclk*mS=(11059200/4)*1000=0xA4CB8000, the compiler will consider it an overflow (it regards the calculation result as a signed number). As long as an overflow warning appears, the setting is incorrect.
You should also not do division first to prevent loss of precision, which will result in the calculation result being "0" and causing the timer to die.
In short, calculation accuracy must be guaranteed, and overflow warnings must not appear.
-------------------------------------------------- ----------------------------------
Regarding the stack settings used by the C compiler:
1. There is a sentence in Startup.s:
MSR CPSR_C,#0x5f //System mode
LDR SP, =UsrStack //User stack
2. In the Scatter file, there is
STACKS 0x40004000 UNINT
{
UsrStack.o(+ZI)
}
3. In UsrStack.s there is
AREA Stacks, DATA, NOINT
EXPORT UsrStack
UsrStack SPACE 1
END
Define a UsrStack, the size doesn't matter, put it at the top of the available physical memory. When the C compiler compiles a subroutine call, it pushes the registers to be protected onto the stack, such as:
stmfd r13!,{r3-r7,r14}
Among them, the alias of r13 is SP.
This is a full descending stack, that is, the data in the unit pointed to by SP is valid, and when pushing data into the stack, SP is decremented before storing the data.
Previous article:The driver module in arm is loaded and called by the application
Next article:ARM scatter-loading files
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Participate in the Tektronix Probe Revealing Action and Share the 2019 New Year Red Packet
- Looking for the official SDK of HiSilicon's HI3518EV300
- Temperature Measurement Record--Comparative Measurement
- TMS570x/RM4x LaunchPad: Basic setup of MIBSPI loopback mode based on examples
- [ATmega4809 Curiosity Nano Review] Serial port application preliminary: printing sine string through serial port
- MSP430 power saving mode wake-up method
- The magnetic field on the surface of a cylindrical magnet is 4000Gs. Ten of the same type of magnets stacked in the same direction have a magnetic field of only 5400GS.
- A collection of seven voltage regulator diode application circuits
- Disadvantages of Too Large Bootstrap Capacitor in DC-DC Circuits
- DSP system design - clock and power supply related issues