EmbDev.net

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

Author: Mar Sunone (bmar)
Posted on:

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:

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:

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:

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]




Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.


webmaster@embdev.netContactAdvertising on EmbDev.net