Optimerad klocka

Koden till drivningen av IV-18-displayen på min sovrumsklocka är numera optimerad. Den ursprungliga C-koden var snyggt skriven och använde structar och bitfält för att bli tydlig, lättläst och enkel att ändra. Det senare inte minst viktigt, eftersom displayen i labbuppkopplingen är ansluten annorlunda än den i målsystemet.

Problemet med bitfält (och pekare) på en 8-bitars PIC-processor är att det inte passar så bra på en minnesmodell som är tänkt för enkla assemblerprogram, och dessutom är av Harward-arkitektur, vilket innebär att program- och dataminne har helt olika adressrymd. Dettta gör att processorn kan hämta data och operation samtidigt, men passar inte så bra till språket C.

Resultatet av denna mis-match blev att mitt 200-raders C-program (kommentarer och tomma rader medräknade) översattes till över 2000 rader assembler, varav det mesta var kod för att hitta bittarna i minnet. Prestanda blev lite lidande. Displayen uppdaterades ca 500ggr/s, vilket nog är sisådär 5 gånger snabbare än nödvändigt.

Optimering var således av nöden. Jag ville dock inte göra avkall på ändringsbarheten, så kodgenerering var ett bra alternativ.

Mappning mellan bitar och segment och galler, samt hur segmenten ska kombineras till symboler sker i en XML-fil.

<vfd>
<segments>
  <segment nam="a" bit="15">
  <segment nam="b" bit="13">
  ...
  <segment nam="dp" bit="4">
</segment>

<grids>
  <grid nam="g1" bit="17">
  ...
</grid>
<symbols>
  <symbol nam="0">
    <segment nam="a">
    <segment nam="b">
    <segment nam="c">
    <segment nam="d">
    <segment nam="e">
    <segment nam="f">
  </symbol>

</symbols>
   ...
</vfd>

Denna tolkas av ett litet perl-program som genererar en .h-fil med macro-definitioner.

#define GRID_g1_a 0x00
#define GRID_g1_b 0x00
#define GRID_g1_c 0x01
...

#define SEGMENT_a_a 0x00
#define SEGMENT_a_b 0x40
#define SEGMENT_a_c 0x00
...

#define SYMBOL_0_a 0x07
#define SYMBOL_0_b 0x70
#define SYMBOL_0_c 0x00
...

Nu spelar det inte längre så stor roll och macro-definitionerna blir oläsbara, eftersom facit finns i form av XML-filen.

Resultatet då?

Fortfarande 200 rader C översätts till 200 rader assembler. Tiden för att ladda ner programmet i processorn har krympt från knappt 15 s till drygt 4. Alla segment lyser när de ska, liksom alla sifffror.

Uppdateringsfrekvensen har gått från 500Hz till drygt 2000Hz.

Resultatet blev en klar förbätttring på alla punkter. Kostnaden var en lite mer komplicerad byggprocess.