Automatically initialize the data segment in MAX-IDE

Automatically initialize the data segment in MAX-IDE

Abstract: This application note discusses the flexible tools for programs and data segments provided by MAX-IDE for application programming of MAXQ® microcontrollers. The program and data segment mechanism can automatically declare variable positions in the data memory and initialize these variables with the starting value. The application can cache the values ​​of these variables in the flash memory and restore the data if needed. This method allows applications based on assembly language to take full advantage of the automatic loading of data segments provided by MAX-IDE, regardless of whether the microcontroller is connected to the JTAG debugger or not. The MAXQ2000 microcontroller evaluation board can demonstrate this solution, and this article gives the corresponding routines.

Overview Variables in the MAXQ assembler can be stored in working registers (such as accumulators A [0] to A [15]) or data memory (SRAM). Storing variables in the data memory can provide a larger working area for application variables, but requires additional access time.

The MaxQAsm compiler and the MAX-IDE environment provide a mechanism for declaring the program segment and data segment separately, and generate respective hex output files for each segment. When running, MAX-IDE automatically loads the program segment file to the program memory (usually flash memory), and loads the data segment file to the data memory (usually RAM). However, because the data memory is volatile memory, once the microcontroller is powered down, the contents of the data segment will be lost.

This article uses the MAXQ2000 EV (evaluation) board to first demonstrate how to save preloaded data memory values ​​into flash memory when the application starts, and then demonstrate how to refresh the data segment from flash memory when the microcontroller is powered up again. Whether the application is in the development stage (connected to the JTAG adapter and MAX-IDE) or running in the field, these two steps allow the same data segment mechanism to be used to declare and initialize variables.

The examples in this application note are written for the MAXQ2000 microcontroller and the MAXQ2000 evaluation board, but the corresponding procedures and principles are applicable to any microcontroller based on MAXQ20 that can reprogram the flash memory.

Provide the latest version of the installation software and documents about the MAX-IDE environment, which can be downloaded for free. MAX-IDE installer MAXQ core compilation guide development tools guide Variables and storage locations Embedded applications usually require a certain work area to store state information, configuration data, intermediate data, loop counters, and calculation results. The data stored in this work area is usually used as a variable and has the following characteristics. They are temporary data. If the application program is interrupted due to power failure or reset, there is no need to save these data. They can be accessed and updated frequently. They must be stored in locations that can be read and written quickly; the number of writes to these locations must be unlimited. They have defined initial values. When the program starts to run, the user program must set them to specific values. Programs written in C or other high-level languages ​​are compiled into assembly code, and the compiler usually automatically allocates space for the variables (while initializing the variables to a pre-defined starting value). In this case, the user only needs to declare variables, variable types and their initial values ​​(optional), and the rest is handled by the compiler. unsigned int c = 0x1234; However, when writing applications in MAXQ assembly language, you must explicitly specify the variable allocation space and set the variable initial value. These details can strictly control the resources of the MAXQ microcontroller, but increase the complexity of the system.

For small assembly-based applications or applications that do not require a large amount of work area, internal registers can be used to store all application variables. This method has two important advantages: the program structure is compact and the running speed is fast. According to the register position, register variables can be read, written, or copied within one instruction cycle. For a microcontroller based on MAXQ20, under worst operating conditions, it usually takes up to two instruction cycles at most. Directly manipulate variables. Can directly operate some internal registers. For example, any of the 16 working accumulators A [0] to A [15] can be selected (using the AP register) as the effective accumulator Acc. This means that if you need to operate on a variable stored in these registers, you can directly operate on the register without copying the data out and then copying the data back. Similarly, when the djnz instruction is executed, the variables stored in the LC [0] and LC [1] registers can be used directly as the loop counter. For large-scale applications or when the application requires a large number of working variables, some or all of these variables can be stored in SRAM-based data storage. This method allows more variables to be created, limited by the space of the data memory. Variables stored in this way can be accessed through the MAXQ20 core ’s standard data pointer, which is used to read or write byte-width or word-width variables (Note: The routines in this application note assume DP [0] is configured to work In word mode). move DP [0], # 0010h; LocaTIon of variable in data memory move Acc, @DP [0]; Read variable add # 1; Increment variable value by 1 move @DP [0], Acc; Store variable back in data memory When performing a series of long calculation operations on a variable, you can first copy the variable value to the working register, as shown in the above routine. All intermediate operations can be performed using this working register, and the variable value is copied back after the calculation is completed. The MAX-IDE segment declaration determines how to determine the storage address of variables when storing application variables in SRAM-based data storage?

