closed

Loginbox

Please enter your username and password into the following fields to log in.


  • Username:
  • Password:
  •  
  • Auto log in on every visit.


  •  

Introducing Skeleton records.



Merlin offline
Administrator
Avatar
Gender: male
Location: UNITED KINGDOM 
Age:
Posts: 1261
Registered: 03 / 2005
Private message
Subject: Introducing Skeleton records.  -  Posted: 20.09.2022 - 10:08   -  
I have been working on a powerful new feature for AVRco that I call skeleton records.

Skeleton records are a significant move towards object orientation.

We classically associate object orientation with classes but they are not the only way to achieve it. At the end of the day object orientation is gathering everything associated with an object in one place, be that data, functions, procedures or whatever. In our case we achieve it with records.

Skeleton records are distinguished from classical records by adding chevrons <> after the word ‘record’. Those chevrons may contain additional information in the form of parameters, but more of that later.

As a tutorial we will illustrate how to use skeleton records by building a driver for ADC for the Mega4808 and 4809 chips specifically, but the design should work for other chips in the same family.

A short extract illustrates some of the features of skeleton records.

Code
type
  tADCPrecision = (adc10Bit, adc8Bit);
  tADCSAMPNUM = (adcNone, adcACC2, adcACC4, adcACC8, adcACC16, adcACC32, adcACC64);
  tADCRefSel = (adcInternal, adcVDD, adcVREFA );
  tADCPrescalar = (adcDIV2, adcDIV4, adcDIV8, adcDIV16, adcDIV32, adcDIV64, adcDIV128, adcDIV256);
  tADCINITDelay = (adcDLY0, adcDLY16, adcDLY32, adcDLY64, adcDLY128, adcDLY256);
  tADCASV = ( adcASVOFF, adcASVOn );
  tADCWINCM = (adcWCNONE, adcWCBELOW, adcWCABOVE, adcWCINSIDE, adcWCOUTSIDE);
  tADCMUXPOS = (adcAIN0, adcAIN1, adcAIN2, adcAIN3, adcAIN4, adcAIN5, adcAIN6, adcAIN7, adcAIN8,
               adcAIN9, adcAIN10, adcAIN11, adcAIN12, adcAIN13, adcAIN14, adcAIN15, adcDACREF0=$1C,
               adsTEMPSENSE=$1E, adcGND=$1F);
  tDUTCYCLE = (adcDC50, adcDC25);

  TUPDI_ADCn_LL = Record<>
  private
    fCTRLA :              byte;
    fCTRLB :              byte;
    fCTRLC :              byte;
    fCTRLD :              byte;
    fCTRLE :              byte;
    fSAMPCTRL :           byte;
    fMUXPOS :             byte;
    fReserved1 :          byte;
    fCOMMAND :            byte;
    fEVCTRL :             byte;
    fINTCTRL :            byte;
    fINTFLAGS :           byte;
    fDBGCTRL :            byte;
    fTEMP :               byte;
    fReserved2 :          word;
    fRES :                word;
    fWINLT :              word;
    fWINHT :              word;
    fCALIB :              byte;
  private
    function GetRUNSTBY : boolean;
    procedure SetRUNSTBY( NewVal : boolean );
    function GetRESSEL : tADCPrecision;
    procedure SetRESSEL( NewVal : tADCPrecision );
    function GetFREERUN : boolean;
    procedure SetFREERUN( NewVal : boolean );
    function GetENABLE : boolean;
    procedure SetENABLE( NewVal : boolean );
    function GetSAMPNUM : tADCSAMPNUM;
    procedure SetSAMPNUM( NewVal : tADCSAMPNUM );
    function GetSAMPCAP : boolean;
    procedure SetSAMPCAP( NewVal : boolean );
    function GetREFSEL : tADCRefSel;
    procedure SetREFSEL( NewVal : tADCRefSel );
    function GetPRESC : tADCPrescalar;
    procedure SetPRESC( NewVal : tADCPrescalar );
    function GetINITDLY : tADCINITDelay;
    procedure SetINITDLY( NewVal : tADCINITDelay );
    function GetASDV : tADCASV;
    procedure SetASDV( NewVal : tADCASV );
    function GetSAMPLDLY : byte;
    procedure SetSAMPLDLY( NewVal : byte );
    function GetWINCM : tADCWINCM;
    procedure SetWINCM( NewVal : tADCWINCM );
    function GetSAMPLEN : byte;
    procedure SetSAMPLEN( NewVal : byte );
    function GetMUXPOS : tADCMUXPOS;
    procedure SetMUXPOS( NewVal : tADCMUXPOS );
    function GetSTCONV : boolean;
    procedure SetSTCONV( NewVal : boolean );
    function GetSTARTEI : boolean;
    procedure SetSTARTEI( NewVal : boolean );
    function GetWCMPEnable : boolean;
    procedure SetWCMPEnable( NewVal : boolean );
    function GetRESRDYEnable : boolean;
    procedure SetRESRDYEnable( NewVal : boolean );
    function GetWCMP : boolean;
    procedure SetWCMP( NewVal : boolean );
    function GetRESRDY : boolean;
    procedure SetRESRDY( NewVal : boolean );
    function GetDBGRUN : boolean;
    procedure SetDBGRUN( NewVal : boolean );

    procedure SetTEMP( NewVal : word );

    procedure SetRES( NewVal : word );

    procedure SetWINLT( NewVal : word );

    procedure SetWINHT( NewVal : word );
    function GetDUTYCYC : tDUTCYCLE;
    procedure SetDUTYCYC( NewVal : tDUTCYCLE );
  public
    property RUNSTBY : boolean
             read GetRUNSTBY
             write SetRUNSTBY;
    property RESSEL : tADCPrecision
             read GetRESSEL
             write SetRESSEL;
    property FREERUN : boolean
             read GetFREERUN
             write SetFREERUN;
    property ENABLE : boolean
             read GetENABLE
             write SetENABLE;
    property SAMPNUM : tADCSAMPNUM
             read GetSAMPNUM
             write SetSAMPNUM;
    property SAMPCAP : boolean
             read GetSAMPCAP
             write SetSAMPCAP;
    property REFSEL : tADCRefSel
             read GetREFSEL
             write SetREFSEL;
    property PRESC : tADCPrescalar
             read GetPRESC
             write SetPRESC;
    property INITDLY : tADCINITDelay
             read GetINITDLY
             write SetINITDLY;
    property ASDV : tADCASV
             read GetASDV
             write SetASDV;
    property SAMPLDLY : byte
             read GetSAMPLDLY
             write SetSAMPLDLY;
    property WINCM : tADCWINCM
             read GetWINCM
             write SetWINCM;
    property SAMPLEN : byte
             read GetSAMPLEN
             write SetSAMPLEN;
    property MUXPOS : tADCMUXPOS
             read GetMUXPOS
             write SetMUXPOS;
    property STCONV : boolean
             read GetSTCONV
             write SetSTCONV;
    property STARTEI : boolean
             read GetSTARTEI
             write SetSTARTEI;
    property WCMPEnable : boolean
             read GetWCMPEnable
             write SetWCMPEnable;
    property RESRDYEnable : boolean
             read GetRESRDYEnable
             write SetRESRDYEnable;
    property WCMP : boolean
             read GetWCMP
             write SetWCMP;
    property RESRDY : boolean
             read GetRESRDY
             write SetRESRDY;
    property DBGRUN : boolean
             read GetDBGRUN
             write SetDBGRUN;
    property TEMP : byte
             read fTEMP
             write fTEMP;
    property RES : word
             read fRES
             write fRES;
    property WINLT : word
             read fWINLT
             write fWINLT;
    property WINHT : word
             read fWINHT
             write fWINHT;
    property DUTYCYC : tDUTCYCLE
             read GetDUTYCYC
             write SetDUTYCYC;
  end;


