common programing mistakes

Go To Last Post
53 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This a really vague question  But if you want to share some experience, please share.

 

What are the most common programing mistakes programmers make when writing code for embedded program eg UART, I2C, SPI, CAN, etc.

 

This topic has a solution.
Last Edited: Sat. Aug 28, 2021 - 03:37 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Number one biggest problem with "classic" AVRs is to accidentally set fuses for "external oscillator" instead of "crystal or resonator". This is not an issue with Mega0, Tiny0/1, or other newer devices.

 

Another big problem is to disable RESET pin, usually to try to get just one more I/O. With many older devices, when you do this, you loose the ability to program using standard hardware.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I used to make these mistakes a lot in the very beginning :-

 

1. Forgetting to set pins in output mode.

2. Wondering why ISR is not firing, because of missing global interrupt bit, sei();

3. Odd variable behavior due to missing volatile keyword.

 

 

 

“Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?” - Brian W. Kernighan
“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” - Antoine de Saint-Exupery

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Agree with ka7ehk, the fuses are critical. Specially with the most confusing check/uncheck stuff, care on this.

I think I will NEVER understand properly what is check, or uncheck towards 0/1 on Fuse presentation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The biggest common mistake in programming isn't with the programmers, it's with the C compiler writers.  They, all, to a man, absolutely refuse to create and implement error messages that make sense to a beginner that is going to be making all the common errors that generate these messages.  It's as if they simply can not lift themselves out of the 1970s _PDP-11_24-char-max_error_message mentality.   Forget a semi-colon? Get a message " error: expected initializer before '}' token".   Huh???   What could this possibly mean to a beginner?      How about after 50 years of C compiler development and hundreds of millions of dollars of software development, maybe you could change this to:   "error: expected initializer before '}' token.    Most likely cause: You have forgotten the semi-colon at the end of the line."

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
  1. Not understanding the datasheet.
  2. Not understanding the initial state of various IO registers.
  3. Not understanding how fast the code can run.
  4. Not understanding the implications of "blocking."
  5. Not understanding the limits of performance ("This is common and easy on my desktop; how come I can't do it on an AVR?"  There are currently discussions over on the Arduino forums for both "video compression on SAMD21" and "how come this VGA Camera Library isn't supported on SAMD21?"
  6. Not trusting the compiler. ("there's a compiler bug causing my program to not work!"  (almost certainly not.))
  7. Not checking for errors. Not knowing what to do with errors if they do occur and are noticed.
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Completely at random:

 

-using data types that are much too large for the data.  Don't use a 16-bit int to hold a value that ranges between 0 and 10.  This matters a lot for small micros with limited RAM.

 

-in like fashion, creating giant data structures or arrays without thinking how much RAM you have, and how much you will need.  It can really help to put constant data into flash and not in RAM (which is where it will go unless you explicitly specify otherwise)

 

(both of the above are about running out of resources.  You need to think in terms of bytes and megahertz, not gigabytes and gigahertz)

 

-as mentioned, interrupts without an ISR or proper use of 'volatile'.  More subtly, ISR <-> main code data corruption.

 

-putting delays (explicit or long operations such as serial debug calls) into code that needs to execute quickly.

 

-running at 1MHz when you think you're running at 8 or 20.

 

-not understanding the hardwire side, or the hardware/software interface/interaction

 

-not having the experience or knowledge to read data and understand sheets properly.

Last Edited: Sun. Aug 15, 2021 - 11:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:

The biggest common mistake in programming isn't with the programmers, it's with the C compiler writers.  They, all, to a man, absolutely refuse to create and implement error messages that make sense to a beginner that is going to be making all the common errors that generate these messages.  It's as if they simply can not lift themselves out of the 1970s _PDP-11_24-char-max_error_message mentality.   Forget a semi-colon? Get a message " error: expected initializer before '}' token".   Huh???   What could this possibly mean to a beginner?      How about after 50 years of C compiler development and hundreds of millions of dollars of software development, maybe you could change this to:   "error: expected initializer before '}' token.    Most likely cause: You have forgotten the semi-colon at the end of the line."

 

For once, I find myself almost agreeing with you. But on reflection, I think the missing semicolon is more a problem with the C syntax, rather than the compiler.

However, most of my work over the years has used GCC, maybe some of the higher priced compilers are smarter...

