EmbDev.net

Forum: ARM programming with GCC/GNU tools syntax clarifications on WinARM


von Thomas F. (thomas_f)


Rate this post
useful
not useful
Hello ,

I have just started with WinARM and am trying some of the canned
examples.
I need some clarification on following:

unsigned char buffer[10];
  buffer="this is check";
This shows a compiler error:
main.c:185: error: incompatible types in assignment.AFAIK Keil supports
this as
as valid assignment.

uart1Puts(buffer);
This gives a warning:
main.c:196: warning: pointer targets in passing argument 1 of
'uart1Puts'
differ in signedness.

Has anyone written sample code for SPI ATMEL dataflash AT45DB161 or
similar which I could refer to ?

Thanks for reading this and hope to have your replies.

Thomas

von Michael W. (mictronics)


Rate this post
useful
not useful
You can not assign a 13 characters string to a 10 characters long
buffer.

uart1Puts seems to expect "char".


Thomas Fernando wrote:
> Hello ,
>
> I have just started with WinARM and am trying some of the canned
> examples.
> I need some clarification on following:
>
> unsigned char buffer[10];
>   buffer="this is check";
> This shows a compiler error:
> main.c:185: error: incompatible types in assignment.AFAIK Keil supports
> this as
> as valid assignment.
>
> uart1Puts(buffer);
> This gives a warning:
> main.c:196: warning: pointer targets in passing argument 1 of
> 'uart1Puts'
> differ in signedness.
>
> Has anyone written sample code for SPI ATMEL dataflash AT45DB161 or
> similar which I could refer to ?
>
> Thanks for reading this and hope to have your replies.
>
> Thomas

von Thomas F. (thomas_f)


Rate this post
useful
not useful
Michael,

Thanks for pointing that out,but thats not the source of error.
unsigned char buffer[15];
buffer="check_this";
I increased the buffer size and reduced string size,still same problem.
In any case C compilers do not do bound checking for arrays.

Function prototype is
const char *uart1Puts(const char *string);
which is a constant char pointer(as is buffer) not "char".

Thanks for your observations.
Thomas
Michael Wolf wrote:
> You can not assign a 13 characters string to a 10 characters long
> buffer.
>
> uart1Puts seems to expect "char".
>
>
>

von Clifford S. (clifford)


Rate this post
useful
not useful
Thomas Fernando wrote:
> unsigned char buffer[10];
>   buffer="this is check";
> This shows a compiler error:
> main.c:185: error: incompatible types in assignment.AFAIK Keil supports
> this as
> as valid assignment.
It is invalid and should not work in any ISO C compiler. In C, strings
are not a true data type and so cannot be assigned. You can however use
a literal string constant as an initialiser:

unsigned char buffer[] = "this is check" ;

The omission of the size between [] causes the compiler to determine the
size from the initialiser (which is 14 BTW not 13, there is a nul
terminator). Be cautious when using this, you cannot later use it to
hold a larger string; use an explicit size is you need to do that.

If you need to do a run-time assignment you must use strcpy() or
memcpy() or similar.

strcpy( buffer, "this is a check" ) ;

Again caution is required to make sure buffer is sufficiently large.

In C++ if you use the std::string class, you can assign a literal string
constant to a std::string object, but that is performed by the 'magic'
of operator overloading not available in C. Even if you used C++
however, you probably would not want to use the std::string class in an
embedded system and would have the same restrictions as in C.

The warning:
> main.c:196: warning: pointer targets in passing argument 1 of
> 'uart1Puts'
> differ in signedness.
means exactly what it says. It expects a char* and you passed an
unsigned char* (or rather an unsigned char[] - but that is irrelevant
here). It is expecting a pointer to signed data, and you passed a
pointer to unsigned data. The signedness of char is implementation
dependent - it may or may not be implicitly signed, depending on the
compiler or compiler options - in this case it is signed.

Now I would question why buffer needs to be 'unsigned'; if it is only
used for containing character data then leave it as an unadorned char
array. It is best to only use explicit signedness qualifier for char
when you are intending to use it as a 'small integer'; i.e. when you are
likely to perform arithmetic operations on the data.


Clifford

von Thomas F. (thomas_f)


Rate this post
useful
not useful
Clifford,

Your answer was perfectly right. I checked with Keil too and what you
said applies there too.

The use of unsigned char was a throwback to 8bit uC programming where
using unsigned char gives a more optimized code size compared to char
which is treated as a signed arithmetic variable.

Thanks for your explanation.
Thomas

von Thomas F. (thomas_f)


Rate this post
useful
not useful
Hi,

Could I ask for some help on C syntaxes I found in WINARM? I was
wondering if you could tell me about :