In general, all data storage can be used by the application except for the maximum 32 bytes of storage space used by the debugger. This means that a variable can be declared to define its location in data memory. The program can read and write variables through this address, and use the #define macro command to associate the variable address with the symbol name. #define VarA # 0020h #define VarB # 0021h #define VarC # 0022h move DP [0], VarA; Point to VarA variable move Acc, @DP [0]; Read value of variable move DP [0], VarB; Point to VarB variable move @DP [0], Acc; Copy VarA to VarB move DP [0], VarC; Point to VarC variable move @DP [0], # 1234h; Set VarC = 1234h This scheme works well, However, there are several issues that need attention. The address of each variable must be defined in advance. This work is time-consuming, especially when it is determined that all variables are subsequently moved to different data storage areas. It must be noted that more than one variable should not occupy the same address. If such an error occurs, it will be difficult to track down these faults. The initial (start) value of the variable must be loaded by the application program, as in the last line of the above program. If there are multiple variables initialized in this way will take up a lot of program space. A more effective solution is to use the MAX-IDE mechanism to declare the program segment and data segment separately. This method allows programmers to specify which part of the assembler is defined as program space and which part is defined as data space. segment code move DP [0], #VarA; Point to VarA move Acc, @DP [0]; Get current value of VarA add # 1; Increment it move @DP [0], Acc; Store value back in VarA segment data VarA: dw 0394h; IniTIal value for VarA Using the above scheme, the variable address declared in the data segment is automatically specified when the compiler parses the file, and the address label is allocated to the program space in the same way. The label is used to specify the symbol name for the variable address. The dw and db declarations can be used to set the initial value of the word width or byte width when the variable is initialized. In this case, assuming that there is no segment data instruction in advance in the assembly file, the compiler will start the data segment from address 0000h. This means that VarA will be stored at the word address 0000h. For the program space, the org statement will force the variable to be stored starting from the specified starting address.

Data segment initialization In the previous program list, the initial value of the variable VarA definition (declared with dw) is 0394h. However, this value is not loaded into VarA in the program. So, how to initialize this value? The answer is that when compiling and running the project, MAX-IDE will automatically perform data segment initialization.

The MaxQAsm compiler responds to the segment data instruction by generating a secondary hex output file. Usually, the hex file generated for the project contains program data. For example, if the project "example.prj" is compiled, a hex file named "example.hex" will be generated, and it contains the program data generated by compiling the project file. If a data segment is defined, an additional hex file named "example_d.hex" will be generated, which contains the compiled data for the segment.

When executing a project, MAX-IDE checks whether a data segment file (ending with _d.hex) was generated during project compilation. If there is a data segment file, MAX-IDE loads the segment data into the device's data SRAM through a standard JTAG loader. This process is performed after the standard hex file is loaded into the program memory.

This scheme works well in the development stage. When the device is connected to the JTAG adapter, MAX-IDE reloads the program data and segment data before the application program runs. However, once the device is powered down and re-powered, and allows independent operation (no debugger connected), MAX-IDE will not be able to load the data segment correctly before each operation. The variable cannot be set to the required value, which causes the application to fail to execute correctly. This kind of failure is difficult to analyze, because once the device is reconnected to the debugger, MAX-IDE will restart loading the data segment before each run, and the problem will disappear.

A remaining problem with saving and restoring data segments is how to keep the application working when it is connected to the debugger (MAX-IDE reloads the program and data before each run) and independently (the RAM contents are uncertain after power on). Obviously, the solution requires two steps: the application saves the variable values ​​(once initialized) to flash memory, and reloads these values ​​after each reset or power-up.