The big problem is that in C, the missing semicolon, or other mistakes, can show up as errors a page away - I've, on occasions, had to resort to crude binary chop methods to isolate the offending line of source. Not being a compiler writer, I can't say whether this is an easily soluble problem. No doubt finer minds will weigh in.

Four legs good, two legs bad, three legs stable.

Last Edited: Sun. Aug 15, 2021 - 11:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to develop a "programming mindset", in visualizing how some set of actions can be split into definable tasks to accomplish a goal...WHY are you using an IRQ...WHY did you decide you need floating point?  Why did you organize things this way rather than another way?

You code "works", but what about all of the exceptions?  You can now open a file and save some data, great...but what if the file is corrupt?  What if the file name is invalid? What if the write is too slow?  What if  access is locked out?  You need to consider more than just the baseline implementation.

 

A very common introductory misconception is to say:  dog = 3 * cat + 7   ...ok, cat is 10 so dog is 37.  But don't think that if later, cat becomes 5, dog follows along at 22..NOPE!

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ansh11 wrote:
What are the most common programing mistakes programmers make when writing code for embedded program

  • non-reentrancy
  • stack overflow

 

P.S.

ansh11 wrote:
But if you want to share some experience, please share.
Dead code kills.

Contexts - mechatronics, automotive (unintended acceleration)

A machine may kill an operator; if not then may injure an operator.

Do continual scrub of the requirements traceability matrix (system requirements, system design, hardware and software requirements, hardware and software design, HDL and code)

 


“firmware-specific” « Search Results « Barr Code (Embedded Gurus)

 

Dead Code and the Law of Unintended Consequences | Barr Group

How "brake override" stops runaway cars | Consumer Reports - YouTube (5m55s)

Desperate Teen Drives Car With Gas Pedal Stuck at 120 MPH - YouTube (1m47s)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Throw in another one, although it's an oddball:  Re-initializing the loop counter variable inside the loop.   I've gotten burned by that one.  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

John_A_Brown wrote:
However, most of my work over the years has used GCC, maybe some of the higher priced compilers are smarter...
or different [LLVM(Clang)] or verified and validated.

John_A_Brown wrote:
I've, on occasions, had to resort to crude binary chop methods to isolate the offending line of source. Not being a compiler writer, I can't say whether this is an easily soluble problem.
Likewise am not a compiler maintainer though am a linter operator (linting is a best practice)

 


CompCert: formally verified optimizing C compiler (AbsInt)

 

PC-lint Plus Online Demo - Gimpel Software - The Leader in Static Analysis for C and C++ with PC-lint Plus

the defect in question is in the next to last line of source code :

/*
    Welcome to the PC-lint Plus interactive demo.
    Press the 'Run' button above to analyze the sample code in this
    text area using PC-lint Plus. Messages will be displayed under
    the corresponding line. The 'Clear' button will hide these messages.

    You can enter your own sample code to evaluate PC-lint Plus.
    The options above can be used to choose whether to use C or C++ and
    to enable optional features such as MISRA rule enforcement.

    Note that MISRA support should be used with the matching language.
    E.g. if using MISRA C 2012 the language (which defaults to C++17)
    should be changed to C99 or C11.
*/

/* Library Function Semantics */
/* Floating Point Value Tracking */
void r(double);
void cr() {
    r(42)
}

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
You code "works", but what about all of the exceptions?
and assertions

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also got burned once by someone who was trying to translate my AVR asm code into C who managed to assume that all 'jmp's were logically equivalent to 'call's, which, after only a few trips around managed to smash the stack in a very bad way...  gchapman pointed this out before, and yes, it is a real thing.  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The classic programming error is surely just a write to unauthorized memory?

 

That can be a write through a corrupt/non-initialized pointer, a write beyond the bounds of an array, a write through a pointer of wider type than the actual destination etc. etc.

 

Here's just some:

{
    char * p;
    char array[10];
    char c;
    long * pl;
    
    *p = 'A'; // p was not initialized

    for (int i = 0; i <= 10; i++) {
        array[i] = i; // should have been < 10 not <= 10 !!
    }

    pl = &c;
    *pl = 'B'; // writes 4 bytes at 'c' not just one.
}

If you want to write "robust" code start with MISRA. A lot of very clever people spent a lot of time analyzing what the common errors in C (later C++) are and writing mandatory/advisory rules for things to be avoided to give you a chance of not falling into the usual pitfalls !

 

