Author Topic: Where do I start if I want to learn larger architecthre "C" uC programming?  (Read 14998 times)

0 Members and 1 Guest are viewing this topic.

Online nctnico

  • Super Contributor
  • ***
  • Posts: 28711
  • Country: nl
    • NCT Developments
2) Do not avoid pointers like someone suggested.
:palm: I guess some people still drive around with the model-T Ford... Which is OK if you want to casually drive around but if you need something reliable for your daily commute there are better options. Same goes for pointers. They are an integral part of C but that doesn't mean using them is good coding practise. Properly written software validates a pointer before using it. Even experienced programmers shoot themselves in the foot with pointers every now and then.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Same goes for pointers. They are an integral part of C but that doesn't mean using them is good coding practise. ...
Even experienced programmers shoot themselves in the foot with pointers every now and then.
So experienced programmers are not employing your idea of "good coding practice"?

I can only speak as someone who has been a professional C programmer since 1996. Every single product I've worked on has been written in C which made heavy use of pointers.

Properly written software validates a pointer before using it.
This is demonstrably false. There are plenty of examples of perfectly good C which contradict your statement.

"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
-Every single product I've worked on has been written in C which made heavy use of pointers. -

the same here. A piece of c without pointers is almost unthinkable, unless you are an absolute newbie working on a blinky.

-this is demonstrably false. There are plenty of examples of perfectly good C which contradict your statement. -

she or he likely was using a unique definition of validation.

as to k&r, I think it's a must read but not sufficient. Good individual pieces of code may not work together seamlessly. This is where firms publish coding guidelines and use libraries to enforce coding standards. This is like industrilized code production vs. Mom and pop code production.

that trend towards stylized coding is more keen as you move to bigger and more powerful chips.
================================
https://dannyelectronics.wordpress.com/
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Good individual pieces of code may not work together seamlessly.
I think you've brought up an interesting topic. As far as I'm concerned, the biggest difference between a beginner and an experienced programmer is the ability to

1) get the small routines working together,
2) make this happen in as pleasant a way as possible (understandable, clean design).

You're right when you say that K&R wont teach this. I think it's too much to ask from a book. Instead you should probably be creating programs from scratch that end up in the >= 10KLOC range. That's what I reckon anyway.
"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Agreed. I would add that as experience grows, your ability to divide a project into well defined modules that in the end will work together becomes far more valuable than your ability to code individual modules correctly and beautifully.

#2 is far easier to achieve than #1 above.
================================
https://dannyelectronics.wordpress.com/
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Getting that #2 clean design right is a big step towards that #1 where all your small routines work together correctly.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 28711
  • Country: nl
    • NCT Developments
They are an integral part of C but that doesn't mean using them is good coding practise.

Do you don't recommend using arrays in C? Or passing pointers to variables so functions can modify them?

I don't think you understand pointers, which is why you fear them.
Please play the ball not the man. I have a perfect understanding of pointers. But I also have a perfect understanding of their dangers which is why I recommend using C++ where you can pass variables by reference instead of a pointer.

Say you have this C function:
do_something(int in1, int *out1, int *out2)
If someone calls that with do_something(1, NULL, &a) that may break if do_something doesn't check the pointers.

In C++:
do_something(int in1, int &out1, int &out2)
If someone calls that with do_something(1, NULL, a) it won't compile.

See the difference? The second form is easier because you don't have to worry someone calling do_something with an invalid pointer (*). If a large piece of software consists of many modules there is always a chance someone tries to call a function in a way that has not been forseen.

(*) It is good coding practise to check boundaries of function parameters especially if a function is visible to other modules in a piece of software. It helps to compartmentalize the software and prevents errors from causing a cascade of weird behaviour.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Quote
I have a perfect understanding of pointers.

Quote
"I am not drunk.... I...I...I am NOT...not drun...k...."

Quote
"I can still do it...."

Quote
"I am not a criminal!"