For the first step, the application must save the value to flash memory. This operation is executed every time the host runs the application for the first time after erasing or loading the program. The application checks the "flag" position to verify that the variable was previously copied into flash memory. This flag can be stored in a special function, non-volatile memory, or shared memory with a variable, as long as the variable has a non-zero initial value (distinguished from an empty RAM address). The application program copies the value of each variable from the data RAM to the flash memory. Most MAXQ microcontrollers with rewriteable flash memory (such as the MAXQ2000) use the UROM_flashWrite function. The application program writes a flag in the flash memory to indicate that the variable has been stored. For the second step, in the subsequent program operation, the application program must reload the variables from the flash memory to the predetermined data RAM address. The application checks the location of the flash memory flag to verify that the variable has been stored. The application program uses the UROM_copyBuffer subroutine to copy variables from the flash memory to the correct location of the data RAM. The following program list shows the save-restore scheme using the MAXQ2000 evaluation board. In this program, the variable values ​​are stored in the flash memory at addresses 7000h–71FFh. $ include (maxQ2000.inc) ;; Code memory (flash): 0000h-7FFFh (word addr) ;; Data memory (RAM): 0000h-03FFh (word addr) org 0000h ljump start; Skip over password area org 0020h start: move DPC, # 1Ch; Set all pointers to word mode move DP [0], # 0F000h; Check first variable value (flag) lcall UROM_moveDP0; 'move GR, @DP [0]' executed by UTIlity ROM move Acc, GR cmp # 1234h jump NE, copyToFlash ;; This is the "free-running" code, executed on subsequent power-ups, that copies ;; values ​​from the flash back into their proper data segment locaTIons. Move DP [0], # 0F000h; Source: Flash location 7000h move BP, # 0; Dest: Start of RAM move Offs, # 0 move LC [0], # 100h; Copy 256 words lcall UROM_copyBuffer jump main ;; This is the first-pass code. A bit of a trick here; because MAX-IDE enters ;; and exits the loader separately when loading the code and data segment files, ;; the application is allowed to execute briefly before the data segment file ;; has been loaded. The first four lines under co pyFlash ensure that the ;; application waits for MAX-IDE to load the data segment file before continuing. copyToFlash: move DP [0], # 0h; Wait for flag variable to be loaded by MAX-IDE. move Acc, @DP [ 0]; Note that this will reset the application; the cmp # 1234h; data segment is not loaded while the application jump NE, copyToFlash; is still running. Move DP [0], # 0; Start of RAM variable area move A [ 4], # 7000h; Location in flash to write to move LC [0], # 100h; Store 256 words in flash 7000h-70FFh copyToFlash_loop: move DP [0], DP [0]; Refresh the data pointer to read values ​​correctly ,; because calling UROM_flashWrite changes memory; contexts and affects the cached @DP [0] value move A [0], A [4]; Location to write move A [1], @DP [0] ++; Value to write (taken from RAM) lcall UROM_flashWrite move Acc, A [4] add # 1 move A [4], Acc djnz LC [0], copyToFlash_loop main: move PD0, # 0FFh; Set all port 0 pins to output move PO0, # 000h; Drive all port 0 pins low (LEDs off) move DPC, # 1Ch; Set po inters to word mode move DP [0], #varA move Acc, @DP [0] cmp # 1234h; Verify that the variable is set correctly jump NE, fail pass: move PO0, # 55h sjump $ fail: sjump $ segment data org 0000h varA: dw 1234h org 00FFh varB: dw 5678h end Conclusion The program and data segment tools provided by MAX-IDE can automatically declare variable addresses in the data memory and initialize these variables with the initial values. You can use an application to cache these variables in flash memory and restore them if necessary. This method allows assembly-based applications to use the data segment auto-loading function provided by MAX-IDE, regardless of whether the microcontroller is connected to the JTAG debugger, and can keep working.

PA Speaker Accessories

horn speaker accessory

Our company specializes in production and R&D of various products including tweeter, alarm loudspeaker, horn loudspeaker, high power Driver Unit , etc. In recent years, our company has developed and manufactured many kinds of products such as air defense warning loudspeaker, flood control and warning loudspeaker, police vehicle-mounted loudspeaker, public address system etc.

Pa Speakers Accessories,Replacement Diaphragm,Diaphragm (acoustics) ,speaker diaphragm,voice coil diaphragm

Taixing Minsheng Electronic Co.,Ltd. , https://www.ms-speakers.com