EmbDev.net

Forum: ARM programming with GCC/GNU tools ARM7 Simple USART routine


von Mar S. (bmar)


Rate this post
useful
not useful
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

von Clifford S. (clifford)


Rate this post
useful
not useful
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).

von Mar S. (bmar)


Rate this post
useful
not useful
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.

von Clifford S. (clifford)


Rate this post
useful
not useful
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

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.