Udo has been helping me to develop these features.

Anyone else interested in playing with skeleton records and maybe contributing to their development please let me know and I will send them the latest beta.

Regards

Merlin

============================================================

Ich habe an einer mächtigen neuen Funktion für AVRco gearbeitet, die ich Skeleton Records nenne.

Skeleton Records sind ein bedeutender Schritt in Richtung Objektorientierung.

Wir assoziieren Objektorientierung klassischerweise mit Klassen, aber sie sind nicht die einzige Möglichkeit, dies zu erreichen. Letzten Endes bedeutet Objektorientierung, dass alles, was mit einem Objekt verbunden ist, an einem Ort gesammelt wird, seien es Daten, Funktionen, Prozeduren oder was auch immer. In unserem Fall erreichen wir dies mit Datensätzen.

Skeleton-Datensätze unterscheiden sich von klassischen Datensätzen durch das Hinzufügen von Chevrons <> nach dem Wort "Record". Diese Chevrons können zusätzliche Informationen in Form von Parametern enthalten, aber dazu später mehr.

Als Tutorial werden wir die Verwendung von Skeleton-Records anhand eines ADC-Treibers für die Mega4808- und 4809-Chips veranschaulichen, aber das Design sollte auch für andere Chips der gleichen Familie funktionieren.

Wer sonst noch Interesse hat, mit Skeleton Records zu spielen und vielleicht zu ihrer Entwicklung beizutragen, möge sich bitte bei mir melden, und ich werde ihm die neueste Beta-Version schicken.

Mit freundlichen Grüßen

Merlin
Merlin.

:magic:

Software is a black art.
go down go up
miparo offline
Schreiberling
Avatar
Gender: male
Location: GERMANY  Germany
Age: 56
Posts: 914
Registered: 09 / 2007
Private message
Subject: Re: Introducing Skeleton records.  -  Posted: 20.09.2022 - 13:57   -  
Hi Merlin,
Very nice, off to the future :)
Kein Support per PN! | No support via PM!
go down go up
Harry offline
PowerUser
Avatar
Gender: male
Location: GERMANY  zwischen Augsburg und Ulm
Age: 57
Posts: 1993
Registered: 03 / 2003
Private message
Subject: Re: Introducing Skeleton records.  -  Posted: 20.09.2022 - 19:50   -  
Ist bestimmt super, aber objektorientiertes Programmieren ist bisher an mir vorbei gegangen und ich habe noch niemanden gefunden, der mir den Sinn und Zweck sowie die Funktion erklären konnte ..... leider.

