EmbDev.net

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


Author: Mar Sunone (bmar)
Posted on:

Rate this post
0 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
#define TXRDY      ((unsigned int) 0x1 <<  1)     // TXRDY Interrupt
#define CSR        ((unsigned int) 0xFFF70000)     // Status register
#define THR        ((unsigned int) 0xFFF50000)     // Transmitter Holding Register

int main(void)
{//* Begin
  unsigned int *mem;
  unsigned int *pCSR=CSR;    // Global Pointer to USART0 Status Register
  unsigned int *pTHR=THR;      // Global Pointer to USART0 TX Buffer
  
  mem=0;
  // Loop forever
  for (;;)
  {  
    while (!(*pCSR & TXRDY));  // Wait for Empty Tx Buffer
    *pTHR = *mem;              // Transmit Character
    mem++;
  } // End for

} //* End

Author: Clifford Slocombe (clifford)
Posted on:

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

Author: Mar Sunone (bmar)
Posted on:

Rate this post
0 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:
#define TXRDY      ((unsigned int) 0x1 <<  1)     // TXRDY Interrupt
#define CSR        ((unsigned int) 0xFFF70000)     // Status register
#define THR        ((unsigned int) 0xFFF50000)     // Transmitter Holding Register

int main(void)
{//* Begin
  unsigned int *mem;        // Pointer to memory address
  unsigned int *pCSR;      // Pointer to USART0 Status Register
  unsigned int *pTHR;      // Pointer to USART0 TX Buffer

  pCSR=CSR;            // set pointer to USART status register
  pTHR=THR;            // set pointer to TX buffer address
  mem=0x100;            // Start pointer with an offset
  // Loop forever
  for (;;)
  {  
    while (!(*pCSR & TXRDY));  // Wait for Empty Tx Buffer
    *pTHR = *mem;        // Transmit Character
    mem++;            // increase mem pointer
    
    if(mem>0xFFFF) mem=0x100;  // check top memory reached -> restart
    
  } // End for

} //* 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.

Author: Clifford Slocombe (clifford)
Posted on:

Rate this post
0 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/programmingpointer...
http://www.embedded.com/columns/programmingpointer...

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

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.