Outsourcing >

SSI Quality Process Overview Customer Satisfaction Our Engineers Questions to Ask Technical Lab Testimonials Whitepapers
SSI Embedded Systems Trust Facts

Fact: Over 50% of SSI Staff has 8 or More Years Experience

"You can count on the work being done right and on time." ~ SSI Client

Fact: 30% of SSI staff has twelve or more years experience

"The people blended in and became part of the design team."

Fact: Experienced Team Lead manages all projects

"I was impressed with the quality of SSI's work throughout this contract. I appreciated their ability to work with minimal guidance, and minimal design details. And I greatly appreciated their suggestions and alternate design proposals. Their willingness to work overtime when necessary to meet deadlines was greatly appreciated." ~ SSI Client

Fact: All SSI staff is trained on the Quality Development Process

"Work is spectacular. More exceptional than I thought it would be. Sensors work great. They can detect the slightest pressure accurately. It is WAY beyond my expectations." ~ SSI Client

Fact: Long term staff retention rate at SSI is > 95%

Fact: SSI's Internal Software process operates as CMM Level 3

"The experience was a good one" ~ SSI Client

Fact: SSI has been in business 16+ years

"The best thing about working with SSI is that the people genuinely care about the success of the overall project. Typical contractors stop when they have merely met the letter of the contract that they are bound to; where as, SSI is willing to go above and beyond to drive a project to completion and ultimately success." ~ SSI Client

Fact: Over half of SSI Business is from returning clients

"I would use SSI again" ~ SSI Client

Fact: SSI client relationships last several years

"The best thing about working with SSI is that the people genuinely care about the success of the overall project. Typical contractors stop when they have merely met the letter of the contract that they are bound to; where as, SSI is willing to go above and beyond to drive a project to completion and ultimately success." ~ SSI Client

Fact: SSI's Customers report a consistent 4.5 out of 5 rating for satisfaction

"Keep finding people who can get to the root of the issue and resolve it as specified. [Your Engineer] is golden!." ~ SSI Client

Fact: 100% of clients surveyed said they would recommend SSI to others

"SSI will deliver what is promised on a timely basis." ~ SSI Client

Fact: SSI Supports Continual Employee Training

"Consistent high quality engineers who perform very well. SSI is the only company -- contracting or consulting -- who consistently provides the best talent who are not only technically accomplished but have excellent verbal and personal skills. I have not seen anything like it before." ~ SSI Client

SSI Embedded Trust Facts

Best Practices for Writing Efficient Code

Writing Efficient Code | Best Practices for Writing Efficient Code | Efficient Code Example
  • Use pointer arithmetic where ever possible, especially in iterative situations.

  •  
  • Pay attention to the size of the data that you are using. Counting to 10 using an I32U can be inefficient and wasteful of RAM. This also applies to subscripts. Using a 32 bit subscript could take considerably longer to execute than using an 8 bit subscript.

  •  
  • By ANSI definition all values used in a calculation are promoted to the size of the largest value. For example:
  • i8uResult = i8uValue2 * i32uValue1 / i16uValue2 + 1;

    All of the values in this statement will be promoted to I32U because that is the largest value used. This assignment would cause three 32 bit operations to be performed to yield an 8 bit result.

    Note: When constants are used (either explicitly or in #defines) their data size is the same as the data size of int (unless explicitly specified in the constant or with a type cast).

  • Where ever possible let the compiler do your math at compile time not run time. For example if you have an array of structures at a specific address and you want the ending address of this array use the following:
  • #define END_ADDRESS_OF_ARRAY (ARRAY_BASE + sizeof(ST_STRUCTURE) * ARRAY_ELEMENTS)

  • Do repeated identical calculations only once and store the results in statics or globals.

  •  
  • Re-use temporary variables. This saves memory and may allow for better register re-use.

  •  
  • Depending on the compiler, putting lengthy loops (large number of iterations) in a separate function may optimize better. This is due to how the compiler determines what to put in registers. A small tight loop in a large function may not optimize as well as the same loop it in a function by itself (not counting the overhead of the function call itself).

  •  
  • Pass as few parameters as possible to a function. Each parameter passed takes time to put on the stack and read from the stack.

  •  
  • Pass non-atomic data types by pointer rather then putting them on the stack. This takes less time then copying them onto the stack and also saves on stack space.

  •  
  • Avoid excessive function call nesting as each function call requires stacking and unstacking of parameters as well as the actual function call.

  •  
  • In extremely time tight situations consider in-lining code to save the over head of the function call at the expense of code size.

  •  
  • If you are using many writes to multiple bits in a bit fielded structure in a single function, consider using a byte (or word) wide write instead. Though this is makes the code a little less obvious it reduces the instructions executed. For example replacing 8 one bit bit field writes for a single byte write saves 7 write instructions and possibly more depending on the microprocessor.

  •  
  • On some microprocessors the RAM is faster than the FLASH. On these systems it might be necessary to use initialized data rather than const data and to possibly put extremely time tight code in RAM.

  •  
  • Use table lookups where possible for complex math. This can save a significant amount of processing time at the expense of RAM.

  •  
  • Keep functions as small as possible. They tend to optimize better.

  •  
  • If at all possible avoid using sprintf and scanf or any of its derivatives. These are generally considered the largest and slowest of the standard library functions. Use to itoa()/atoi() family of functions to convert from hex/decimal to ASCII and vice versa.

  •  
  • Use memset() and memcpy() for contiguous memory writes and copies. Many compilers have these functions written in assembler and hand optimized. The same is true for strcpy() and strncpy().

  •  
  • Take advantage of the microprocessor’s register size when copying data. Doing 32 bit reads and writes on a 32 bit processor with a 32 bit data but is much more efficient then doing 8 bit writes. If the 32 bit microprocessor is using a 16 bit bus, however, it might be more efficient to do 16 bit reads and writes.

  •  
  • By the ANSI standard the register keyword is only a suggestion to the compiler and behaves differently for each compiler. On the PIC C30 compiler a variable with the register keyword is permanently locked into a register and that register is no longer available to use for anything else.

  •  
  • Use shifts instead of divides or multiples where ever possible.

  •  
  • Use i32uValue >>= 6; rather than i32uValue /= 64;

Writing Efficient Code | Best Practices for Writing Efficient Code | Efficient Code Example

SUBSCRIBE TO NEWS & EVENTS
The Real Time Review brings you the latest embedded software news and technical articles - published approx. six times throughout the year.
> VIEW ALL NEWS

RSS Feed
A Certified Women's Business Enterprise and Member of the Illinois Technology Association