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
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
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". > > >
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
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
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
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
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
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
Log in with Google account
No account? Register here.