You might want to look at a language like Ada too. This builds into the language protections against may of the common pitfalls (like array bounds checking etc).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

The classic programming error is surely just a write to unauthorized memory?

 

Or perhaps the classic programming error is surely to write C for a microcontroller...  Stick to assembler.  S.   ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Scroungre wrote:
Or perhaps the classic programming error is surely to write C for a microcontroller...  Stick to assembler.  S.

I admire often what those C-people must know. You, Assembler lover, you can do anything with 50-odd Instructions plus some actions.

If you choose C-language, be prepared for all kind of programming situations, bugs of all sizes running around, even those of the type

"the only good bug is a dead bug" ref. Verhoeven: Starship Troopers.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

The classic programming error is surely just a write to unauthorized memory?

Specifically though; "The classic programming error is surely just a write to deallocated memory" surely ?

 

/**
 * Returning str is NOT alllowed.
 */
char * foo (uint8_t i)
{
    char str[8];
    itoa(i, str, 10);
    return str;
}

 

[Edit: What on earth has changed the line height in the Code Editor?]

 

Last Edited: Mon. Aug 16, 2021 - 11:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The most common programming error is a one-off error...do you start with item 1 or zero?...is the third byte rcvd really at location 2?  Causes much mayhem.

You find the avg of pressures p0-p32 by dividing by 32...and don't notice the issue for a long time, since all seems fine.

 

You assume a pin(s) remains the same during multiple calls during a block of conditionals  ---leading to "impossible"  logical results.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

grohote wrote:

Scroungre wrote:

Or perhaps the classic programming error is surely to write C for a microcontroller...  Stick to assembler.  S.

 

I admire often what those C-people must know. You, Assembler lover, you can do anything with 50-odd Instructions plus some actions.

If you choose C-language, be prepared for all kind of programming situations, bugs of all sizes running around, even those of the type

"the only good bug is a dead bug" ref. Verhoeven: Starship Troopers.

 

 

 

 

Strictly technically, the C coders do with exactly the same 50-odd instructions.  's just that they trust the compiler to write them for them.  laugh  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:

The biggest common mistake in programming isn't with the programmers, it's with the C compiler writers.  They, all, to a man, absolutely refuse to create and implement error messages that make sense to a beginner that is going to be making all the common errors that generate these messages.  It's as if they simply can not lift themselves out of the 1970s _PDP-11_24-char-max_error_message mentality.   Forget a semi-colon? Get a message " error: expected initializer before '}' token".   Huh???   What could this possibly mean to a beginner?      How about after 50 years of C compiler development and hundreds of millions of dollars of software development, maybe you could change this to:   "error: expected initializer before '}' token.    Most likely cause: You have forgotten the semi-colon at the end of the line."

 

 

I have started programming in rust and your point is very evident from that perspective because the compiler writers for rust have made big effort to generate informative error messages.

 

$ cargo build
   Compiling demo07 v0.1.0 (/home/xxxxxx/proj/rust/demo07)
error[E0308]: mismatched types
  --> src/main.rs:76:13
   |
76 |     qbuf[ix] = quat;
   |                ^^^^ expected `f64`, found array `[f64; 4]`

error[E0277]: the trait bound `usize: NdIndex<Dim<[usize; 2]>>` is not satisfied
  --> src/main.rs:76:2
   |
76 |     qbuf[ix] = quat;
   |     ^^^^^^^^ the trait `NdIndex<Dim<[usize; 2]>>` is not implemented for `usize`
   |
   = help: the following implementations were found:
             <usize as NdIndex<Dim<IxDynImpl>>>
             <usize as NdIndex<Dim<[usize; 1]>>>
   = note: required because of the requirements on the impl of `std::ops::Index<usize>` for `ArrayBase<OwnedRepr<f64>, Dim<[usize; 2]>>`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `demo07`

To learn more, run the command again with --verbose.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MattRW wrote:

Simonetta wrote:

The biggest common mistake in programming isn't with the programmers, it's with the C compiler writers.  They, all, to a man, absolutely refuse to create and implement error messages that make sense to a beginner that is going to be making all the common errors that generate these messages.  It's as if they simply can not lift themselves out of the 1970s _PDP-11_24-char-max_error_message mentality.   Forget a semi-colon? Get a message " error: expected initializer before '}' token".   Huh???   What could this possibly mean to a beginner?      How about after 50 years of C compiler development and hundreds of millions of dollars of software development, maybe you could change this to:   "error: expected initializer before '}' token.    Most likely cause: You have forgotten the semi-colon at the end of the line."

 

 

I have started programming in rust and your point is very evident from that perspective because the compiler writers for rust have made big effort to generate informative error messages.

 

$ cargo build
...
To learn more, run the command again with --verbose.

 

 

That WASN'T --verbose?  Oh dear me.  S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One might argue that the biggest problem programming issues is perhaps simply not planning your requirements before you start programming...

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The most common programming error that beginners make is giving up after 100+ attempts at getting some little thing to work right.

 

There's a scene in the movie "El Topo" where the macho gunfighter agrees to help the Master break rocks.  He bangs away on one rock forever, and then throws down his hammer and howls to the Master:  "I've hit this rock a thousand times, and Nothing!..."

To which the Master picks up hammer, taps the rock, and has it dissolve into dust, saying"...only a thousand times?..."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
This builds into the language protections against may of the common pitfalls (like array bounds checking etc).
Memory safe computer languages | AVR Freaks

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and creating correct requirements (Boeing 737 MAX)

(easier said than done)

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

barnacle wrote:
One might argue that the biggest problem programming issues is perhaps simply not planning your requirements before you start programming...

Requirements for software and hardware. 
Incomplete requirements, oversized requirements, and the worse: changed requirements, or inflated, or galloping.

No wonder all kinds of software problems may result.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One might argue that the biggest problem programming issues is perhaps simply not planning your requirements before you start programming...

That can be part of it, but often even that doesn't help, when people aren't really thinking about the problem---they just create 20 pages of nonsense.  Or they spend so much time invested in writing them that they can't bring themselves to toss them into the nearest trash bin even after realizing it is almost bunk... While yes, we probably could simply calibrate the adc & store the offset & gain factors in EEPROM, we already created a very comprehensive 10 page set of soldering  and software test requirements for swapping out AVR's until one is installed and measured displaying the correct offset.   This parts swapping & software check will meet our requirement that every unit performs to 1% or better.  This has already been approved by Hank, so it is best to move forward with other items.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Mon. Aug 16, 2021 - 03:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Probably the commonest mistake here is to just leap in and start throwing code straight into your editor - with no prior thought or strategy.

 

So you just end up with one big blob of code trying to do everything  and, when it doesn't work, no idea where to start looking for the problems.

 

Another is to give no consideration to how you will test & debug the code.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In this modern era, the biggest mistake that programmers make is ... to do programming.

 

Instead you should assume that whatever it is that you are going to be programming has actually already been programmed, tested, and uploaded to some coding-focused website.  All that you need to do is find it.

 

Then you can study the code and learn how it works: both the high-level language format like C++  and the low-level hardware interfacing of the microcontroller itself and its sensors.  Then modify it to the extent that it is needed, and get it working on your system platform.

 

A good internet search engine is more valuable to a modern programmer than a debugger.

 

Until you are an expert in some focused field, assume that you will be doing more code cutting-and-pasting than actual writing.

Last Edited: Wed. Aug 25, 2021 - 02:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 2

I'm not at all sure that I agree with Simonetta's comment above.

 

In concept it's fine, but my experience has been that lick-n-sticking existing code rarely requires less work than planning it from scratch, with the possible exception of indicating a suitable library to use. Modifying existing code means - to me - doing the work twice.

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

barnacle wrote:
I'm not at all sure that I agree with Simonetta's comment above.

In concept it's fine, but my experience has been that lick-n-sticking existing code rarely requires less work than planning it from scratch, with the possible exception of indicating a suitable library to use. Modifying existing code means - to me - doing the work twice.

 

I'm with you.  Code reuse is the magic bullet that never really was.  Sure, snips here and there, but it's more about rummaging through the junk box to find useful parts rather than reaching into the box to pull out a fully working Turbo Encabulator.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
Then you can study the code and learn how it works: both the high-level language format like C++  and the low-level hardware interfacing of the microcontroller itself and its sensors.  Then modify it to the extent that it is needed, and get it working on your system platform.

The trouble with that is that integrating 3rd-party code into your own requires a deal of programming skill & experience.

 

