Pipe Verhalten

  • 1
  • 2
  • Page 1 of 2
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1340
Registered: 02 / 2009
Subject:

Pipe Verhalten

 · 
Posted: 24.04.2018 - 20:01  ·  #1
Hallo Leute,

ich teste gerade mal die Idee von rolf mit der Pipe um die LOGS auf die SD-Karte zu schreiben.
Blöderweise startet der Controller immer neu nachdem ich erfolgreich in die Pipe geschrieben habe.

Hier mein Aufbau:

Code
var
// Meldungssystem
   LogPipe : Pipe[255] of byte; // PIPE of byte für LOGBUCH


Code
// Log in Pipe  speichern
procedure LogString(const InStrLog: string[24]);
var
 xLog : byte;
 strLog : string[45];
begin
strLog:= RTCZeitBlock.strLog+InStrLog+#CR+#LF;
  for xLog:= 1 to Length( strLog ) do
   PipeSend( LogPipe, byte(strLog[xLog]) );  // wenn ich diese Zeile entferne stürzt die CPU nicht ab.
  endfor;
end LogString;


In einen anderen Process wird dann regelmäßig diese Funktion gestartet, aber bis dahin komme ich mit dem Debugger erst gar nicht. Sobald er die Schleife mit dem Schreiben in die Pipe beendet hat startet die CPU neu (nein, der Watchdog ist das nicht :-) )

Im Debugger sieht man die Daten korrekt in der Pipe stehen (siehe Anhang). Sobald er aus der Schleife geht, kommt der Neustart. Aber nur wenn ich Daten in die Pipe schreibe.

Code
// Log speichern Pipe
procedure Save_LogPipe;
var
 dosTime, dosDate : word;
 xFor, xstrNo, strNo : byte;
 strLog: string[45];
begin
xstrNo:= PipeStat( LogPipe );  // wenn Daten in Pipe, Anzahl ziehen
 if xstrNo > 0 then  // größer 0 dann aktiv werden
 
    // erzeuge Datum und Zeit für Datei
    dosTime := F16_StrToTime( RTCZeitBlock.strzeit);
     dosDate := F16_StrToDate( RTCZeitBlock.strdatum );

    // Dateiname erzeugen
     //  Beispiel JahrMonatTag.log  = 20180422.log
    Datei_Name := '20'+ByteToHex(RTCZeitBlock.jahr)+ByteToHex(RTCZeitBlock.monat)+ByteToHex(RTCZeitBlock.tag)+'.log';
     LogDir := '';

      F16_FileAssign(Log_Datei, LogDir, Datei_Name);// Handle mit FileNamen verknüpfen
      if F16_FileExist(LogDir, Datei_Name,faAnyFile) then
        F16_FileAppend(Log_Datei);               // vorhandene Datei öffnen
      else // Datei vorhanden
        //Datei erzeugen 
         F16_FileCreate(LogDir, Datei_Name, [faArchive], DosTime, DosDate,0);
      endif; // File Exist
       // Schreibe Log-Zeile

       for xFor := 1 to xstrNo do
        Write( SerOutD0, char(PipeRecv( LogPipe )) );
       endfor;
       
      if not F16_FileClose(Log_Datei) then                         // File schließen

      endif; 

      if not F16_FileSetDate(LogDir, Datei_Name, DosTime, DosDate) then // Setzen Time Date der Datei
      endif; 
      if not F16_FileSetAttr(LogDir, Datei_Name, [faArchive]) then 
      endif; 
      
 endif; //  xstrNo Keine Daten in der PIPE
end Save_LogPipe; 


Da ich bis jetzt noch nie mit so einer Pipe gearbeitet habe, könnte es ja auch ein Fehler von mir sein. Hat Jemand eine Idee?

Thorsten
You must be logged in or your permissions are to low to see this Attachment(s).
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Pipe Verhalten

 · 
Posted: 25.04.2018 - 10:31  ·  #2
Hallo Thorsten,

ich habe versucht diesen Aufbau verkürzt nachzubilden und konnte
keine Fehler feststellen. Möglicherweise ein Frame Überlauf wegen
den strings??
Wie immer:
ein kleines Testprogramm wo der Fehler nachvollzogen werden kann
wäre sehr hilfreich. Ohne FAT etc....