1) unsigned _cpsr; There does not seem to be any valid C datatype
specified ? What would the _ before cpsr indicate?So how would the
compiler specify the size of _cpsr?Is this a valid ANSI C declaration ?

2)static inline unsigned __get_cpsr(void) :
What would the __  prior to get_cpsr indicate ?

3)#define VIC_ENABLE      (1 << 5)
Does this mean that tag VIC_ENABLE is replaced with 0b100000
during preprocessing ?

Hoping to have some clarifications.


Thomas

von Clifford S. (clifford)


Rate this post
useful
not useful
Thomas Fernando wrote:
> 1) unsigned _cpsr; There does not seem to be any valid C datatype
> specified ? What would the _ before cpsr indicate?So how would the
> compiler specify the size of _cpsr?Is this a valid ANSI C declaration ?
>
> 2)static inline unsigned __get_cpsr(void) :
> What would the __  prior to get_cpsr indicate ?
>
> 3)#define VIC_ENABLE      (1 << 5)
> Does this mean that tag VIC_ENABLE is replaced with 0b100000
> during preprocessing ?

It is not always possible to say what is going on from a single line
without context. Where are you seeing this code?

The keyword 'unsigned' on its own is a data type. It is a synonym for
'unsigned int' - the 'int' is implicit. The ISO standard

In C/C++ the first character of a symbol may either be an underscore or
a letter, thereafter underscores, letters, and numbers are allowed. The
ISO standard requires that _ and  followed by a capital letter are
reserved for implementation extension - in that sense the function name
is not compliant. In C this is useful because by avoiding such names you
can avoid clashing with system defined symbols and compiler extensions.
That said I remember using one version of GCC for ARM that internally
defined a symbol 'arm', which bit me when I used the name in a different
context - a very hard to fathom error. Hopefully the later versions use
compliant symbols.

Often, if C/C++ code is mixed with assembler underscores are added to
the asm symbols because some compilers prefix symbols with an underscore
in the object code - so the underscore is needed in assembler to make
the symbols match; this is not what is happening here.

With respect to (3), you you are right. This no doubt a macro defining a
bit mask to access the enable bit of the Vectored Interrupt Controller.
The reason it is written like that is because the enable bit is bit 5 of
the register. Defining it like this is less error prone and more obvious
- you can see which bit it masks without converting to binary and
counting zeroes (although with practice when the value is in hex you can
do that in your head - and for single bits decimal too - at least for
the low order bits).

Clifford

von Thomas F. (thomas_f)


Rate this post
useful
not useful
Hi Clifford,
Thanks for your views once again.

Clifford Slocombe wrote:
>
> It is not always possible to say what is going on from a single line
> without context. Where are you seeing this code?

I was going through some code in the examples directory.This was from
the examples for the UART in  LPC2138(ArmVic.c).I am attaching some of
the relevant code FYI:

static inline unsigned __get_cpsr(void)
{
  unsigned long retval;
  asm volatile (" mrs  %0, cpsr" : "=r" (retval) : /* no inputs */  );
  return retval;
}

A calling function :
unsigned restoreIRQ(unsigned oldCPSR)
{
  unsigned _cpsr;

  _cpsr = __get_cpsr();
  __set_cpsr((_cpsr & ~IRQ_MASK) | (oldCPSR & IRQ_MASK));
  return _cpsr;
}

Clifford said:
The keyword 'unsigned' on its own is a data type. It is a synonym for
'unsigned int' - the 'int' is implicit. The ISO standard.......

Why create added confusion,if there is no advantage to be gained ?I
would think declaring it as "unsigned int" is much more readable?
Though some of WinARM's methods like creating structures and pointers to
access contiguous registers was quite a new learning experience.

Thanks
Thomas

von Clifford S. (clifford)


Rate this post
useful
not useful
Thomas Fernando wrote:
> Hi Clifford,
> Thanks for your views once again.

> I was going through some code in the examples directory.This was from
> the examples for the UART in  LPC2138(ArmVic.c).I am attaching some of
> the relevant code FYI:

Thanks; actually I did find that code. CPSR is an ARM register, I guess
the underscore prefix is just the preferred style of whoever write that
code.

> Clifford said:
> Why create added confusion,if there is no advantage to be gained ?I
> would think declaring it as "unsigned int" is much more readable?
Probably lost in the history of the C programming language which has
been around since 1972. A compiler is not free to choose what parts of
the language it implements, it is stndardised.

> Though some of WinARM's methods like creating structures and pointers to
> access contiguous registers was quite a new learning experience.
It is nothing to do with WinARM - WinARM is just a collection of tools
and examples from a number of sources - primarily GNU. The GCC compiler
implements the ISO C standard. It is an expressive and flexible
language, and many programmers employ many styles and approaches - some
good, some bad. Whatever you are looking at you can bet it is not the
only one true way of doing it.

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.