As does going through 3rd-party code to see what it does, and understand if it is actually appropriate to your requirements.

 

assume that whatever it is that you are going to be programming has actually already been programmed, tested, and uploaded to some coding-focused website. 

I'm not sure that assuming whatever you find on the interwebs has been (thoroughly) tested is a good idea ... ?

 

And a lot of code dumped in online repositories is poorly (if at all) documented.  frown

 

Yes, it's good to avoid re-inventing the wheel - but a beginner does still need to learn some basic skills to be able to select an appropriate wheel, and use it properly in their own design ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems like code you find for simple things (say, here's some code for an AD98765 temperature chip) ends up being someone's else's quick slop that you might have just as well done yourself.  You you might use it more as a starting point (and big revamp), or just do it yourself.

Code that is more technically involved (took someone a lot of care and work to make it happen), often seems to be better crafted.  So you can find someone's code to do a two dimensional 4th order spline fit & it may very well be quite ready for your adoption.  This could be for an Arduino or even a python-based setup.  Of course if you work on a Linux board, there's all kinds of things to choose from & you'd never be able to write even a fraction of it in your lifetime (just look at OpenCV)---so you must pick & choose carefully.

 

Regardless, if you want be a leader you need to do programming to get good at programming. Those who simply watch from the sidelines will eventually become your followers.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
Code that is more technically involved ...   someone's code to do a two dimensional 4th order spline fit

or, more AVR-related, things like protocol stacks, GUIs, etc ...

 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
you should assume that whatever it is that you are going to be programming has actually already been programmed, tested

 

Simonetta,

the real challenge is to accept the AVR challenge and go that deep -or high, nobody did before of you.

Once there, you will see much more challenges and you can choose which to follow.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simonetta wrote:
you should assume that whatever it is that you are going to be programming has actually already been programmed

I don't find that to be the case - why would people pay me to re-do stuff that's already done & dusted?

 

I guess what you really mean is that you need to distinguish what is run-of-the-mill, standard, done-&-dusted stuff from what is unique to the project?

 

In other words, where can you actually add value - rather than just doing a "me too".

 

Things like protocol stacks, standard algorithms, peripheral drivers, RTOS, etc would likely be candidates for treating as "components"

 

 

EDIT

 

But, again, this all assumes that you are already an established programmer.

 

A beginner is going to have to start by learning the basics - which, by definition, will all have been done before.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Aug 26, 2021 - 09:29 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

A common one for beginners is ignoring the return value from library routines: Why does my code sometimes times work and sometimes output garbage? Because the library routine FillBuffer returned an error code of -2 which means buffer overflow.

 

One I'm guilty of is excessive/pointless optimization. I had a clock project that ran the whole processor at 32kHz. To avoid LED flicker the interrupt routines needed aggressive optimization. I then proceeded to over-optimize basically all of the code as an educational exercise. (code attached for the curious.)

 

 

 

 

 

 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

balisong42 wrote:

One I'm guilty of is excessive/pointless optimization.

 

I do that to circuit board layouts.  I like to just leave them up on the screen(s) for a few days after completing the layout - and poke at them a little now and then, straightening this trace, shifting that one to a different layer, &c.  Of course, sometimes I come across a colossal blunder* that desperately needs fixing before the boards get ordered...  S.

 

* Actually, if I did it, it's a "Trivial Oversight".  If someone else did it, it's a "Colossal Blunder".  ;)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do that to circuit board layouts.  I like to just leave them up on the screen(s) for a few days after completing the layout 