rolf
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1340
Registered: 02 / 2009
Subject:

Re: Pipe Verhalten

 · 
Posted: 25.04.2018 - 10:42  ·  #3
Quote by rh

Hallo Thorsten,

ich habe versucht diesen Aufbau verkürzt nachzubilden und konnte
keine Fehler feststellen. Möglicherweise ein Frame Überlauf wegen
den strings??
Wie immer:
ein kleines Testprogramm wo der Fehler nachvollzogen werden kann
wäre sehr hilfreich. Ohne FAT etc....

rolf

Hallo rolf,

lt. Debugger ist noch genug frei im FRAME der TASKs / Prozesse.
Ich bin aber schon dabei ein gekürztes Testprogramm zu erstellen.

Also mache ich erstmal nichts grundsätzlich falsches :-D
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1340
Registered: 02 / 2009
Subject:

Re: Pipe Verhalten

 · 
Posted: 25.04.2018 - 12:51  ·  #4
Hallo rolf,

ich verstehe es nicht, im Testprogramm funktioniert alles wie es soll!

Test0: Normaler LOOP aufruf ok
Test1: Im Task Pipe leeren, OK
Test2: Im Process leeren, OK

Also muss sich das irgendwo mit einen der Treiber im kompletten Projekt beissen. :-(

Hast Du eine Idee wie ich es eingrenzen kann?

Hier mein TestCode:
Code
program XMEGA_Test;

{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = xmega256A3U, VCC = 3.3;
//Device = xmega128A1U, VCC = 3.3;

Define_Fuses
  Override_Fuses;
  NoteBook               = D;
  COMport                = USB;
  LockBits0              = [];
  FuseBits0              = [];
  FuseBits1              = [ WDPER0, WDPER3 ];   // Watchdog   0:3 / 0110 512CLK 0.512s

// 0=WDPER0
// 1=WDPER1
// 2=WDPER2
// 3=WDPER3

  FuseBits2              = [];                         // mandatory !!
  // Brown-out is obligatory with USB !!!
//  FuseBits5              = [BODACT0, BodLevel0, BodLevel1, BodLevel2];
  FuseBits5              = [BodLevel0,BodLevel2, BodAct0]; //  2.6V:

  ProgFlash = true; // or false – program Flash
  ProgEEprom= FALSE; // or false – program EEprom
  AutoRelease    = true; // or false – Release Target    // Wichtig für Programmierung über UPP !!

Import SysTick, SerPortD0 ;

//From System Import Processes, Tasks,longword, longint, SystemTime16, StackChecks, Pipes;  // for DNS
From System Import Processes, Tasks, Pipes;

Define
  // XMega USB must use the internal 32MHz OSC. So the system must use the 2MHz OSC
OSCtype                = int2MHz, PLLmul = 16, prescB = 1, prescC = 1;        // 32MHz
//  OSCtype                = int2MHz, PLLmul = 20, prescB = 1, prescC = 1, overdrive; // 40 MHz
//  OSCtype                = int2MHz, PLLmul = 24, prescB = 1, prescC = 1, overdrive; // 48 MHz


  SysTick                = 10;                 // msec
  StackSize              = $0512, iData;
  FrameSize              = $0512, iData;
// SerPort D1
  SerPortD0              = 57600, Databit8,parNone, Stop1; {9600 Baud, 1Stopbit}
  RxBufferD0             = 128, iData;
  TxBufferD0             = 128, iData;
  SerCtrlD0              = PortB, 0, negative; {control line for RS485 driver}
// Task / Process
  Scheduler              = iData;
  TaskStack              = 256, iData;
  TaskFrame              = 256;

Implementation

{$IDATA}

{--------------------------------------------------------------}
{ Type Declarations }

 {--------------------------------------------------------------}
{ Const Declarations }
  // definitions for bitmap types
CONST
// CR LF
 // TimerTypen
  CR : byte = 13; // $0D
  LF : byte = 10; // $0A

{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
  SerTimer      : SysTimer;
  WDITimer      : SysTimer;
  bTast0, bTast1: boolean;

// Meldungssystem
   LogPipe : Pipe[255] of byte; // PIPE of byte für LOGBUCH

// Input  Onboard
   HxIN_SOFTRESET    [@PINE, 3 ] : bit;
   HxIN_RUNSTOP      [@PINR, 0 ] : bit;
   HxIN_SERVTAST     [@PINR, 1 ] : bit;

i : integer;
y : byte;
x : byte;

{--------------------------------------------------------------}
{ functions }
procedure DebugOut( OutStr : String[59] );
begin
  Writeln(SerOutD0,OutStr);
end; //Ende Debug Out





{--------------------------------------------------------------}
procedure InitPorts;
begin
// INIT Werte IOs

//Reset Input Taste
  PIN3CTRLE := %01011000; // pullup und INVERT
  DDRE.3:= 0;  // 0=EINGANG  1=Ausgang
//Run Stop Schalter
  PIN0CTRLR := %01011000; // pullup und INVERT
  DDRR.0:= 0;  // 0=EINGANG  1=Ausgang
//ServTaste
  PIN1CTRLR := %01011000; // pullup und INVERT
  DDRR.1:= 0;  // 0=EINGANG  1=Ausgang
//IN ZBV0
  PIN6CTRLF := %01011000; // pullup und INVERT
  DDRF.6:= 0;  // 0=EINGANG  1=Ausgang
//IN 3
  PIN1CTRLF := %01011000; // pullup und INVERT
  DDRF.1:= 0;  // 0=EINGANG  1=Ausgang
//IN 11
  PIN4CTRLF := %01011000; // pullup und INVERT
  DDRF.4:= 0;  // 0=EINGANG  1=Ausgang
//IN 12
  PIN7CTRLF := %01011000; // pullup und INVERT
  DDRF.7:= 0;  // 0=EINGANG  1=Ausgang
//IN 13
  PIN5CTRLF := %01011000; // pullup und INVERT
  DDRF.5:= 0;  // 0=EINGANG  1=Ausgang
//IN 14
  PIN3CTRLF := %01011000; // pullup und INVERT
  DDRF.3:= 0;  // 0=EINGANG  1=Ausgang
//IN 15
  PIN2CTRLF := %01011000; // pullup und INVERT
  DDRF.2:= 0;  // 0=EINGANG  1=Ausgang

//OUT_K17
  //PIN0CTRLF := %00000000; // pullup und INVERT
  DDRF.0:= 1;  // 0=EINGANG  1=Ausgang

end InitPorts;

//---------------------------------------------------------------
// Log in Pipe  speichern
procedure LogString(const InStrLog: string[24]);
var
 xLog : byte;
 strLog : string[45];
begin
DebugOut('Pipe: ' + ByteToHex( PipeStat(LogPipe)));
strLog:= '20180424;121220;'+InStrLog+#CR+#LF;
  for xLog:= 1 to Length( strLog ) do
   PipeSend( LogPipe, byte(strLog[xLog]) );
  endfor;
DebugOut('Pipe: ' + ByteToHex( PipeStat(LogPipe)));
end LogString;


//---------------------------------------------------------------
// Log speichern Pipe
procedure Save_LogPipe;
var
 xFor, xstrNo : byte;
begin

// überprüfe Pipe
xstrNo:= PipeStat( LogPipe );
 if xstrNo > 0 then

     for xFor := 1 to xstrNo do
       Write( SerOutD0, char(PipeRecv( LogPipe )) );
      endfor;

 endif; //  xstrNo
end Save_LogPipe;

Task Test0(iData, resumed);
begin
 //Save_LogPipe; // Test 0 Pipe Auswerten

end;

//--------------------------------------------------------------
Process Test1 (128, 128 : iData;5 ); {Stacksize = 128 bytes, Framesize = 128 bytes}
begin
 Save_LogPipe; // Test 1 Pipe Auswerten

   Schedule; // Rechenzeit freigeben
End Test1;


{--------------------------------------------------------------}
{ Main Program }
{$IDATA}

begin
y:=0;
x:=0;

InitPorts;
 EnableInts($87);


SetSysTimer( WDITimer, 100);
 SetSysTimer( SerTimer, 200);
 DebugOut( 'System gestartet....');
  loop

//Save_LogPipe; // Test 2 Pipe Auswerten

if IsSysTimerZero( SerTimer ) then
SetSysTimer( SerTimer, 200);
endif;

// Taste 0
//
   if (HxIN_SERVTAST AND not bTast0)then
    DebugOut('ServTast: ;');
     bTast0:= true; // Flankenhilfsmerker
      LogString('ServTast');

   endif;
   if (not HxIN_SERVTAST AND bTast0)then
     bTast0:= false;
   endif;

// Taste 1
//
   if (HxIN_SOFTRESET AND not bTast1)then
    DebugOut('SoftReset: ;');
      bTast1:= true; // Flankenhilfsmerker
       LogString('SoftReset');

     //  HxDispData:=FALSE;
   endif;
   if (not HxIN_SOFTRESET AND bTast1)then
     bTast1:= false;  // Flankenhilfsmerker
   endif;





  endloop;

end XMEGA_Test.


Wie und wo kann ich eigentlich die FRAME für den MAIN_PROC einstellen? Im Handbuch steht nur was drinnen "..über den Compiler-Schalter vor dem Main..", aber wie heisst dieser Compiler-Schalter. Ich würde die Idee von Dir gerne mal testen und den Frame erhöhen, lt. Info habe ich noch 88 frei. Aber einfach mal zum testen.

Oder ist damit das vom DEFINE gemeint?
Code
  StackSize              = $0128, iData;
  FrameSize              = $0128, iData;

Thorsten
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Pipe Verhalten

 · 
Posted: 25.04.2018 - 13:25  ·  #5
Hallo Thorsten
das mit dem $noshadow ist nicht ganz ungefährlich.
Mit dem define stack und frame ist immer das Main gemeint.

rolf
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1340
Registered: 02 / 2009
Subject:

Re: Pipe Verhalten

 · 
Posted: 25.04.2018 - 14:09  ·  #6
Quote by rh

Hallo Thorsten
das mit dem $noshadow ist nicht ganz ungefährlich.
Mit dem define stack und frame ist immer das Main gemeint.

rolf


Hallo rolf,

das mit dem $noshadow habe ich irgendwann mal wegen einem anderen Problem reingenommen.
Ist von damals noch drinnen, hatte mich bis jetzt auch nicht gestört, da im Handbuch steht:
Code
{$NOSHADOW}
Die Definition muss, falls benötigt, noch vor der Device Deklaration erfolgen. 
Bei non Multitask Anwendungen werden bei allen Interrupts nur die durch die 
Interrupts benutzten Register gesichert. Dies spart wesentlich Ram, Rom und 
Rechenzeit. Dieser Schalter wird durch den Import von Prozesse und Tasks 
überschrieben.


Somit ist es doch eigentlich egal ob es im Code steht oder nicht, da ich die Tasks / Prozesse nutze. Oder?

Beim erneuten Test eben mit dem größeren Frame im Main und dem Debugger, poppte ganz kurz beim beenden des Debuggers eine Meldung auf "Frame Overflow beim LCD Display". Also habe ich hier mal zum Test das ganze erhöht. Und siehe da, das war es. Aber lt. Anzeige waren da noch über 160 frei.

Da ich am Ende des "LCD Displays" kurz prüfe ob Daten in der Pipe stehen, kann es sein das dann die 256Bytes aus der Pipe dort auf den Frame kommen? Wenn ja, könnte dies das Problem gewesen sein. Wenn das so ist, würde ich gerne wissen warum? Der Speicher der Pipe ist ja schon im GLOBAL vorhanden und reserviert.

Thorsten
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 24
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: Pipe Verhalten

 · 
Posted: 25.04.2018 - 14:19  ·  #7
Hallo Thorsten,

das mit dem $noshadow trifft so zu.
Ich bin mir nur nicht ganz im klaren ob da "private" Interrupts
nicht doch betroffen sind. Bin sehr oft auch selbst nur ein dämlicher User...

Mit PipeStat wird nur die Füllung (payload) der Pipe geprüft aber nichts
gelesen bzw. geleert. Stack und Frame werden nur bei User Operationen
geprüft, aber nicht innerhalb von Treibern.

rolf
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2080
Registered: 03 / 2003
Subject:

Re: Pipe Verhalten

 · 
Posted: 25.04.2018 - 15:58  ·  #8
Hallo Thorsten,

wie kommt man eigentlich auf $0128 Frame & Stack? Das sind 296 Byte ;)

Gruss
Harry
  • 1
  • 2
  • Page 1 of 2
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   140   154 · Page-Gen-Time: 0.032419s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI