# Datenhandling - Zugriff von vielen FCs & FBs auf die gleichen Daten



## logo78 (31 August 2010)

Hi,
versucht euch mal folgendes Scenario vorzustellen, wie würdet ihr das vereinfachen/verbessern?!

Wir haben hier ein Altprojekt, welches ich als Referenz für ein Musterprojekt nehmen soll.
Es handelt sich um eine Anlage mit dutzenden und identischen Anlagenkomponenten (sagen wir mal Fahrzeuge dazu), deren Daten in je einem DB abgelegt sind (ca. 1Kbyte mit Status, Fehler, Aufträge, Fahrroute, Fahrziele, etc...)

Es gibt zudem dutzende FCs und FBs mit Teilfunktionen (Strategien, Auswertungen, Arithmetik, Schnittstellen/Kommunikation, etc..) die sequentiell
aufgerufen werden.
Je nach Eingangsparameter (FC:IN FahrzeugNr as INT), wird folgendermaßen gearbeitet.

```
L     #Fahrzeug_Nr //Das ist der Eingansparameter
      +     100 //Die FahrzeugDBs liegen im Bereich 101-199
      T     #FZG_DB
      AUF   DB [#FZG_DB]
 
L DBX....
L DBW....
...
..
```
Um das Ganze etwas übersichtlicher zu gestalten, hat sich ein ehemaliger Kollege die Mühe gemacht, TeilStrukturen der Fahrzeug-DBs im temporären Stack der jeweiligen FCs nachzubilden, damit er:

```
//Rangieren der Nutzdaten in den temp. Stack
// Ziel_Soll
      L     DBD  300                 
      T     LD    20                    
// Ziel_Routing
      L     DBD  304                    
      T     LD    24 
 
...Hier kommt das eigentliche Programm...
 
//ZurückRangieren des temp. Stack in das entsprechende DB
// Ziel_Soll
  L     LD    20                    
  T     DBD  300                 
// Ziel_Routing
  L     LD    24 
  T     DBD  304
```
wenigstens mit sinnvollen Bezeichnungen der temporären Variablen arbeiten kann, anstatt mit DBX, DBW, DBB und DBD.

Allerdings, über den Querverweis findet man nichts, erst recht nicht, wenn man Doppelwortweise über den Temp.Datenstack hin-und herrangiert hat.

Mit einer symbolischen Adressierung kann man es leider in diesem Fall vergessen.
Ich habe lange überlegt und nachgeforscht, ob es eine Alternativmethode existiert, mit dem man diese Aufgabenstellung meistern und sich die Flexibilität beibehalten kann. Ich kenne nur zwei, welche mir aber auch nicht so richtig gefallen.

-Den Umweg über ein Schmier-DB. Sprich, am Anfang des jeweiligen Funktion ein Blockmove von NutzDB auf SchmierDB. Dann wird im Programm symbolisch mit den Adressen des SchmierDBs gearbeitet, um dann am Schluss wieder ein Blockmov von SchmierDB auf NutzDB zu machen.
Vorteil: Querverweis funktioniert, übersichtlicher
Nachteil: Zykluszeit und not very fashion 


Die UC/CC Methode, bei der die untergeordneten FBs immer die Instansdaten des übergeordneten FBs mitbenutzen.
FB_Fahrzeug1
UC FB_FunktionA
UC FB_FunktionB

FB_Fahrzeug2
UC FB_FunktionA
UC FB_FunktionB

Vorteil: Gibt es einen?
Nachteil: Querverweis funktioniert genausowenig
Habt ihr ideen?


----------



## Paule (31 August 2010)

logo78 schrieb:


> -Den Umweg über ein Schmier-DB. Sprich, am Anfang des jeweiligen Funktion ein Blockmove von NutzDB auf SchmierDB. Dann wird im Programm symbolisch mit den Adressen des SchmierDBs gearbeitet, um dann am Schluss wieder ein Blockmov von SchmierDB auf NutzDB zu machen.
> 
> 
> Vorteil: Querverweis funktioniert, übersichtlicher
> Nachteil: Zykluszeit und not very fashion


Also ich würde auch diese Variante empfehlen.
Das kopieren auf die Lokaldaten finde ich nicht so gut.

Und von wegen Zykluszeit, jetzt kopierst du ja auch alle Daten einzeln auf den Stack, der Blockmove macht ja auch nichts anderes.


----------



## Aventinus (31 August 2010)

Du könntest die Strukturen umstellen.
Stell dir Deine Datenhaltung als Tabelle vor. Jetzt hast du als Spalten die DB´s (für jedes Fahrzeug einen) und die einzelnene Daten hast du in den Zeilen.
Wenn du das ganze umdrehst hast du einen DB mit Fahrzeugnummern, einen mit Routen, einen mit Aufträgen usw.

Das ganze deklarierst du als Array. Je nach dem was du brauchst, Fahrzeugnummer als Int, Aufträge als UDT - was weiß ich.
Über den Index kannst du die passenden Daten wieder zusammenführen.


----------



## Jochen Kühner (31 August 2010)

*UDT als IN Parameter*

Kannst auch einen UDT oder Struct als In Paremter machen, und von ausen die Daten an diese Anlegen, aber das dauert zumindest auf einer 315 weitaus länger als ein Blockmove.

Also Ich definiere eigendlich meist einen Pointer als IN, lege die Daten von ausen darauf, und kopier mirs in meinem FC in Lokaldaten. In den Lokaldaten verwende Ich dann denn gleichen UDT wie im DB!


----------



## logo78 (1 September 2010)

@Aventinus,
ich verstehe was du meinst, das könnte man machen, wenn die Menge der FahrzeugDaten überschaubar wären und wenn man von vornerein wüsste, dass jede Funktion nur einen bestimmten 'Range' bräuchte.
Aber wir haben hier DBs mit je 1kbyte! an Daten mit allen möglichen DatenTypen, u.U. das Ganze dutzende Male (viele Fahrzeuge) und jede Funktion muss auf das gesamte Datenspektrum des jeweiligen Fahrzeugs zugreifen können.
Das kann leider so nicht funktionieren.

@Jochen,
aus dem o.G. Grund fällt die Möglichkeit mit Eingangsparametern aus.
Das wäre wohl bei jeder Funktion ein UDT mit 1Kbyte  
Ein ziemlicher Overhead.

Außerdem muss ich ja Werte lesen und auch beschreiben können, somit müsste die hässlichen In/Out benutzen, welches aber auch nicht geht, 
da beim sequentiellen abarbeiten/durchreichen der Daten, jeder FC die nicht benutzten Datenbereiche 'nullt', da ja Siemens intern auch 'nur' den Lokalstack(in/out) auf den Datenbereich rangiert.


----------

