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

Example of Efficient Code

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

Sample Program

The following program and the related chart give an example of some of the methods mentioned here and how long they take to execute on a PIC18 microprocessor with different types of optimization enabled.

#include "ssi_types.h"

#define ARRAY_SIZE  10

typedef struct
{
    I32U    i32uDummy1;
    I32U    *pi32uPointer;
    I32U    *pi16uPointer;
    I32U    *pi8uPointer;
    I32U    i32uDummy2;
} ST_MY_STRUCT;

ST_MY_STRUCT    astMyStruct[ARRAY_SIZE];

I32U    ai32uMyArray[ARRAY_SIZE];
I16U    ai16uMyArray[ARRAY_SIZE];
I8U     ai8uMyArray[ARRAY_SIZE];

void    Foo( void );

void    main( void )
{
    Foo();

/*  return -1;*/
}

void Foo( void )
{   
    I32U            i32uCounter;
    I16U            i16uCounter;
    I8U             i8uCounter;
    I32U            i32uMyData;
    I32U            i16uMyData;
    I32U            i8uMyData;

    ST_MY_STRUCT    *pastMyStructPointer;
    I32U            *pai32uMyArrayPointer;
    I16U            *pai16uMyArrayPointer;
    I8U             *pai8uMyArrayPointer;

    /*
        Initialize the pointers in the structure
    */
    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; )
    {
        astMyStruct[ i8uCounter ].pi32uPointer = &i32uMyData;
        astMyStruct[ i8uCounter ].pi16uPointer = &i16uMyData;
        astMyStruct[ i8uCounter++ ].pi8uPointer =  &i8uMyData;
    }

    /*
        Sample Code Snippet #1 - 32 Bit Counter / 32 Bit Array
    */
    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(astMyStruct[ i32uCounter ].pi32uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 32 Bit Counter / 32 Bit Array
    */
    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; )
    {
        *(astMyStruct[ i32uCounter++ ].pi32uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 32 Bit Counter / 32 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(pastMyStructPointer->pi32uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 32 Bit Counter / 32 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai32uMyArrayPointer = ai32uMyArray;

    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(pai32uMyArrayPointer++) += 1;
    }

    /*
        Sample Code Snippet #1 - 32 Bit Counter / 16 Bit Array
    */
    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(astMyStruct[ i32uCounter ].pi16uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 32 Bit Counter / 16 Bit Array
    */
    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; )
    {
        *(astMyStruct[ i32uCounter++ ].pi16uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 32 Bit Counter / 16 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(pastMyStructPointer->pi16uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 32 Bit Counter / 16 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai16uMyArrayPointer = ai16uMyArray;

    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(pai16uMyArrayPointer++) += 1;
    }

    /*
        Sample Code Snippet #1 - 32 Bit Counter / 8 Bit Array
    */
    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(astMyStruct[ i32uCounter ].pi8uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 32 Bit Counter / 8 Bit Array
    */
    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; )
    {
        *(astMyStruct[ i32uCounter++ ].pi8uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 32 Bit Counter / 8 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(pastMyStructPointer->pi8uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 32 Bit Counter / 8 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai8uMyArrayPointer = ai8uMyArray;

    for ( i32uCounter = 0 ; i32uCounter < ARRAY_SIZE ; i32uCounter++ )
    {
        *(pai8uMyArrayPointer++) += 1;
    }

    /*
        Sample Code Snippet #1 - 16 Bit Counter / 32 Bit Array
    */
    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(astMyStruct[ i16uCounter ].pi32uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 16 Bit Counter / 32 Bit Array
    */
    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ;  )
    {
        *(astMyStruct[ i16uCounter++ ].pi32uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 16 Bit Counter / 32 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(pastMyStructPointer->pi32uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 16 Bit Counter / 32 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai32uMyArrayPointer = ai32uMyArray;

    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(pai32uMyArrayPointer++) += 1;
    }

    /*
        Sample Code Snippet #1 - 16 Bit Counter / 16 Bit Array
    */
    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(astMyStruct[ i16uCounter ].pi16uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 16 Bit Counter / 16 Bit Array
    */
    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ;  )
    {
        *(astMyStruct[ i16uCounter++ ].pi16uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 16 Bit Counter / 16 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(pastMyStructPointer->pi16uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 16 Bit Counter / 16 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai16uMyArrayPointer = ai16uMyArray;

    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(pai16uMyArrayPointer++) += 1;
    }

    /*
        Sample Code Snippet #1 - 16 Bit Counter / 8 Bit Array
    */
    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(astMyStruct[ i16uCounter ].pi8uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 16 Bit Counter / 8 Bit Array
    */
    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ;  )
    {
        *(astMyStruct[ i16uCounter++ ].pi8uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 16 Bit Counter / 8 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(pastMyStructPointer->pi8uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 16 Bit Counter / 8 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai8uMyArrayPointer = ai8uMyArray;

    for ( i16uCounter = 0 ; i16uCounter < ARRAY_SIZE ; i16uCounter++ )
    {
        *(pai8uMyArrayPointer++) += 1;
    }



    /*
        Sample Code Snippet #1 - 8 Bit Counter / 32 Bit Array
    */
    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(astMyStruct[ i8uCounter ].pi32uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 8 Bit Counter / 32 Bit Array
    */
    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; )
    {
        *(astMyStruct[ i8uCounter++ ].pi32uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 8 Bit Counter / 32 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(pastMyStructPointer->pi32uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 8 Bit Counter / 32 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai32uMyArrayPointer = ai32uMyArray;

    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(pai32uMyArrayPointer++) += 1;
    }

    /*
        Sample Code Snippet #1 - 8 Bit Counter / 16 Bit Array
    */
    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(astMyStruct[ i8uCounter ].pi16uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 8 Bit Counter / 16 Bit Array
    */
    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; )
    {
        *(astMyStruct[ i8uCounter++ ].pi16uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 8 Bit Counter / 16 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(pastMyStructPointer->pi16uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 8 Bit Counter / 16 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai16uMyArrayPointer = ai16uMyArray;

    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(pai16uMyArrayPointer++) += 1;
    }

    /*
        Sample Code Snippet #1 - 8 Bit Counter / 8 Bit Array
    */
    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(astMyStruct[ i8uCounter ].pi8uPointer) += 1;
    }

    /*
        Sample Code Snippet #2 - 8 Bit Counter / 8 Bit Array
    */
    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; )
    {
        *(astMyStruct[ i8uCounter++ ].pi8uPointer) += 1;
    }

    /*
        Sample Code Snippet #3 - 8 Bit Counter / 8 Bit Array
    */
    /*
        Point to the start of the structure array
    */
    pastMyStructPointer = astMyStruct;

    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(pastMyStructPointer->pi8uPointer) += 1;
        pastMyStructPointer++;
    }

    /*
        Sample Code Snippet #4 - 8 Bit Counter / 8 Bit Array
    */
    /*
        Point to the start of the Array.
    */
    pai8uMyArrayPointer = ai8uMyArray;

    for ( i8uCounter = 0 ; i8uCounter < ARRAY_SIZE ; i8uCounter++ )
    {
        *(pai8uMyArrayPointer++) += 1;
    }
}

void LocalItoa1( I16U i16uValue, char *pcBuffer, I8U i8uBuflen )
{
    I8U i8uCount;

    pcBuffer += ( i8uBuflen - 1 );

    for ( i8uCount = 0 ; i8uCount < i8uBuflen ; i8uCount++)
    {
        *pcBuffer-- = (i16uValue % 10) + 0x30;
        i16uValue /= 10;
    }
}

void LocalItoa2( I16U i16uValue, char *pcBuffer, I8U i8uBuflen )
{
    pcBuffer += ( i8uBuflen - 1 );

    while ( i16uValue > 0 )
    {
        *pcBuffer-- = (i16uValue % 10) + 0x30;
        i16uValue /= 10;
    };
}
  Execution Speed in uS
  PIC18F6621 No Optimization
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1 600 600 600 546 546 546 391 391 391
Snippet 2 670 670 670 526 526 526 401 401 401
Snippet 3 569 569 569 505 505 505 440 440 440
Snippet 4 509 569 369 445 405 305 380 340 268
                   
  PIC18F6621 Debug Optimization
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1 560 560 560 516 516 516 371 371 371
Snippet 2 640 640 640 496 496 496 381 381 381
Snippet 3 539 539 539 485 485 485 420 420 420
Snippet 4 469 449 369 415 496 305 350 330 245
                   
                   
  PIC18F6621 Full Optimization
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1 892 892 892 724 724 724 575 575 575
Snippet 2 852 852 852 648 648 648 545 545 545
Snippet 3 961 961 961 783 783 783 696 696 696
Snippet 4 849 809 549 671 631 421 582 542 358
                   
                   
  PIC18F6622 No Optimization w/Extended Instructions
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1 574 574 574 458 458 458 315 315 315
Snippet 2 634 634 634 458 458 458 315 315 315
Snippet 3 478 478 478 362 362 362 319 319 319
Snippet 4 398 358 328 282 242 212 239 199 192
                   
                   
  PIC18F6622 Debug Optimization w/Extended Instructions
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 32 Bit Addition 8 Bit Addition 32 Bit Addition 32 Bit Addition 8 Bit Addition 32 Bit Addition 32 Bit Addition 8 Bit Addition
Snippet 1 544 544 544 418 418 418 295 295 295
Snippet 2 604 604 604 428 428 428 295 295 295
Snippet 3 458 458 458 332 332 332 299 299 299
Snippet 4 369 348 328 242 222 202 209 189 190
                   
                   
  PIC18F6622 Full Optimization w/Extended Instructions
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1 792 792 792 662 662 662 395 395 395
Snippet 2 732 732 732 632 632 632 415 415 415
Snippet 3 752 752 752 564 564 564 483 483 483
Snippet 4 520 500 480 330 310 290 253 233 234
                   
                   
  Function Size in Bytes
  PIC18F6621 No Optimization
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1                  
Snippet 2                  
Snippet 3       0xff4          
Snippet 4                  
                   
  PIC18F6621 Debug Optimization
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1                  
Snippet 2                  
Snippet 3       0xf48          
Snippet 4                  
                   
                   
  PIC18F6621 Full Optimization
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1                  
Snippet 2                  
Snippet 3       0x4d8          
Snippet 4                  
                   
                   
  PIC18F6622 No Optimization w/Extended Instructions
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1                  
Snippet 2                  
Snippet 3       0xbfa          
Snippet 4                  
                   
                   
  PIC18F6622 Debug Optimization w/Extended Instructions
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 32 Bit Addition 8 Bit Addition 32 Bit Addition 32 Bit Addition 8 Bit Addition 32 Bit Addition 32 Bit Addition 8 Bit Addition
Snippet 1                  
Snippet 2                  
Snippet 3       0xb48          
Snippet 4                  
                   
                   
  PIC18F6622 Full Optimization w/Extended Instructions
  32 Bit Counter 16 Bit Counter 8 Bit Counter
  32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition 32 Bit Addition 16 Bit Addition 8 Bit Addition
Snippet 1                  
Snippet 2                  
Snippet 3       0x420          
Snippet 4                  
                   
                   
 

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