Showing posts with label embedded. Show all posts
Showing posts with label embedded. Show all posts

Wednesday, 27 December 2017

C/C++ Stop Miss using inline.... PLEASE!

This is a plea, from the bottom of my rotten black heart, please... Please... PLEASE stop miss using the inline directive in your C and C++.

Now, I can't blame you for this, I remember back in the 90's being actually taught (at degree level) "use inline to make a function faster", and this old lie still bites today.

inline does not make your function faster, it simply forces the compiler to insert "inline" another copy of the same code whenever you call it, so this code:

#include <iostream>

inline void Hello()

{
    std::cout << "Hello";

}

int main ()
{
    Hello();
    Hello();
    Hello();
}

Turns into the effective output code of:

int main ()

{
    std::cout << "Hello";

    std::cout << "Hello";
    std::cout << "Hello";
}

What does this mean in practice?  Well, you saves yourself a JMP into the function, and the position on the stack holding the return address, and the RET from the function which pops off the stack and returns from the function.

This is WHY people were told to use inline to make things faster in the 90's, I was taught this when I a system with around 254K of working RAM for the programs I was writing, saving that space on an 8K stack was important in complex systems, especially if you were nesting loops of calls.

However, today, on a modern processor, even modern embedded processors, DO NOT DO THIS!

You're no longer saving anything, you're in fact making your code bigger and slower as suddenly your program expands in size and you are having to fetch more and more from the slower RAM layers rather than the program instructions page fitting into the lower CACHE layers.

As you get page misses you fetch more, you literally stop the program and switch context to another item and then switch back, literally halting your program in its tracks as it suddenly had to go load the N'th of possibly thousands of repeated stanza's of code.

Don't do, this, don't lumbar yourself, let the compiler handle it's own optimizations, they're pretty good at it!

Now some of you will be saying "yeah, no shit Xel, what's your point?"... My point is I recently had around 4000 lines of code handed to me, a huge long listing, and around 40% of it was a series of functions.  This whole thing could compile down to around 62K.... But when compiled it was just over 113K... This was too big to fit into the memory of the micro-controller it was for.

The developer had been working merrily over the yule tide, happy and satisfied their code would work, they went to work this morning and instead of running the code on the IDE within an emulator, they actually ran it on the metal.

It crashed, and they couldn't figure out why, the size was why.

And then they couldn't work out why the code was so big... It is tiny code.

They came, cap in hand, to myself - and I took no small satisfaction in rolling my eyes and telling them to remove the "inline" from EVERY function... "But it'll run so slowly" they decried... "REMOVE THE INLINE".

Of course it works, they have the system fitting into the micro-controller RAM, the stack is working a lot harder, their code is a lot smaller, and they are now in possession of a more balanced opine on "inline".

* EDIT *

One person, yes hello Hank, asked me "why", why was this a not a problem on the emulator, but was a problem on the bare metal, well the bare metal was using a different compiler than the pseudo compiler for the windows based IDE, the Windows based IDE was actually running the code through a compiler which ignored "inline", and so produced code a little like this:

(Image Courtesy "CompilerExplorer")

You can see that even though "int square(int)" is marked "inline" it contains the push to the stack and the "pop ret" pairing, and making it a call from main results in two function calls to the same assembler.

The bare metal compiler did not, an undocumented difference I might add.

Friday, 16 December 2016

Software Engineering : Is not Engineering

Right I'm guilty, and annoyed at myself, and making a change... Though I might still keep this as a tab on posts... I AM NOT GOING TO USE THE TERM "SOFTWARE ENGINEER" anymore....

This makes my degree certificate wrong, as it clearly states "Software Engineering", but even though that is indeed what I do every day, and what I read about every night, it is not what; nor who; I am... I am a programmer, a hacker (in the traditional sense), a tinkerer and a student of all things software.

Many other writers have call us programmers out on this, and finally, I'm going to eat humble pie and agree, when one sits down to write code one is not doing what the great engineers did, we are not forging rail-ways, bridges, hulls of great ships or physical tangible results which must stand the test of time.

We are building a more ethereal, almost smoke and mirror concept, results through the action of our instructions through another, that is programming it is what I do.

Why do I want to make this distinction?  Well, as you may tell from some of the recent posts around here, I've been involved in merging parts of teams and companies, meeting both incoming and shifting personnel to fit them into the matrix that spells "results" for a company.

No code has yet been cut, but a new team, and new ideas might very well be needed.  In turn I have reached out there and been talking to others, to recruiters, to other companies, and indeed I've sat before other people.

My friends also call upon my expertise, as one of the few from our graduating class still working in Software or indeed technology, I am often called upon for a little technical guidance.

Results have been mixed, but the determinable difference I have had between success and failure has relied, nearly exclusively, on the other party understanding the term "Software Engineer", it does not mean we can programme your VCR, set the clock on your Microwave, or save your phone contacts to your SIM card.  It means we are able to employ structured methods, to define procedure, and to design, write and test then document code as products for use or sale.

This does not include our being Electrical, Mechanical or Structural Engineers!

I am not trying, willing, or able to build the next Channel Tunnel, or Skylab, or HMS Bullshit.  I am able to cut code to make an existing system, or device, bend to the will of requirements upon it, I am able to look at the said device and decide whether it is fit for the purpose or not, I am not creating that device!

Creating said device is Mechanical or Electrical Engineering, I am Software, the use of the "Engineer" moniker is causing some confusion, some blurring of lines and so to help delimit this boundary and stop this confusion from now on I will self identify as a Programmer, and cease to try to explain all that this entails.

I am a Programmer, a Lead Programmer, a Systems Programmer, a Device Programmer, a Prototype Programmer, a Senior Programmer, a Team Leading Programmer, a Development Provisioning Programmer, no longer am I an Engineer!

