Go Down

Topic: Programming in C (Read 5808 times) previous topic - next topic

jtw11

#60
Nov 24, 2012, 04:02 pm Last Edit: Nov 24, 2012, 04:05 pm by jtw11 Reason: 1
So - my effort in the learning of C right from the start has begun. I've got a bit of K&R, and am reading through as we speak. Will pick up a full copy from the library in the week.

I'm using xCode on Mac to run some of these programs to get used to C - however, it seems I've come across a stumbler straight away. I'm running a quick "Hello, world" program first. Here's what I've got, as stated by K&R.

Code: [Select]
#include <stdio.h>

main()
{
printf("Hello, World!"\n);
}



It compiles and runs fine, and prints to the xCode console. However, first - it gets angry at me and says I should have written int main() as opposed to main().

Secondly, it seems every other Hello world program, in C contains the following line, and indeed the xCode example does have it. But, the K&R code runs fine without it?

Quote
int main(int argc const char * argv[])

dhenry

Quote
it gets angry at me and says I should have written int main() as opposed to main().


And it is right in doing that: a good template would be this:

Code: [Select]

#include <stdio.h>

int main(void)
{
  printf("Hello, World!"\n);
}


Parameters to main() are not needed in an embedded environment as you have no way of inputting them to the mcu.

jtw11

It may sound like a stupid question; but what do you mean by no parameters to main?

Clearly we have many ways in inputting things to an MCU?

Would anybody have any recommendations for a book aimed specifically at embedded C, rather than C used in a 'normal' PC environment? Things such as the above I fear will complicate matters, I'm never one just to accept "that's how it is" and move on, so will always want to know why things that appear to make no different to my code are there.

dhenry

main() is one of the earliest functions to be executed. To provide it with parameters, you will have to have a host OS.

Quote
Would anybody have any recommendations for a book aimed specifically at embedded C,


C is C and K&R is the best book you can find on C (and one of the hardest to understand fully as well). Embedded programming really is reading a good C book and lots of datasheets.

And many more hours of coding and debugging.

tuxduino

The standard "main" function template is:

Code: [Select]

int main(int argc, char** argv) {
}


where argc is the number of program arguments, including the program name itself ,and argv is an array of c-strings (null-terminated array of char) that contain those argument.
Code: [Select]

#include <stdio.h>

int main(int argc, char** argv) {
    if (argc == 1) {
        printf("Usage: %s <your name>\n", argv[0]);
        return 1;
    }

   printf("Hallo, %s !\n", argv[1]);
}


Code: [Select]

tuxduino@mylaptop:~/tmp/x$ gcc -o halloName halloName.c
tuxduino@mylaptop:~/tmp/x$ ./halloName
Usage: ./halloName <your name>
tuxduino@mylaptop:~/tmp/x$ ./halloName tuxduino
Hallo, tuxduino !


All of this makes sense in a pc environmente, where you have stdin, stdout and a shell passing arguments to your program. That's totally absent in an embedded environment (unless you're on raspi, of course :P ), so main() function arguments are pointless.

pico


K&R is the best book you can find on C (and one of the hardest to understand fully as well).


You keep saying that, but you never actually say what part of the book you have trouble understanding.

If it was hard to understand, it certainly wouldn't be a very good primer.

WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

jtw11



K&R is the best book you can find on C (and one of the hardest to understand fully as well).


You keep saying that, but you never actually say what part of the book you have trouble understanding.

If it was hard to understand, it certainly wouldn't be a very good primer.




Mmm - I do find it somewhat strange that one would recommend a book saying it was the hardest to fully understand.

I just feel as if a book aimed solely at C in an embedded environment will serve me better, for example - Tuxuino, thank you for your reply - but none of the post makes sense to me, and if I'm going to keep reading things like that I need not learn right now, I may end up being distracted from what I set out to do.

Looks like there are books about embedded C using AVRs!

pico

#67
Nov 24, 2012, 04:54 pm Last Edit: Nov 24, 2012, 05:12 pm by pico Reason: 1

It may sound like a stupid question; but what do you mean by no parameters to main?

Clearly we have many ways in inputting things to an MCU?


When a C program is run under an OS (Linux etc.) command line parameters can be passed to the program (e.g. in "sort mylist", if the program was called "sort", the first command line parameter would be "mylist"), and in the program sort.c sees these command line parameters as parameters passed to main() (which is the "top level" function that the program starts in.)

Since you can't pass parameters to main() in an embedded application (the program just starts up at power up without any user interaction), this avenue of communication isn't open. The program, once running, can get potentially get inputs from a variety of other input sources however.