Absolutely!!!  The worst thing is to see that if you scoot this chip over there and this thing over here, & rotate that connector 90 deg it is much cleaner (then you can't unsee it)..next thing you know, lots of traces are being ripped up. 

Do you reassign the IO pins 30 times, so that there are no crossovers? crying  It's nice to see the final result.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One of my mistakes in assembly programming, the common one, is not using labels for close jumps, using Rjmp PC+displacement, it saves a lot of non necessary labels.  Is there something more annoying that creating a label to be used just once, then you need to think what name you will use in such label, and end up using "k419" and stay afraid that maybe you already used K419 somewhere else... 

 

So I use 

 

     SBIS PortB,5

     Rjmp PC+3

     Do something else

     Ret

     Here is PC+3

 

The problem, is when the displacement is larger than 3, 4, or 8, and you count the instructions by hand and find it is 12, so you use PC+12, and it is wrong, or, later you change the code in between the Rjmp PC+Displacement and the destination, and it becomes 13 or 14 or 9 instructions, and you forget to fix it... 

 

You can go over the failure several times without noticing.

Everytime it happens, I promise myself to do not use Rjmp PC+Displacement, but 10 minutes later I am doing all over again.

 

I remember an assembler that I wrote in REXX (IBM mainframe) for Z80, I used a tricky thing for short labels.

 

I made possible to use labels as @0, @1, @2, ... several times, so the code could have fifty labels @1, considering they are separated by a label starting with Uppercase.

 

Example:

 

MainRoutine:

    any quantity of labels starting with @...

 

SecondRoutine:

    Because SecondRoutine label starts with uppercase, it resets all the @... labels used on MainRoutine.

 

During the assembling, internally I just converted @0 label from MainRoutine as "MainRoutine@0" and the other "SecondRoutine@0" so the assembly knew exactly where each label is in the addressing and doesn't confuse them.

 

Interesting enough, I also made possible to have another routine label starting with uppercase and not stealing the temp labels from the previous uppercase starting label.

The way to do it, was making sure that the first temp label is always @0, so in real, it is the @0 that effectively reset the mother name for the temp labels.  It is a double security.

 

So, it could be;

 

MainRoutine:

    @0                 ; internally is MainRoutine@0

    Jmp @2

    @1                 ; internally is MainRoutine@1

SecondRoutine:

    @2                 ; internally is MainRoutine@2

    @3                 ; internally is MainRoutine@3

ThirdRoutine:

    @0                 ; internally is ThirdRoutine@0

    @2                 ; internally is ThirdRoutine@2

 

The Jmp @2 will jump to @2 after SecondRoutine, since it makes part of MainRoutine, and not to the @2 on the ThirdRoutine, it is a complete different set, since it there is a @0 reseting there.

     

 

Wagner Lipnharski
Orlando Florida USA

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ avrcandies :

I try to get most of that out of the way early on.  I think one of the worst bad habits of PCB layout is being NOT willing to rip up a partially done board when a new alignment springs to mind.  Try several alignments before really committing yourself to part locations.  And yes, reassigning pins is incessant!  This is (I think) one reason why having one person do both the schematics and the layout is essential - because otherwise you get horrible layouts because the schematic guy doesn't want to mess up his pretty schematic.

 

@ wagnerlip :

Some compilers will let you do things like "rjmp 1f" which is "jump forwards to the next label '1'", with 1b (backwards) 2f (forwards to the next '2') &c., but mine doesn't, so I use alphabetical (lower-case) suffixes.  Yes, I get a LOT of stray labels, but in routine FOO: all are easily categorized as "FOOa", "FOOb", and if you want a 'bail out' label, "FOOz".    After a lot of edits you get labels like "FOOabc" meaning 'after FOOabb, but before FOOb', but they can be lived with.  As suffixes, they're not going to be re-used elsewhere, unless you have a lot of functions named "FOO".

 

S.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I try to get most of that out of the way early on. 

You can try early on, but once the traces start to take shape, only then do you get the real story.  Moving one chip 1/2 inch to the left can make quite an unexpected improvement (or opposite)...Almost like changing your first 3 moves in a chess game.

I think one of the worst bad habits of PCB layout is being NOT willing to rip up a partially done board when a new alignment springs to mind.

 I don't appreciate board design houses sometimes, since they are often intent on merely cranking out something & if you say how bout swapping these two chips, it will really clean up by leaps and bounds...they of course say... well it's already laid out & functional.

(course, I say that to the wife when she talks about rearranging all the furniture).

 

Some folks just turn on the autorouter & head for the beach...maybe they are right!  "Say Boss, this was tough; see that tangle of traces I had to create?"  Why yes, you deserve a big raise!!

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:

Almost like changing your first 3 moves in a chess game.

 

Ahh, but the beauty of doing so in board layout means you get a do-over.  In chess, you just lose.  The hard part is deciding when taking the mulligan is worth it or not: it almost always is.  If nothing else, it lets you make a board you're proud of.  Don't let the sunk cost (traces already drawn) get in the way of making it better.

 

I have purchased autorouters.  They're expensive.  They suck.  Neither for personal nor professional use have I ever shipped an auto-routed layout to a board house. 

 

And I don't have a wife...  wink   S.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not having a wife is not prerequisite for choosing not to use an autorouter. I have a wife, but I still don't use autorouters. I hate being told that this way is better than that way, but I can put up with it from the wife.

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When all else fails, one can make local labels based on line numbers.

For a long time, I've mostly used gcc,

so things like 1f and 3b do the trick for me.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Assembler, and also C-language modular approach can be precious.

What I do not know is, which is an optimum of the file length, in lines.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What I do not know is, which is an optimum of the file length, in lines.

Perhaps 10 pages worth?  Break things down into useful pieces/functionalities.  Too many files can mean you spend all your time opening and manipulating lots of files, ope, close, search, etc, etc.

It is a balancing act, as huge files can be just as painful.   How about no "files"--let some system dig, digest & report the info you need to see--you don't even know where it resides---utopia?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Fri. Aug 27, 2021 - 08:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

barnacle wrote:
... I still don't use autorouters. I hate being told that this way is better than that way, but I can put up with it from the wife.

So when she slates your PCB layout is her way a genuine improvement or just a change to make it look nicer ?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Popular mistakes are also:

 

  • using assigment operator = instead of compare ==
  • using "premature optimization is root of all evil" as an excuse to not doing any optimization whatsover - it's not even whole saying!
  • variable shadowing - hiding global or even local variables by local variables with same name (usually because of blind copy pasting of everything without thinking about it)
  • variable definitions faaaaaar before it's use (aka strict C foot-shooting). But in C++ it's much better to scope visibility of variables as short as it's possible and never reuse variables.
  • already mentioned arrays and out of bounds access (small buffers, miscounting)
  • comparing C strings by == (needs strcmp or similar, == compares only pointers)
  • sizeof on pointer (static array passed as type arr[] which is equivalent to  type * arr)

 

For c++ it's also overusing dynamic allocation (in Arduino it is overusing String concatenations)

Also popular mistakes are using lambdas as callback and expect they'll throw exceptions right the way, or that they changes anything outside... (callbacks are usually called who knows when) - but it's not used much in embedded

 

Computers don't make errors - What they do they do on purpose.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:
--let some system dig, digest & report the info you need to see--

Editor's Notes | The Embedded Muse 423 by Jack Ganssle

[last paragraph]

Alas, it appears my favorite metrics tool is no longer available. Msquaredtechnologies's RSM is/was a $200 comprehensive program that analyzed even huge code bases. I even ran it against Linux once. Though the web site is still there it sports broken links, the ordering page does not work and they don't respond to email. An alternative is the free Sourcemonitor.

RSM was in a set of inexpensive tools :

Inexpensive Firmware Process Improvements for Small Teams - Barr Group

by Susan McCord

[3/4 page]

Slide #48 - My Tools, $597.95

 


C program analysis | AVR Freaks

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

N.Winterbottom wrote:

barnacle wrote:
... I still don't use autorouters. I hate being told that this way is better than that way, but I can put up with it from the wife.

So when she slates your PCB layout is her way a genuine improvement or just a change to make it look nicer ?

 

 

Nah, usually she just laughs because I put something on upside down.

 

Neil

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Scroungre wrote:

@ wagnerlip :

Some compilers will let you do things like "rjmp 1f" which is "jump forwards to the next label '1'", with 1b (backwards) 2f (forwards to the next '2') &c., but mine doesn't, so I use alphabetical (lower-case) suffixes.  Yes, I get a LOT of stray labels, but in routine FOO: all are easily categorized as "FOOa", "FOOb", and if you want a 'bail out' label, "FOOz".    After a lot of edits you get labels like "FOOabc" meaning 'after FOOabb, but before FOOb', but they can be lived with.  As suffixes, they're not going to be re-used elsewhere, unless you have a lot of functions named "FOO".

 

Nothing like time and experience to promote some natural evolution and sometimes common solutions among life forms.

I use FOO9 as the exit or return part of the routine, no matter if it is in the middle or end of it.

For simplicity, since last millennium, I use AVRASM2 as the assembler, PN2 (programmer's notepad) as editor, and AVRDUDE (or AVRDUDESS) as programmer.

PN2 has nice programmable shortcuts to call aAVRASM2 and DUDE, by just pressing Ctrl+anykey.

Wagner Lipnharski
Orlando Florida USA