Hi, I just started learning ARM and I have download the winARM as compiler. I would like starting with ARM with a simple routine that send out via USART the ARM memory. I built the following routine and I guess if it is right (got some warning...)? In doing that I have utilized the example included in winARM + "cut and past"... Thanks for your help
1 | #define TXRDY ((unsigned int) 0x1 << 1) // TXRDY Interrupt |
2 | #define CSR ((unsigned int) 0xFFF70000) // Status register |
3 | #define THR ((unsigned int) 0xFFF50000) // Transmitter Holding Register |
4 | |
5 | int main(void) |
6 | {//* Begin |
7 | unsigned int *mem; |
8 | unsigned int *pCSR=CSR; // Global Pointer to USART0 Status Register |
9 | unsigned int *pTHR=THR; // Global Pointer to USART0 TX Buffer |
10 | |
11 | mem=0; |
12 | // Loop forever |
13 | for (;;) |
14 | { |
15 | while (!(*pCSR & TXRDY)); // Wait for Empty Tx Buffer |
16 | *pTHR = *mem; // Transmit Character |
17 | mem++; |
18 | } // End for |
19 | |
20 | } //* End |
ARM7 defines a processor architecture, but does not define a specific microprocessor or microcontroller. Each ARM7 microcontroller vendor adds its own peripheral devices, so there is no ARM7 USART; you need to specify exactly what ARM based microcontroller you are using. The code posted does not include any hardware configuration, so it is very unlikely to do anything useful as it stands. You need to initialise the hardware. Mar Sunone wrote: > I built the following routine and I guess if it is right (got some > warning...)? The ? indicates a question, but this does not appear to be a question. What are you asking? If you got warnings, tell us what they were. The punctuation "..." (ellipsis) indicates that you have omitted information. If you have nothing more to say, don't use the ellipsis since it implies that you are holding something back. This line: > *pTHR = *mem; // Transmit Character on the first iteration when mem == 0 will dereference a null pointer, which is a runtime error in C. Dereferencing an indefinitely increasing memory address will eventually result in an invalid access fault. The output stream will include non-printing and control characters. Mar Sunone wrote: > In doing that I have utilized the example included in winARM + "cut and > past"... There are many examples in WinARM - be specific (specify the path in the WinARM directory).
Thanks Clifford for your inputs, For the time being I am approaching ARM by programming, latern I will get the development board to doing some tests (or a real application). As example I have utilized the "at91sam7s64_uart_simple" base code adjusted to the below code (updated based on your input). I have considered to pass the address of the USART and status register directly without the structure (easy to read in one page, just for the example). Regarding the warning, I saw that the first compiling is generating warnings, but recompiling without changing anything, the warnings disappear (I am using the programmer notepad of winarm, I really like the way is organized: easy and quick to go). Anyway, the warning I had were the following: main.c:28: warning: assignment makes pointer from integer without a cast main.c:29: warning: assignment makes pointer from integer without a cast linked with the code: pCSR=CSR; pTHR=THR; This is the code with your input:
1 | #define TXRDY ((unsigned int) 0x1 << 1) // TXRDY Interrupt |
2 | #define CSR ((unsigned int) 0xFFF70000) // Status register |
3 | #define THR ((unsigned int) 0xFFF50000) // Transmitter Holding Register |
4 | |
5 | int main(void) |
6 | {//* Begin |
7 | unsigned int *mem; // Pointer to memory address |
8 | unsigned int *pCSR; // Pointer to USART0 Status Register |
9 | unsigned int *pTHR; // Pointer to USART0 TX Buffer |
10 | |
11 | pCSR=CSR; // set pointer to USART status register |
12 | pTHR=THR; // set pointer to TX buffer address |
13 | mem=0x100; // Start pointer with an offset |
14 | // Loop forever |
15 | for (;;) |
16 | { |
17 | while (!(*pCSR & TXRDY)); // Wait for Empty Tx Buffer |
18 | *pTHR = *mem; // Transmit Character |
19 | mem++; // increase mem pointer |
20 | |
21 | if(mem>0xFFFF) mem=0x100; // check top memory reached -> restart |
22 | |
23 | } // End for |
24 | |
25 | } //* End |
I saw the .hex file generated and it is really big compared with the few above code lines, do you know why? What is the way to obtain an asm file to see what the compiler is doing? Thanks for your help.
Mar Sunone wrote: > Regarding the warning, I saw that the first compiling is generating > warnings, but recompiling without changing anything, the warnings > disappear They cannot just disappear; you have to fix them! However a warning will not prevent a module from compiling, so if you are using a make file, the code will not be recompiled because teh object file is up-to-date. Do a clean build and I'll bet the warnings will come back if you did nothing to fix them. > Anyway, the warning I had were the following: > main.c:28: warning: assignment makes pointer from integer without a cast > main.c:29: warning: assignment makes pointer from integer without a cast They mean what they say; you need: #define CSR ((volatile unsigned int*) 0xFFF70000) // Status register #define THR ((volatile unsigned int*) 0xFFF50000) // Transmitter The 'volatile' is very important; see: http://www.embedded.com/story/OEG20010615S0107 http://www.embedded.com/columns/programmingpointers/174300478 http://www.embedded.com/columns/programmingpointers/175801310 However, you would be better off using the device specific header file for the part which will have the registers already correctly defined. > > I saw the .hex file generated and it is really big compared with the few > above code lines, do you know why? The hex file will include the C runtime start-up code (normally in the assembler file crt0.s). Also a hex encoded file will be a little over twice the size of the actual loaded binary code. The contribution made by your code is small in this case, and the rest is a fixed overhead, so only seems significant for trivial code, for a full application it is likely to be insignificant. > What is the way to obtain an asm file to see what the compiler is doing? > The easiest way is to load the code into the debugger/simulator and view it in mixed ASM/Source mode. The compiler has options for outputting assembler and mixed assembler source listings. See the manual: http://gcc.gnu.org/onlinedocs/ There are also linker options to generate a map file that will tell you the size of every module linked to your code. See http://sourceware.org/binutils/docs/ld/index.html Clifford