Lots of similarities here.
================================
https://dannyelectronics.wordpress.com/
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Please play the ball not the man. I have a perfect understanding of pointers. But I also have a perfect understanding of their dangers which is why I recommend using C++ where you can pass variables by reference instead of a pointer.

I'm not so sure you do understand pointers. A pointer is just an address. If I've got an 8-bit  register mapped at address 0x1234 then I want to be able to write
Code: [Select]
  char *reg;
  ...
  reg = 0x1234;
  ...
  data = *reg;
Wth your perfect understanding you may see danger. Me, I see no problems whatsoever. 
« Last Edit: June 24, 2014, 02:38:34 pm by bwat »
"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Quote
I see no problems whatsoever. 

I am in the same camp, due to, I think, our less-than-perfect understanding of pointers.

:)
================================
https://dannyelectronics.wordpress.com/
 

Offline TimMcDonald

  • Newbie
  • Posts: 3
The big issue isn't word size having larger words just makes things easier where the difficulty comes from is more advanced features such as peripherals with DMA and pipelining . I personally find programming AVR to be easier in assembly were I can see what every clock cycle and is doing and I understand how data types other than bytes are being implemented because I chose the implementation, these MCUs have very limited RAM and I like to know exactly how things are being done. By contrast programming a PIC32 in assembly is wizard level stuff and I would use a language like C and standard libraries to get stuff done. Programming in Arduino style C on any MCU should be only easier as the MCU's get more powerful on the on other hand if you want to leverage the feature sets of more advanced MCU's be prepared to do a lot of research that isn't necessarily going to transfer to other platforms.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Quote
if you want to leverage the feature sets of more advanced MCU's be prepared to do a lot of research that isn't necessarily going to transfer to other platforms.

If you get into the weeds and want to take advantage of a particular feature of the peripherals on a mcu, yes, it is unlikely to be portable to another chip with a different feature set.

On the flip side, you can certainly install a layer that implements a common set of features across a wide range of chips. end of the day, a timer is a timer and a nvic is a nvic.

All in the approaches / implementation.
================================
https://dannyelectronics.wordpress.com/
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 28711
  • Country: nl
    • NCT Developments
I've seen this sort of thing countless times, and the function itself is always half baked. By hand-holding through these kinds of issues it just encourages sloppy programming and a lack of proper understanding.
That sounds rather elitist  ;)
What happens when a deadline approaches quickly? Do you add pointer checking or work on code which finishes the project on time? By avoiding error prone constructs you don't need to add checks so you can have the project finished on time AND sleep well that night.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
I've seen this sort of thing countless times, and the function itself is always half baked. By hand-holding through these kinds of issues it just encourages sloppy programming and a lack of proper understanding.
That sounds rather elitist  ;)
It seems to me that Mojo-chan is promoting "proper understanding". Labelling those with higher standards than your own as "elitist" only means you would rather see people dragged down than lifted up.  I choose to work for proper understanding and embetterment for myself and for others where I can - it's the positive thing to do.

By avoiding error prone constructs you don't need to add checks so you can have the project finished on time AND sleep well that night.
Do you also avoid integer division?
"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Quote
"proper understanding"

How can you have an understanding more proper than "perfect understanding"?

:)
================================
https://dannyelectronics.wordpress.com/
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Quote
Say you have this C function:
do_something(int in1, int *out1, int *out2)
If someone calls that with do_something(1, NULL, &a) that may break if do_something doesn't check the pointers.

This is a rather poor example. The real problem is a lack of checking in do_something(). If you can't even manage that, what are the chances that do_something() doesn't contain other issues?
I'd argue that nctnico's position (and his example) are reasonable. Given that with C++ you have the choice to use references or pointers to pass a arguments indirectly, which technique should you choose? I mean, what kind of thought process do you go through as an API designer?

IMO, if an argument is being passed indirectly but can *never* be NULL, then the argument should generally be passed by reference, not pointer. Doing this basically pushes the NULL-checking code that you'd write inside the function back out to the compiler. It also means you don't need to check for that particular error at runtime, proving a (small) savings of execution time and code space.
Quote