Tuesday, 12 July 2016

Software Engineering : Arduino Uno - Flashing Clock

What is this flashing clock?  Well, it's just an arduino uno, with three LED's, one each for the seconds, minutes and hours.  They don't show the time, they just flash as each period they're counting passes.

So, we're going to count the seconds and flash just the second LED.  Then each 60th flash, we reset the seconds counter, increment the minute counter and have the minute LED flash.  Ditto for the hour counter each 60th minute.

I've got the LED's VCC legs connected to digital pins 8, 9 and 10, with the other connected to the three grounds.  When I come to make this an actual board I can have a single ground pin being used up, rather then using all three on the board.

An important part of the code to focus on is how to turn on each light in turn...

If you want to turn on the second, the minute and the hour LED all at the same time, you could have some horrid "if" statement controlling them, but much more clean looking is this:

// Turn lights on
switch(CycleCount)
{
    case 2:  digitalWrite(HourPin, HIGH);
    case 1:  digitalWrite(MinutePin, HIGH);
    case 0:  digitalWrite(SecondPin, HIGH);
                break;
}

So, the count is reset to zero each cycle it is incremented if we add to the minutes, and incremented if we add to the hours.

The switch statement then drops through, notice that there are no "breaks" on the 2 and 1 (hours & minutes) cases.  So, if we have incremented the hour, we have a count of two and so we set the HourPin High, drop through to the MinutePin High and finally the Second Pin High before we break.

Likewise, if we only set the minutes this cycle, then the count will be one, so the switch statement will drop down to the Minute Pin high, skipping the Hour pin totally.

The effect of this is to seemingly instantly turn on all the LED's each cycle as they are needed together, there is no humanly noticeable staggering of the lights coming on, as one might get with an if statement, or once might get if one were to set the LED as we increment the values.  Doing Lights on when we increment actually clearly shows the LED's going on and off in a staggered pattern.

Our task after turning all of them on is to just wait a short time (100 milliseconds) and then turn them all off with another switch statement.  And with them all off again simply wait for the remainder of the second (i.e. 900 ms).


Keep this in mind as you read the following code:

// The pins
int SecondPin = 8;
int MinutePin = 9;
int HourPin = 10;

// The counts
int CycleCount = 0;
int SecondCount = 0;
int MinuteCount = 0;
int HourCount = 0;

void setup() 
{ 
  // Setup the pins
  pinMode (SecondPin, OUTPUT);
  pinMode (MinutePin, OUTPUT);
  pinMode (HourPin, OUTPUT);
}

void loop() 
{
  // Increment the counts
  CycleCount = 0;
  SecondCount = SecondCount + 1;
  if ( SecondCount > 59 )
  {
      SecondCount = 0;
      ++MinuteCount;
      ++CycleCount;

      if ( MinuteCount > 59 )
      {
        ++CycleCount;
        MinuteCount = 0;
        ++HourCount;

        if ( HourCount > 23 )
        {
          HourCount = 0;
        }
      }
  }

  // Turn lights on
  switch(CycleCount)
  {
    case 2:
      digitalWrite(HourPin, HIGH);
    case 1:
      digitalWrite(MinutePin, HIGH);
    case 0:
      digitalWrite(SecondPin, HIGH);
      break;
  }   

  // Light are on for 1/10 of a second
  delay(100);

  // Tuen lights off
  switch(CycleCount)
  {
    case 2:
      digitalWrite(HourPin, LOW);
    case 1:
      digitalWrite(MinutePin, LOW);
    case 0:
      digitalWrite(SecondPin, LOW);
      break;
  }   

  // Lights all off for 9/10 of a second
  delay (900);
}

If you found anything of use here, please return again, and don't forget to check out my other YouTube videos.

Tuesday, 24 February 2015

Working with Taiwan Twinglish Embedded Development Kits

You know sometimes, I wish people would just write a manual.  I've just come across a chap who wants to sell a development kit to the company I work for, he's in Taiwan and very excited, he knows all about his kit, and he's been on the phone bulling it up for the boss.

He has ticked all the boxes with the boss, and they've gone a head and ordered the extortionately priced item, and it's arrived on my desk.

I took one look, and asked "Where's the manual", there isn't one.  Because this is a development kit... Right, what power does it take.. No-one knows, the only way to tell has been to look at the chips and see what the lowest possible power feed should be to the lowest value chip.

Which prong was the negative?... Only could tell that by tracing - by eye - back from an obvious earth plane and a couple of large caps and checking that the line was the negative rail.

This level of just basic documentation, being lacking, immediately makes me worry about the whole bundle.

They're trying to sell this, but I think they're actually trying to get a native English speaker - i.e. me - to write their manual for them.

Next thing, how do I build software to run on this kit?... They don't know... Seriously, this is what the chap has said to me, "It in C, write in C"... okay, what compiler you got?... "We no got compiler"...

So I have to go to the chip vendor and ask for their compiler?... These people throwing this kit together don't have a compiler?  And don't have any recommendation of which compiler to use?....

Luckily I can look at the board and see the processor, so I know what architecture I'm going to target, but I was about to ask "What's the architecture", and I'm pretty sure he'd not know.

How to get the software as built onto the kit, also seems a mystery, there's no obvious portable slot, no ethernet, no USB, no serial... I can't believe I have to burn EEPROM's and plug them in... In this day and age, I've been told "Firmware take your software in, firmware do it"... but not been told how.

I swear, I could pull the last shreds of my hair out with this, not least because I have to appraise this for use by our whole UK arm before this guy jumps on a pre-booked plane ticket from Taiwan over to here.... Gah