I used to understand arm Program (* (volatile unsigned long *). I read two articles today and I think it is useful to understand this, of course, this is not only useful in defining internal special registers. When using an external bus, you can also define the address of an external device based on the actual situation.
The following is Article 1.
I finally understood the definition of # define sreg (* (volatile unsigned char *) 0x5f) I saw before # define sreg (* (volatile unsigned char *) 0x5f), which is always strange, I don't know why. I finally got a little bit of experience today. Please submit more bricks to the prawns ~~~
Embedded system programming requires programmers to use C language to access a fixed memory address. Since it is an address, according to the syntax rules of the C language, the number of addresses should be pointer type. Therefore, after knowing the memory address to be accessed, for example, 0x5f, the first step is to forcibly convert it to the pointer type (unsigned char *) 0x5f, And the sreg of AVR is an eight-bit register, therefore, 0x5f is forcibly converted to the unsigned char type. The volatile keyword indicates that the variable may be unexpectedly changed, so that the compiler will not assume the value of the variable. This "unexpected change" is not changed by the program, but by the hardware-Unexpected. Step 2: unreference the pointer variable to operate the content of the address pointed to by the pointer * (volatile unsigned char *) 0x5f step 3, it is a good habit to carefully enclose the parameters in the # define macro in parentheses, so # define sreg (* (volatile unsigned char *) 0x5f)
Similarly, if a 32-bit processor is used to access a 32-bit memory address, you can define # define ram_addr (* (volatile unsigned long *) 0x0000555f) as follows) then you can use the C language to read and write this memory address. Read: TMP = ram_addr; write: ram_addr = 0x55;
Article 2
For different computer architectures, devices may be port ing or memory ing. If the system structure supports independent I/O address space and port ing, you must use the assembly language to implement actual device control, because the C language does not provide the concept of a true "Port. For memory ing, it is much more convenient.
Take # define iopin (* (volatile unsigned long *) 0xe0028000) as an example: as a macro definition statement, define is a pseudo command that defines a variable or constant. First (volatile unsigned long *) means to forcibly convert the following address to volatile unsigned long *, unsigned long * is the unsigned long integer, and volatile is a type qualifier, like const, when the volatile limit is used, it indicates that the variable depends on the system implementation, so that the variable will be modified by other programs or computer hardware. Because the address depends on hardware, volatile indicates that its value depends on hardware.
The volatile type is like this, and its data may indeed change under unknown conditions. For example, the terminal of a hardware device has changed it, and now the hardware device often has its own private memory address, such as the video memory, which usually uses image mirroring, reflected in a specific memory address, so that under some conditions, the program can directly access these private memory. In addition, for example, when multiple programs operate on the shared memory address. Your program does not know when the memory will be changed. Without the voliatile modifier, the program uses the data in the catch, which may be outdated. If voliatile is added, the program re-extracts the address to ensure it is up to date. Summarized as follows:
1. the volatile variable allows modifications to content other than programs, such as hardware. 2. access to the data will directly access the content of the address at any time, that is, the optimization of the access speed through the cache is canceled.
(Volatile unsigned long *) 0xe0028000) is an address that is defined as required by the hardware. The "*" pointer is added before. To direct the address directly, the entire definition Convention symbol iopin is replaced, during the call, you can directly write the content to the address register. This is actually the convenience of the memory ing mechanism. Among them, the volatile keyword is an important feature of embedded system development. The above expression is split and analyzed. First (volatile unsigned long *) 0xe0028000 means to forcibly convert 0xe0028000 to a pointer of the volatile unsigned long type, which is temporarily recorded as P, so it is # define a * P, that is, the content where a points to the position of the P pointer. In this example, register a can be accessed through memory addressing and read/write operations can be performed.
For (volatile unsigned char *) 0x20, we will analyze it. It consists of two parts: 1) (unsigned char *) 0x20, 0x20 is only a value, the preceding addition (unsigned char *) indicates that 0x20 is an address and the address type is unsigned char. It means that when reading and writing this address, it should be written into the value of unsigned char, reading is also an unsigned char. 2) Volatile: the keyword volatile ensures that this command will not be omitted due to the optimization of the C compiler, and requires that the value be read directly each time. For example, when while (unsigned char *) 0x20) is used, sometimes the system may not actually read the value 0x20, but the value read for the first time, this loop may be an endless loop. If volatile is used, the actual value of 0x20 must be read each time.
So (volatile unsigned char *) 0x20 is a fixed pointer that is immutable, not a variable. Char * u is a pointer variable. Add "*": * (volatile unsigned char *) 0x20 to the variable (normal unsigned char variable, not a pointer variable ), if # define I (* (volatile unsigned char *) 0x20), it is the same as unsigned char I, except that the address of the previous I is fixed.
Then you can solve your problem. (* (volatile unsigned char *) 0x20) can be considered as a common variable with a fixed address pointing to 0x20. 0x20 is only a constant, not a pointer or a variable.