Vielleicht könnte man das hier mal angehen?

Gruss
Harry
Elektronik arbeitet mit Rauch - wenn man den Rauch raus läßt, funktioniert es nicht mehr.
Electronics works with smoke - if you let the smoke out, it works no longer.
go down go up
Merlin offline
Administrator
Avatar
Gender: male
Location: UNITED KINGDOM 
Age:
Posts: 1261
Registered: 03 / 2005
Private message
Subject: Re: Introducing Skeleton records.  -  Posted: 20.09.2022 - 20:32   -  
Hi Harry.

I can definitely understand why object orientation has passed you by. There is so much hype and detail that the basic reasons tend to be lost.

The reason for developing object orientation were, quite simply, cost - both in terms of time and money.

The biggest cost was not, in the early day, creating a program but maintaining it. A little tweak here caused a problem elsewhere, and on analysing it, it came down to poor housekeeping. Microcontrollers were, and certainly the Atmel series still is, partitioned into data and program, with the two being considered very separate.

But it makes no real sense to treat then as separate entities. To consider an absurd parallel, imagine you had a function to cut an apple. There was absolutely nothing to stop a programmer to try and use that function to (metaphorically) cut a girder.

Object orientation simply treats data and the functions you use to manipulate that data as a single entity. It makes your code much more organised and reduces the temptation (going back to our absurd example) to modify our cut function to cut a girder and in the process break the operation for cutting an apple.

The next cost is that often two pieces of data are related. You will already be used to putting them together in a record. The problem with that is that uncontrolled modification of data can break the relationship between these pieces of data. Hence public, private and properties to control the access and modification of data.

Of course many more ideas have been added over the years, but that is the basic reasoning.

I hope that helps

Merlin

================================================================================

Hallo Harry.

Ich kann durchaus verstehen, warum die Objektorientierung an Ihnen vorbeigegangen ist. Es gibt so viel Hype und Details, dass die grundlegenden Gründe oft verloren gehen.

Der Grund für die Entwicklung der Objektorientierung waren ganz einfach die Kosten - sowohl in Bezug auf Zeit als auch auf Geld.

Die größten Kosten verursachte in der Anfangszeit nicht die Erstellung eines Programms, sondern dessen Wartung. Eine kleine Änderung hier verursachte ein Problem an anderer Stelle, und bei der Analyse stellte sich heraus, dass es sich um schlechte Haushaltsführung handelte. Mikrocontroller waren, und die Atmel-Serie ist es sicherlich noch, in Daten und Programm unterteilt, wobei die beiden als sehr getrennt betrachtet wurden.

Es macht aber keinen wirklichen Sinn, sie als getrennte Einheiten zu behandeln. Um eine absurde Parallele zu ziehen: Stellen Sie sich vor, Sie hätten eine Funktion zum Schneiden eines Apfels. Nichts würde einen Programmierer davon abhalten, diese Funktion zu verwenden, um (metaphorisch) einen Träger zu schneiden.

Bei der Objektorientierung werden Daten und die Funktionen, die Sie zur Bearbeitung dieser Daten verwenden, einfach als eine Einheit behandelt. Das macht Ihren Code viel übersichtlicher und verringert die Versuchung (um auf unser absurdes Beispiel zurückzukommen), unsere Schneidefunktion zu ändern, um einen Träger zu schneiden und dabei die Operation zum Schneiden eines Apfels zu zerstören.

Der nächste Nachteil ist, dass oft zwei Daten miteinander verbunden sind. Sie werden bereits daran gewöhnt sein, sie in einem Datensatz zusammenzufassen. Das Problem dabei ist, dass eine unkontrollierte Änderung von Daten die Beziehung zwischen diesen Daten zerstören kann. Daher gibt es öffentliche, private und Eigenschaften, um den Zugriff und die Änderung von Daten zu kontrollieren.

Natürlich sind im Laufe der Jahre noch viele weitere Ideen hinzugekommen, aber das ist die Grundüberlegung.

Ich hoffe, das hilft

Merlin
Merlin.

:magic:

Software is a black art.
go down go up
Avra hidden
Schreiberling
Avatar
Gender: male
Location: SERBIA  Belgrade, Serbia
Age: 51
Posts: 653
Registered: 07 / 2002
Homepage Private message
Subject: Re: Introducing Skeleton records.  -  Posted: 26.09.2022 - 12:36   -  
Very nice cooking ;-)
go down go up
 


Registered users in this topic
Currently no registered users in this section

Delete cookies of this forum  •  FAQ / Help  •  Team page  •  Imprint   |  Local time: 02.10.2022 - 06:19