I've seen this sort of thing countless times, and the function itself is always half baked. By hand-holding through these kinds of issues it just encourages sloppy programming and a lack of proper understanding.

... grumble, grumble ... Get off my lawn!
 :blah:
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
It seems to me that Mojo-chan is promoting "proper understanding". Labelling those with higher standards than your own as "elitist" only means you would rather see people dragged down than lifted up.  I choose to work for proper understanding and embetterment for myself and for others where I can - it's the positive thing to do.
:palm:
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 28711
  • Country: nl
    • NCT Developments
I've seen this sort of thing countless times, and the function itself is always half baked. By hand-holding through these kinds of issues it just encourages sloppy programming and a lack of proper understanding.
That sounds rather elitist  ;)
It seems to me that Mojo-chan is promoting "proper understanding". Labelling those with higher standards than your own as "elitist" only means you would rather see people dragged down than lifted up.  I choose to work for proper understanding and embetterment for myself and for others where I can - it's the positive thing to do.
Maybe but throwing a novice into the deep doesn't help him/her or you. I like to keep my software simple and elegant so other people can maintain it. I often explain more complex constructs in the remarks. You can call that lowering the bar; I call it making sure I'm not stuck with my old projects forever. With less and less time spend on C/C++ on universities you can't expect to find a gifted C/C++ programmer around the corner or fresh from school.
Quote
By avoiding error prone constructs you don't need to add checks so you can have the project finished on time AND sleep well that night.
Do you also avoid integer division?
In most cases I do like to construct divisions in a way that avoids division by zero or have protection against division by 0.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4392
  • Country: us
Quote
you recommend avoiding pointers
I thought it was pretty clear from the first message on the sub-subject that he was talking about using pointers so that functions could (essentially) return multiple simple values; the traditional "swap(a, b);"
I don't know: having control of whether a function parameter can be modified by a called function be in control of the called function makes  me nervous (I rewrote 0 once, back in ForTran.)
OTOH, pointers to complex objects get passed around all the time, and it's "not unexpected" for functions to modify their contents.

It's not clear to me that a modern desktop C programming class will teach you C that is useful in embedded microcontrollers.  Too many dekstop programming classes focus on how to use the GUI libraries available, to create "normal looking" desktop applications.

 

Offline SirNick

  • Frequent Contributor
  • **
  • Posts: 589
What happens when a deadline approaches quickly? Do you add pointer checking or work on code which finishes the project on time? By avoiding error prone constructs you don't need to add checks so you can have the project finished on time AND sleep well that night.

This reminds me of that time in 2005, when I was working on a project that slipped past its deadline for having to write:

Code: [Select]
if (param2 == NULL) return XXX;
If only we were using C++   :scared:

No.  I've heard pointless debates like this too many times.  Coding is a skilled task.  You're always running late, people always make mistakes, software always has bugs.

Code: [Select]
10  That is life.
20  Get over it.

If you avoid the unchecked-NULL-pointer bug, you get caught by overflowing integers or any of a million other unpreventable pitfalls caused by an imperfect human typing in instructions for an unintelligent computer to interpret.

You hear the same nonsense about avoiding goto at all costs, or using { braces } for one-line conditionals, or using constants first in comparisons.  Yes, certain practices will potentially help avoid certain problems, but nothing will save untested code written by someone momentarily asleep at their keyboard.  That is a sickness for which there is no cure.

Ugh.  I'm grumpy today.   :rant:
 

Offline bwat

  • Frequent Contributor
  • **
  • Posts: 278
  • Country: se
    • My website
Quote
you recommend avoiding pointers
I thought it was pretty clear from the first message on the sub-subject that he was talking about using pointers so that functions could (essentially) return multiple simple values; the traditional "swap(a, b);"
This is part of the problem. Your mental model describes it in terms of returning multiple values. This model is wrong as at most one value is returned and the others are  stores to memory. Now, I know you this because you qualified your description with "(essentially)". Why do you explain it like that to yourself? We must stop trying to simplify the problem to suit our frame of reference and instead widen our frame of reference to suit the problem. Please don't think I'm attacking you. I catch myself doing things like this as well. I think we all do it. But we can't operate with inaccurate models in our heads and expect to write correct implementations of our designs.