One of the "Arduinoisms" you may have just encountered is that in an Arduino sketch, you don't actually start in a main() function. (main() is actually there in the background, but hidden away from your "sketch" program.) Instead, you need to write two functions that are called by main() in the background. They are:

Code: [Select]

void setup()
{
}


and

Code: [Select]

void loop()
{
}


The main() function (that you don't see) that is calling these functions looks like this:

Code: [Select]

int main()
{
 setup();
 for(;;)
    loop();
}


which means that the setup() function (that you write) is called once at the start of execution, but your loop function is called repeatedly after that.


Would anybody have any recommendations for a book aimed specifically at embedded C, rather than C used in a 'normal' PC environment? Things such as the above I fear will complicate matters, I'm never one just to accept "that's how it is" and move on, so will always want to know why things that appear to make no different to my code are there.


C in an embedded environment is a subset of C in a non-embedded environment. You read a general C book (like K&R) and just have to understand that some things just won't make sense in an embedded environment (e.g. file IO functions like fopen() etc. won't work because there is no file system for them to operate on!)

The language is the same, however (modulo some of the Arduino idiosyncracies.) In the embedded world, the equivalent to "hello world" is the "blink" program. Have a look for it in the example programs included with the Arduino IDE. Probably the most direct way forward is to be reading the Arduino example code, experimenting with it, and then referring to the K&R to understand the C language constructs they employ.

I suspect you will make rapid progress. :)
WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

jtw11

Thank you Pico regarding how the Arduino IDE combines setup and loop into one main.

Regarding starting at the blink sketch, I've actually written some fairly complex programs that work bug free in the Arduino IDE such as; temperature dependant motor control using H bridges of discrete components with LCD interfacing, tachometer (albeit limited in speed range due to overflows that I need to sort out) etc etc.

However, I just felt that maybe because Arduino was my first intro to programming, now I've got a grasp on the world of it, I should start again with 'pure' C, then move onto 'pure' C++.

Maybe I should take some of my Arduino programs, and try to replicate that exact behaviour using pure C in Atmel Studio, whilst referring to K&R.

pico

#69
Nov 24, 2012, 05:34 pm Last Edit: Nov 24, 2012, 05:46 pm by pico Reason: 1

Maybe I should take some of my Arduino programs, and try to replicate that exact behaviour using pure C in Atmel Studio, whilst referring to K&R.


You'll find that (conceptually) there there isn't that much to do, outside of what we've already discussed.

You'll have to

a) provide your own main function.
b) use different #include directives for the different environment
c) write your own function prototypes (just function declarations that you put near the start of your program to simplify things for the compiler when it comes across a call to a function that it hasn't yet seen in the source file.)
d) change to the use of "bool" instead of "boolean"

and

e) (this is the biggy) either port across any of the libraries you have been using to your new programming environment, adapt your programs to use any equivalents written for the new environment, or develop your own equivalent libraries from scratch.

The thing about e), is that although Arduino is basically C/C++, a lot of the Arduino C/C++ code base in the libraries (e.g. "Ethernet", "SPI", etc.) relies on the "wiring" library functions (e.g., delay(), digitalWrite() etc.) These "wiring" functions won't be available in a standard set of C libraries -- it's actually the "wiring" library add-on that gives Arduino its "flavor" as a development environment, and it's reputation as an "easier" C programming environment for beginners.

So it's all doable, in principle. But it will be be some work porting across an Arduino sketch to a environment that doesn't include "wiring". If learning about the nuts and bolts of C is your goal, this would be a good way of doing just that. But I'd start with porting across some of the simpler programs (like "blink") first just to get your feet wet.

Hope this makes sense to you.



WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

retrolefty

#70
Nov 24, 2012, 05:40 pm Last Edit: Nov 24, 2012, 05:46 pm by retrolefty Reason: 1
Quote
However, I just felt that maybe because Arduino was my first intro to programming, now I've got a grasp on the world of it, I should start again with 'pure' C, then move onto 'pure' C++.

Maybe I should take some of my Arduino programs, and try to replicate that exact behaviour using pure C in Atmel Studio, whilst referring to K&R.


I think you are missing an important point being made. The C language was invented by R of K&R to write programs in a operating system environment, unix to be exact. So C has built in features that allows it to except command line arguments from the OS when the compiled C program is called to run and optionally to return a optional error code to the OS when the C program exits. When you are dealing with the vast majority of microcontroller chips and their applications there will be no operating system running inside the chip to pass arguments to the microcontroller's compiled C program nor any way to exit back to an OS.

So while you can write programs in Atmel Studio that won't do any of the 'non-standard C/C++ modifications' that the arduino IDE preprocessor does to your sketch, there will still be no operating system for you program to interface with, so most of the examples in the K&R book will still not work as most rely of piping of data streams into and out of standalone C programs written to all operate within an underling OS.

If you really want to learn and use pure C (or C++) as it was originally designed and explained in the classic K&R book then you should be using a PC C compiler to write C programs that will run under the PC's OS be it Windows, Linux, Apple, etc. So unless you plan on getting a much more powerful ARM based development board and install some kind of operating system to run on it, any use of the C/C++ programming language has to limit itself to using just the features and methods that make sense in a typical microcontroller based 'standalone' environment. be it arduino or other platform.

Lefty

pico

#71
Nov 24, 2012, 05:54 pm Last Edit: Nov 24, 2012, 05:57 pm by pico Reason: 1

The C language was invented by R of K&R to write programs in a operating system environment, unix to be exact.


Not quite accurate. Ken Thompson and Dennis Ritche firstly developed C (from an earlier language, B) in order to _write_ the UNIX operating system.

They actually had two goes at it. The first attempt they abandoned as things got too complex in an earlier more primitive version of C they had developed. Then they introduced "structures", and that allowed the second attempt to go much more smoothly.

Once the OS was written, C was found to be quite a usable language for application programming as well, of course. So although it is more commonly used as an application development language today, it had it's origins as a systems development language. Which is undoubtedly the main reason it is still the "bare-metal" programming language of choice today.

Nerdy enough for you? ;)
WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

AWOL

Quote
Not quite accurate. Ken Thompson and Dennis Ritche firstly developed C (from an earlier language, B) in order to _write_ the UNIX operating system.

Not quite nerdy enough. It was developed to aid porting Unix.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

pico


Not quite nerdy enough. It was developed to aid porting Unix.


Nope. Writing it. If you think the first version of UNIX was written in assembly language, that is a mistake.
WiFi shields/Yun too expensive? Embeddedcoolness.com is now selling the RFXduino nRF24L01+ <-> TCP/IP Linux gateway: Simpler, more affordable, and even more powerful wireless Internet connectivity for *all* your Arduino projects! (nRF24L01+ shield and dev board kits available too.)

jtw11

#74
Nov 24, 2012, 06:35 pm Last Edit: Nov 24, 2012, 06:39 pm by jtw11 Reason: 1
Pico, thanks for your reply last big reply - that was the sort of answer I'd been trying to coax out of people. Maybe I just didn't ask the right questions.

Quote
a) provide your own main function.

By this, you mean combine the Arduino setup and loop functions into one function, main? As discussed earlier? So, things like setting up pins as inputs for example, you just do inside the main? However, I will need to refer to these as ports and what not I believe instead simply of pin numbers - I need to look in to this.

Quote
b) use different #include directives for the different environment

I'm not too sure what you mean here by different directives? Do you mean for example, say I wrote my own servo library - that I'd write #include <myownservolib.h>. Or are you referring to including again, for example, standard libraries that come with Atmel Studio?

Quote
c) write your own function prototypes (just function declarations that you put near the start of your program to simplify things for the compiler when it comes across a call to a function that it hasn't yet seen in the source file.)


Again, a little lost here. A function for example would be digitalWrite?

Quote
d) change to the use of "bool" instead of "boolean"

No problem - I haven't actually used boolean all that much, so there arn't many instances to change.

Regarding point e) - I agree this seems the most important, writing or finding libraries that provide the functions such as milli() micro() etc as my codes have used these quite extensively. I need to find out how to write a library. Just on a side note, is wire.h included automatically? As I haven't included it in my codes using functions such as millis, and all works fine.

Retrolefty
Quote
I think you are missing an important point being made. The C language was invented by R of K&R to write programs in a operating system environment, unix to be exact. So C has built in features that allows it to except command line arguments from the OS when the compiled C program is called to run and optionally to return a optional error code to the OS when the C program exits. When you are dealing with the vast majority of microcontroller chips and their applications there will be no operating system running inside the chip to pass arguments to the microcontroller's compiled C program nor any way to exit back to an OS.

So while you can write programs in Atmel Studio that won't do any of the 'non-standard C/C++ modifications' that the arduino IDE preprocessor does to your sketch, there will still be no operating system for you program to interface with, so most of the examples in the K&R book will still not work as most rely of piping of data streams into and out of standalone C programs written to all operate within an underling OS.


If I've interpreted this post correctly - you're agreeing that maybe a book on writing actual embedded C for MCUs is probably going to be a better idea here?

Go Up