Funktionsobjekt med c-kod


Funktionsobjekts-klassen defineras med ett $ClassDef objekt under 'Class' objektet. Namnge
objektet och aktivera 'Configure-CCodeFo' från popup-menyn för objektet. Nu skapas

- ett RtBody objekt.
- ett DevBody objekt med ett PlcNode objekt som definierar en buffer för grafisk information
i instanserna.
- ett GraphPlcNode objekt som innehåller diverse information om grafik och kodgenerering
för klassen.

Nästa steg är att definiera attribut för klassen. Attributen indelas i ingångar, interna
attribut och utgångar.

Ingångar
Ingångsattributen definierar ingångarna på funktions-objektet, dvs värden som hämtas från
utgångar på andra funktionsobjekt. Ingångarna definieras med $Input objekt som läggs under
RtBody objektet.

I TypeRef anges datatypen för ingången, de datatyper man kan välja är pwrs:Type-$Boolean,
pwrs:Type-$Float32, pwrs:Type-Int32 eller pwrs:Type-String80.

I GraphName anges texten på ingången i funktionsobjektet, normalt brukar man använda 2 - 4
bokstäver. Man brukar använda stora bokstäver för analoga signaler, små för digitala och
stor första bokstav för övriga signaltyper.

Ett ingångsattribut i en instans innehåller både en pekare till den utgång den är kopplad
till, och ett värde som kan datasättas. Det gör att man kan välja om en ingång ska kopplas,
eller datasättas. Det här valet görs med en checkbox (Used), och om man väljer att inte
markera Used, visas inte ingångs pinnen på funktionsobjektet. I Template objektet kan man
sätta defaultvärde på ingången, i det fall ingången inte kopplas.

Interna attribut
Interna attribut är attribut som ej är ut eller ingångar. Det kan vara beräknade värden som
behöver lagras i objektet, eller värden som används för att konfigurera objektet.

Alla vanliga datatyper är tillgängliga för interna attribut.

Utgångar
Utgångsattributen definierar utgångarna på funktions-objektet, dvs värden som lagras i
objeketet, och som därifrån kan hämtas till ingångar på andra funktionsobjekt. Utgångarna
definieras med $Output objekt som läggs under RtBody objektet.

I TypeRef anges datatypen för utgången, liksom för $Input objekt kan Boolean, Float32, Int32
och String80 anges, och i GraphName anges texten vid utgångspinnen i funktionsobjektet.

OBS !
$Input, $Intern och $Output måste ligga i följande ordning under RtBody: $Input först, sedan
$Intern och därefter $Output.

Defaultvärden
Defaultvärden på attribut kan anges i Template objektet.

Om man vill ange vilka in och utgångar som ska visas som default, finns det en mask i
GraphPlcNode objektet, default_mask. default_mask[0] anger ingångar och default_mask[1]
utgångar. Om biten som motsvarar en in eller utgång sätts visas denna som default.


Funktionsobjekt med två ingångar, ett internt attribut, och en utgång


Funktionsobjektet för klassen

Kod
När klassvolymen byggs genereras en h-fil med en c-struct för klassen. Namnet på structen
blir

pwr_sClass_'StructName'

där StructName hämtas från StructName attributet i RtBody. Default är det samma som
klassnamnet, men t ex om klassnamnet innehåller nationella tecken, kan ett annat namn anges.

Här visas ett exempel på structen för klassen MyFo som innehåller två ingångar In1 och In2,
ett internt attribut Factor, och en utgång Out, alla av typen Float32.

typedef struct {
   pwr_tFloat32 *In1P;
   pwr_tFloat32 In1;
   pwr_tFloat32 *In2P;
   pwr_tFloat32 In2;
   pwr_tFloat32 Factor;
   pwr_tFloat32 Out;
} pwr_sClass_MyFo;

Notera att varje ingång består av två element, en pekare med suffixet 'P', och ett element
som kan datasättas om ingången inte kopplas. Om ingången är kopplad kommer pekar-elementet
att peka på den utgång den är kopplad till, annars pekar den på datasättnings-elementet. I
koden ska man därför använda pekar-elementet för att hämta upp värde på ingången.

Koden för klassen ska vara en funktion med följande utseende

void 'StructName'_exec( plc_sThread *tp,
                         pwr_sClass_'StructName' *o) {
}

I koden hämtas data från ingångarna, och beräknade värden läggs ut på utgångarna. Även
interna attribut kan användas för att lagra information till nästa scan, eller för att hämta
upp konfigureringsdata.

I kod exemplet nedan är In1 och In2 ingångar, Factor ett internt attribut och Out en utgång.

   o->Out = o->Factor * (*o->In1P + *o->In2P);

Observera att pekar-elementet för ingångarna In1 och In2 används i koden.

En prototyp-deklaration av exec funktionen läggs in i ra_plc_user.h

void 'StructName'_exec( plc_sThread *tp,
                         pwr_sClass_'StructName' *o);

Modulen för c-koden kompileras och länkas ihop med plc-programmet genom att en länk-fil
skapas på katalogen $pwrp_exe. Filen ska namnges plc_'nodenamn'_'busnr'_'plcname'.opt, t ex
plc_mynode_0999_plc.opt. Innehållet i filen skickas med som indata till länkaren, ld, och man
lägger även in modulerna för plc-koden. I exemplet nedan antas att dessa moduler ligger i
arkivet $pwrp_lib/libpwrp.a.

$pwr_obj/rt_io_user.o -lpwrp -lpwr_rt -lpwr_usbio_dummy -lpwr_usb_dummy -lpwr_pnak_dummy
  -lpwr_cifx_dummy -lpwr_nodave_dummy -lpwr_epl_dummy