I don't know: having control of whether a function parameter can be modified by a called function be in control of the called function makes  me nervous (I rewrote 0 once, back in ForTran.)
It's like the old Smalltalk joke of Processor := nil. Anyway, the parameter isn't being modified as you say. The parameter is an address. The contents of the address in memory is the thing being modified. But again you know this is what is actually happening because you go on to write:

OTOH, pointers to complex objects get passed around all the time, and it's "not unexpected" for functions to modify their contents.
Exactly!

It's not clear to me that a modern desktop C programming class will teach you C that is useful in embedded microcontrollers.  Too many dekstop programming classes focus on how to use the GUI libraries available, to create "normal looking" desktop applications.
I think it's a lack of a good grounding in assembly language. Many in my generation started with 8-bit assembly (6502 in my case), then 16-bit assembly (68000). By the time we had 16-bit machines we started to hear about this language C. Pointers aren't a problem for an assembly language programmer.
« Last Edit: June 25, 2014, 06:20:08 am by bwat »
"Who said that you should improve programming skills only at the workplace? Is the workplace even suitable for cultural improvement of any kind?" - Christophe Thibaut

"People who are really serious about software should make their own hardware." - Alan Kay
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6617
  • Country: nl
The real problem is a lack of checking in do_something(). If you can't even manage that, what are the chances that do_something() doesn't contain other issues?
Yeah in utopia you are right but we are not in utopia. Are you perhaps a 21st century programmer only used of having >32kB Rom sizes or what?
In real life, with real products with real companies we have embedded products with controllers having 4kB or 8kB ROM and sometimes as little as 128 bytes of RAM (in the past it was even worse but this is a product we did last year) just because the endproduct BOM has to be low (with a million products each dime saves you 100k).
In that real world we do not check all parameters of functions because we don't have that luxury.
Yes I know each book tells you should do it and also do boundary checking etc.  but if you don't have the room you don't   can't do it, period.
And this means testing, testing, testing and testing before shipping.
 

Offline Kjelt

  • Super Contributor
  • ***
  • Posts: 6617
  • Country: nl
If you can't manage to debug such a small project and handle reading the comments before supplying a parameter as NULL (most IDEs will now display the comments along side the function prototype automatically) then you need to find a new job.
Who said that, not me. I just responded to your black/white theoretical statement that in a theoretically perfect world every parameter should be checked. We do not live in a perfect world, and I bet that if I would review your code for a constrained device it would also not be perfect so welcome to reality. Try to read a post first before you give a bs answer.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
I have yet to find a compiler that throws up an error with this code, for example:

Code: [Select]
int* p() {
    return 0;
}
void x(int& y) {
  y = 1;
}
int main() {
   x(*p);
}

g++ must_resist_all_change_O_O.cpp
must_resist_all_change_O_O.cpp: In function ‘int main()’:
must_resist_all_change_O_O.cpp:10: error: invalid initialization of non-const reference of type ‘int&’ from a temporary of type ‘int* (*)()’
must_resist_all_change_O_O.cpp:6: error: in passing argument 1 of ‘void x(int&)’

gcc version 4.4.5. You're welcome.

Quote
More over I don't use C++ for embedded stuff anyway, there are just too many problems and it doesn't really offer any useful advantages.
Yes, you have voiced your opinion on C++ for embedded a few times. But luckily your experiences with C++ for embedded are not representative of the reality some of us encounter. You know, the reality where C++ is quite useful on embedded. But whatever, to each their own. You're happy with C, so stick with that. I'm happy with using C++ as well.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Quote
gcc version 4.4.5. You're welcome.

Nice done to that "expertly" written piece of s...., I mean, code.

:)
================================
https://dannyelectronics.wordpress.com/
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf