Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Titan » J1939 Synchronizing Parallel Test Components of different type(Parallel Test Component Synchronization)
J1939 Synchronizing Parallel Test Components of different type [message #1830322] Thu, 23 July 2020 10:50 Go to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
I have parallel test components of diffent types. In the past there were only parallel test components of the same type, thus when iteraring over the parallel test components only a set of PTCs was used.

Now there are different PTCs , over which I want to iterate. Which these are depends on the test setup. Some test components may represent an Isobus ECU, some an Virtual Terminal and some are just timers, which when active e.g. cyclically send a keep alive message or test for reception of a keep alive message.

type record of PTC PTCSet 


function f_addSyncSlaveSet (in PTC p_slave,
  inout PTCSet p_set) {
  p_set[sizeof(p_set)] := p_slave
  return
}


function f_startPhase (in e_Phase p_phase) runs on MTC {
  var integer v_i
  var integer v_amount := sizeof(v_PTCSet)
  var PhaseStartReq v_phaseStartReq := { phase := p_phase, phase_int := enum2int(p_phase)}

  for (v_i := 0; v_i < v_amount; v_i := v_i +1){
    log("MTC instance: ", self)
    pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i]
  }
}


What I probally need is:

type record of PTCs PTCSet 

type union  PTCs{
    PTC_type1  ptc_type1,
    PTC_type2  ptc_type2,
    PTC_type3  ptc_type3
}


Here the current test cases, with only the "PTC" type components synchronized:

testcase tc_can_j1939_IsobusVtEcuSimulation() runs on MTC {

  // before running this test cases start the j1939 address claim deamons via commandline
  /*
  j1939acd -r 100,80-120 -c /tmp/1122334455667789.jacd 1122334455667789 vcan0
  j1939acd -r 100,80-120 -c /tmp/1122334455667788.jacd 1122334455667788 vcan0
  */

  var PTC v_ptc_J1939VTSocketIF                                 := PTC.create("PTC1_ptc_j1939VTSocketIF") alive
  var PTC v_ptc_J1939ECUSocketIF                                := PTC.create("PTC2_ptc_j1939ECUSocketIF") alive

  f_addSyncSlaveSet(v_ptc_J1939VTSocketIF, v_PTCSet)
  f_addSyncSlaveSet(v_ptc_J1939ECUSocketIF, v_PTCSet)

  connect(mtc:pt_sync, v_ptc_J1939VTSocketIF:pt_sync)
  connect(mtc:pt_sync, v_ptc_J1939ECUSocketIF:pt_sync)

  var PTC_Isobus_VT_CT  v_ptc_J1939VTApplication                      := PTC_Isobus_VT_CT.create("PTC1_ptc_j1939VTApplication") alive
  var PTC_Isobus_VT_VTSTATUSCycle_CT v_ptc_J1939VT_VTStatusCycle      := PTC_Isobus_VT_VTSTATUSCycle_CT.create("PTC_Isobis_VT_VTSTATUSCycle") alive
  var PTC_Isobus_ECU_CT v_ptc_J1939ECUApplication                     := PTC_Isobus_ECU_CT.create("PTC2_ptc_j1939ECUApplication") alive


  connect(v_ptc_J1939VTSocketIF:pt_j1939PDU,                v_ptc_J1939VTApplication:pt_j1939PDU)
  connect(v_ptc_J1939VT_VTStatusCycle:pt_VTStatusTick,           v_ptc_J1939VTApplication:pt_VTStatusTick)
  
  connect(v_ptc_J1939ECUSocketIF:pt_j1939PDU,               v_ptc_J1939ECUApplication:pt_j1939PDU)
  
  
  
  const integer     c_send_prio        := 2
  const J1939_NAME  c_name_VT          := '1122334455667788'O
  const J1939_NAME  c_name_ECU         := '1122334455667789'O  

  v_ptc_J1939VTSocketIF.start(f_ptc_J1939Agent(
      e_testbody1, 
      c_send_prio,
      c_name_VT)) /* name source */

  v_ptc_J1939ECUSocketIF.start(f_ptc_J1939Agent(
      e_testbody1, 
      c_send_prio,
      c_name_ECU ))/* name source */

  v_ptc_J1939VTApplication.start(f_ptc_J1939VTApplication());
  v_ptc_J1939ECUApplication.start(f_ptc_J1939ECUApplication());

  v_ptc_J1939VT_VTStatusCycle.start(f_ptc_J1939VTStatusCycle());

  var e_Phase v_phase

  for(v_phase := c_firstPhase; v_phase < e_testcase_complete;v_phase := f_incMTCPhase(v_phase)) {
    f_startPhase(v_phase)
    log("MTC: ", v_phase)
    f_awaitEndPhase(v_phase)
  }

  all component.done;
  log("MTC done")

  disconnect(v_ptc_J1939VTSocketIF:pt_j1939PDU,                v_ptc_J1939VTApplication:pt_j1939PDU)
  disconnect(v_ptc_J1939ECUSocketIF:pt_j1939PDU,               v_ptc_J1939ECUApplication:pt_j1939PDU)

  all component.kill;      
}


------          --------
|mtc |--------->| PTC  |
|    |          --------
|    |              |
|    |          ----------
|    |--------->| PTC VT |
|    |          ----------
|    |              |
|    |          --------------------
|    |--------->| PTC VT keep alive|
|    |          --------------------
|    |          --------
|    |--------->| PTC  |
|    |          --------
|    |              |
|    |          ----------
|    |--------->| PTC ECU |
|    |          ----------
|    |              |
|    |          -----------
|    |--------->| PTC ... |
|    |          -----------
------


Or is it the case that usually only the first set of PTCs are synchronized by the MTC and the rest is created by the "PTC" components in order to encapsulate the test cases better.
Re: J1939 Synchronizing Parallel Test Components of different type [message #1830361 is a reply to message #1830322] Fri, 24 July 2020 07:23 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

I'll try to reformulate your question, just to make sure I understand it correctly.
So your question, as I understand it, is: "Is it a good practice to have the MTC create/start/synchronize all the other PTCs, or there are advantages of having some of the PTCs create/start /synchronize other PTCs?"

Although technically both scenarios are possible, I prefer the first one, namely having the MTC to play an orchestrator role among the components.

I see at least two advantages of this:
-simplicity ; I don't think I have to argument this extensively: both code and architecture is simpler
-legibility; It's simply easier to read what's going on as the test case executing on MTC offers a clear blueprint of execution ;
If PTCs create other PTCs etc. one has to check details of the functions started on each PTC to create a mental image of the architecture and figure out in which direction the system goes.

On the other hand I see no obvious advantage of the second scenario.


By the way, the mechanism you suggested is the right way of doing synchronization, namely using a simple start/stop protocol; I don't see the definition of f_awaitEndPhase() but I assume components are reporting
termination of execution via the internal synchronization port.

It may look sometimes tempting to use timers instead of synchronization by signals, but that is extremely risky, as it builds in assumptions regarding timing of the execution phases that may or may not be correct and sooner than later will prove wrong.



Best regards
Elemer
Re: J1939 Synchronizing Parallel Test Components of different type [message #1830365 is a reply to message #1830361] Fri, 24 July 2020 08:37 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

thank you for reformulating this.

Before to decide on how to go forward, we have to agree on the way how to orchestrate the PTCs.

I agree with you, it is easier to take the first approach. Thus in the following it is assumed of having the MTC to play an orchestrator role among the parallel test components components.

My problem starts here. The orchestration code, which had been provided by you in the past, can only handle components of one component type. The component type is called "PTC". (see code above)
I need to efficiently handle components of the type "PTC" and of any other component types e.g. "PTC_Isobus_VT_CT", "PTC_Isobus_ECU_CT", etc.

However this is not possible with the current code. As the set of the components "v_PTCSet", which are orchestrated by the MTC is a set of components of the type "PTC"

type record of PTC PTCSet 

and is unable to contain e.g. components of the type "PTC_Isobus_VT_CT".

This means:
- The following is possible:
   var PTC v_ptc_J1939VTSocketIF  := PTC.create("PTC1_ptc_j1939VTSocketIF") alive
   f_addSyncSlaveSet(v_ptc_J1939VTSocketIF, v_PTCSet) 

- however not this:
   var PTC_Isobus_VT_CT  v_ptc_J1939VTApplication := PTC_Isobus_VT_CT.create("PTC1_ptc_j1939VTApplication") alive
   f_addSyncSlaveSet(v_ptc_J1939VTApplication , v_PTCSet) 


What do I have to change in the MTC orchestration code, in order to orchestrate other components than components of the type "PTC" too?


Here should be now the whole MTC orchestration code:
const e_Phase c_firstPhase        := e_open_socket
const e_Phase c_testcase_complete := e_testcase_complete

type record PhaseStartReq {
  e_Phase phase,
  integer phase_int
}
type record PhaseEndInd   {
  e_Phase phase, 
  integer phase_int
}

type port SyncMasterPort message {
  out PhaseStartReq
  in  PhaseEndInd
} with { extension "internal" }

type port SyncSlavePort message {
  in   PhaseStartReq
  out  PhaseEndInd
} with { extension "internal" }

type port J1939PDU_PT message {
  inout   J1939PDU_with_NAME
} with { extension "internal" }

type boolean PoolUploadOngoing

type port PoolUploadOngoingIn message {
  in   PoolUploadOngoing
} with { extension "internal" }

type port PoolUploadOngoingOut message {
  out   PoolUploadOngoing
} with { extension "internal" }

type boolean VTStatusTick

type port VTStatusTickIn message {
  in   VTStatusTick
} with { extension "internal" }

type port VTStatusTickOut message {
  out   VTStatusTick
} with { extension "internal" }

type component PTC_Isobus_VT_VTSTATUSCycle_CT
{
  port VTStatusTickOut                    pt_VTStatusTick
  port PoolUploadOngoingIn                pt_PoolUploadOngoing
  //variables
  //timers
}


type component PTC_Isobus_VT_CT
{
  port J1939PDU_PT                        pt_j1939PDU
  port VTStatusTickIn                     pt_VTStatusTick
  //variables
  //timers
}

type component PTC_Isobus_ECU_CT
{
  port J1939PDU_PT                        pt_j1939PDU
  //variables
  //timers
}


type record of PTC PTCSet 

type component PTC {
  port SyncSlavePort                      pt_sync
  port SocketCAN_PT                       pt_socketCAN
  port J1939PDU_PT                        pt_j1939PDU
  var  e_Phase                            v_phase := c_firstPhase
}

//component declarations
type component MTC{ 
  timer t_guard
  port  SyncMasterPort pt_sync
  var PTCSet         v_PTCSet := {}
}

altstep alt_awaitPhaseStartReq(in e_Phase p_phase) runs on PTC {
  var PhaseStartReq v_PhaseStartReq;
  [] pt_sync.receive (PhaseStartReq: {phase := p_phase, phase_int := ?}){
    log("PTC name: ", self)
    log("Waits for start of phase: ", p_phase)
  }
  // between v_phase and p_phase
  [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int := (enum2int(c_firstPhase) .. enum2int(v_phase))}) -> value v_PhaseStartReq 
  { 
    //v_phase := f_incPhase(v_phase)
    log("PTC name: ", self)
    log("Waits for start of phase: ", p_phase)
    log("Received completion of phase: ", p_phase)
    f_sendPhaseEndInd()
    repeat
  }
  [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int :=?}) -> value v_PhaseStartReq
  {log("Received unexpected message:", v_PhaseStartReq);setverdict(inconc)}
}

function f_startPhase (in e_Phase p_phase) runs on MTC {
  var integer v_i
  var integer v_amount := sizeof(v_PTCSet)
  var PhaseStartReq v_phaseStartReq := { phase := p_phase, phase_int := enum2int(p_phase)}

  for (v_i := 0; v_i < v_amount; v_i := v_i +1){
    log("MTC instance: ", self)
    pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i]
  }
}

function f_incPTCPhase(in e_Phase p_currentPhase) runs on PTC return e_Phase {
  var e_Phase v_nextPhase
  log("PTC: ", self)
  log("PTC instance: ", self)
  log("Current PTC phase: ", p_currentPhase)
  int2enum( enum2int(p_currentPhase)+1, v_nextPhase)
  log("Next PTC phase:", v_nextPhase)
  return v_nextPhase
}

function f_sendPhaseEndInd() runs on PTC{
  // just to allow matching with integer ranges on the reception side, as it is not poosible to do so with enums
  var PhaseEndInd v_PhaseEndInd := {phase := v_phase, phase_int := enum2int(v_phase)}
  pt_sync.send(v_PhaseEndInd)
  log("PTC: PhaseEndInd to MTC with content: ", v_PhaseEndInd, self)
  v_phase := f_incPTCPhase(v_phase)
}

function f_addSyncSlaveSet (in PTC p_slave,
  inout PTCSet p_set) {
  p_set[sizeof(p_set)] := p_slave
  return
}

function f_incMTCPhase(in e_Phase p_currentPhase) runs on MTC return e_Phase {
  var e_Phase v_nextPhase
  log("MTC: ", self)
  log("Current phase: ", p_currentPhase)
  int2enum( enum2int(p_currentPhase)+1, v_nextPhase)
  log("Next phase:", v_nextPhase)
  return v_nextPhase
}

function f_awaitEndPhase(in e_Phase p_phase) runs on MTC {
  var integer v_amount:= sizeof(v_PTCSet);
  var integer v_i
  t_guard.start(c_guard)
  var PhaseEndInd v_PhaseEndInd

  for(v_i := 0; v_i < v_amount; v_i := v_i +1) {
    alt {
      [] pt_sync.receive (PhaseEndInd: {phase :=p_phase, phase_int := ?}){}
      // value between p_phase +1  and e_testcase_complete:
      [] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int :=  (enum2int(p_phase) .. (enum2int(c_testcase_complete)))}){}
      [] t_guard.timeout {
        log("Timeout in MTC phase:", p_phase)
        setverdict(inconc)
      }
      [] pt_sync.receive (?)  -> value v_PhaseEndInd {
        log("Unexpected phase recieved: ", v_PhaseEndInd)
        log("Expected phase range: ", p_phase)
        log(" to ", c_testcase_complete)
        setverdict(inconc)        
      }
      [] any port.receive{
        log("Expected phase:", p_phase)
        setverdict(inconc)
      }
    } 
  }
  t_guard.stop
} 

Re: J1939 Synchronizing Parallel Test Components of different type [message #1830411 is a reply to message #1830365] Sat, 25 July 2020 08:34 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

OK, I think I understand now; but what is the problem with what you have suggested yourself,

namely administering the PTCs in a structure as below:

type record of PTCs PTCSet 

type union  PTCs{
    PTC                             ptc_type1,
    PTC_Isobus_VT_VTSTATUSCycle_CT  ptc_type2,
    PTC_Isobus_VT_CT                ptc_type3,
    PTC_Isobus_ECU_CT             ptc_type4 
	
}



extending the definitions of the new and different PTCs with sync port and phase variable:

//component declarations
type component MTC{ 
  timer t_guard
  port  SyncMasterPort pt_sync
  var PTCSet         v_PTCSet := {}
}

type component PTC {
  port SyncSlavePort                      pt_sync
  port SocketCAN_PT                       pt_socketCAN
  port J1939PDU_PT                        pt_j1939PDU
  var  e_Phase                            v_phase := c_firstPhase
}

//add sync port, phase variable to each PTC component type 

type component PTC_Isobus_VT_VTSTATUSCycle_CT
{
  port SyncSlavePort                      pt_sync
  port VTStatusTickOut                    pt_VTStatusTick
  port PoolUploadOngoingIn                pt_PoolUploadOngoing
  //variables
   var  e_Phase                            v_phase := c_firstPhase
  //timers
}


type component PTC_Isobus_VT_CT
{  
  port SyncSlavePort                      pt_sync 
  port J1939PDU_PT                        pt_j1939PDU
  port VTStatusTickIn                     pt_VTStatusTick
  //variables
   var  e_Phase                            v_phase := c_firstPhase
  //timers
}

type component PTC_Isobus_ECU_CT
{  
  port SyncSlavePort                      pt_sync
  port J1939PDU_PT                        pt_j1939PDU
  //variables
   var  e_Phase                            v_phase := c_firstPhase
  //timers
}





modifying f_addSyncSlaveSet() to refer to the new structure:

function f_addSyncSlaveSet (in PTCs p_slave,
  inout PTCSet p_set) {
  p_set[sizeof(p_set)] := p_slave
  return
}



and then executing everything from the test case running on MTC:

  var PTC v_ptc_J1939VTSocketIF                                 := PTC.create("PTC1_ptc_j1939VTSocketIF") alive
  var PTC v_ptc_J1939ECUSocketIF                                := PTC.create("PTC2_ptc_j1939ECUSocketIF") alive
  var PTC_Isobus_VT_CT  v_ptc_J1939VTApplication                      := PTC_Isobus_VT_CT.create("PTC1_ptc_j1939VTApplication") alive
  var PTC_Isobus_VT_VTSTATUSCycle_CT v_ptc_J1939VT_VTStatusCycle      := PTC_Isobus_VT_VTSTATUSCycle_CT.create("PTC_Isobis_VT_VTSTATUSCycle") alive
  var PTC_Isobus_ECU_CT v_ptc_J1939ECUApplication                     := PTC_Isobus_ECU_CT.create("PTC2_ptc_j1939ECUApplication") alive
  
  
    f_addSyncSlaveSet(v_ptc_J1939VTSocketIF, v_PTCSet)
    f_addSyncSlaveSet(v_ptc_J1939ECUSocketIF, v_PTCSet)
    f_addSyncSlaveSet(v_ptc_J1939VTApplication, v_PTCSet)
    f_addSyncSlaveSet(v_ptc_J1939VT_VTStatusCycle, v_PTCSet)
    f_addSyncSlaveSet(v_ptc_J1939ECUApplication, v_PTCSet)

    connect(mtc:pt_sync, v_ptc_J1939VTSocketIF:pt_sync)
    connect(mtc:pt_sync, v_ptc_J1939ECUSocketIF:pt_sync)	
    connect(mtc:pt_sync, v_ptc_J1939VTApplication:pt_sync)
    connect(mtc:pt_sync, v_ptc_J1939VTApplication:pt_sync)
    connect(mtc:pt_sync, v_ptc_J1939ECUApplication:pt_sync)




Of course each PTC will have to contain the code to manage receiving sync messages and answering them , but this code should be the same as in the old PTCs.

So you can extend the principle over to the new PTCs which are of various and different types.


Besides maybe an unaesthetic duplication of the code of the PTC functions for every possible PTC type, I see no problem with this.

You can save some code and add some structure by creating a base PTC type and define all the other PTC types by extending this base type, something like below:
type component basePTC {
  port SyncSlavePort                      pt_sync
  var  e_Phase                            v_phase := c_firstPhase
}
type component PTC   extends basePTC {
  port SocketCAN_PT                       pt_socketCAN
  port J1939PDU_PT                        pt_j1939PDU
//pt_sync, e_Phase  will be inherited from basePTC
}

:

etc.


This architecture I sketched should work as well as the current one; do you see any problem with it I might have missed?


Best regards

Elemer
Re: J1939 Synchronizing Parallel Test Components of different type [message #1830424 is a reply to message #1830411] Sat, 25 July 2020 19:55 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

that is what I am asking for. Especially I like the base PTC, which is extended to the other PTCs.

altstep alt_awaitPhaseStartReq(in e_Phase p_phase) runs on PTC {
  var PhaseStartReq v_PhaseStartReq;
  [] pt_sync.receive (PhaseStartReq: {phase := p_phase, phase_int := ?}){
    log("PTC name: ", self)
    log("Waits for start of phase: ", p_phase)
  }


One thing I am aware of, is that the "runs on PTC" needs to be generalized to be able to be used with the other PTC types too. Or does it still work, if all PTCs are extensions of the base "PTC" type.

I am afraid of duplicating the code for each PTC type.

Thanks,
Michael

[Updated on: Sat, 25 July 2020 19:56]

Report message to a moderator

Re: J1939 Synchronizing Parallel Test Components of different type [message #1830433 is a reply to message #1830424] Sun, 26 July 2020 06:36 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

at the current status of the standard components behave as primitive objects (as in object-oriented programming).

The standard defines runs on compatibility between components as below:

Runs on compatibility: a function or altstep referring to component type "A" in its runs on clause may be
called or started on a component instance of type 'B' if all the definitions of "A" have identical definitions in "B".


For example:
module Sem_060303_component_types_003 { 

	type port P message {
		inout integer;
	} with {extension "internal"}

	type component GeneralComp {
		port P p;
	}
    
    type component GeneralCompEx {
        port P p;
        port P p2;
    }
    
    function f_test() runs on GeneralComp {
		setverdict(pass);
    }

	testcase TC_Sem_060303_component_types_003() runs on GeneralCompEx {
		f_test(); // GeneralCompEx and GeneralComp are "runs on" compatible
		setverdict(pass);
	}
	
	control{
	    execute(TC_Sem_060303_component_types_003());
	}
}


This means that if you define a component type by extension that covers all your new component types as below:

type component basePTC {
  port SyncSlavePort                      pt_sync
  var  e_Phase                            v_phase := c_firstPhase
}
type component PTC   extends basePTC {
  // port SyncSlavePort                      pt_sync : inherited from basePTC
  port SocketCAN_PT                       pt_socketCAN
  port J1939PDU_PT                        pt_j1939PDU
 //variables
  // var  e_Phase                            v_phase := c_firstPhase  :  inherited from basePTC
  //timers
}


type component PTC_Isobus_CT  extends PTC
{
   // port SyncSlavePort                      pt_sync : inherited from basePTC 
 // port SocketCAN_PT                       pt_socketCAN : inherited from PTC
 // port J1939PDU_PT                        pt_j1939PDU :   inherited from PTC  
  port VTStatusTickOut                    pt_VTStatusTickOut
  port VTStatusTickIn                     pt_VTStatusTickIn
  port PoolUploadOngoingIn                pt_PoolUploadOngoing
  //variables
 // var  e_Phase                            v_phase := c_firstPhase  :  inherited from basePTC
  //timers
}

(please observer that PTC_Isobus_CT covers PTC_Isobus_VT_VTSTATUSCycle_CT, PTC_Isobus_VT_CT, PTC_Isobus_ECU_CT)

then a function, altstep etc. declared to run on PTC_Isobus_CT will also run on PTC:


altstep alt_awaitPhaseStartReq(in e_Phase p_phase) PTC_Isobus_CT {
  var PhaseStartReq v_PhaseStartReq;
  [] pt_sync.receive (PhaseStartReq: {phase := p_phase, phase_int := ?}){
    log("PTC name: ", self)
    log("Waits for start of phase: ", p_phase)
  }
}


Of course when creating components , mapping ports etc. this will have to be taken into consideration:


 
:
var PTC v_ptc_J1939VTSocketIF                                       := PTC.create("PTC1_ptc_j1939VTSocketIF") alive
  var PTC v_ptc_J1939ECUSocketIF                                      := PTC.create("PTC2_ptc_j1939ECUSocketIF") alive
  var PTC_Isobus_VT_CT  v_ptc_J1939VTApplication                      := PTC_Isobus_CT.create("PTC1_ptc_j1939VTApplication") alive
  var PTC_Isobus_VT_VTSTATUSCycle_CT v_ptc_J1939VT_VTStatusCycle      := PTC_Isobus_CT.create("PTC_Isobis_VT_VTSTATUSCycle") alive
  var PTC_Isobus_ECU_CT v_ptc_J1939ECUApplication                     := PTC_Isobus_CT.create("PTC2_ptc_j1939ECUApplication") alive
:


but this way you can avoid duplicating unnecessarily code that is common to
multiple component types.


Best regards
Elemer
Re: J1939 Synchronizing Parallel Test Components of different type [message #1830447 is a reply to message #1830433] Sun, 26 July 2020 14:15 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

I started chnaging the code:

//component declarations

type component SyncPTC {
  port SyncSlavePort                      pt_sync
  var  e_Phase                            v_phase := c_firstPhase
}

type component PTC_Isobus_VT_VTSTATUSCycle_CT extends SyncPTC
{
  port VTStatusTickOut                    pt_VTStatusTick
  port PoolUploadOngoingIn                pt_PoolUploadOngoing
  //variables
  //timers
}


type component PTC_Isobus_VT_CT extends SyncPTC
{
  port J1939PDU_PT                        pt_j1939PDU
  port VTStatusTickIn                     pt_VTStatusTick
  //variables
  //timers
}

type component PTC_Isobus_ECU_CT extends SyncPTC
{
  port J1939PDU_PT                        pt_j1939PDU
  //variables
  //timers
}

type component PTC extends SyncPTC {
  port SocketCAN_PT                       pt_socketCAN
  port J1939PDU_PT                        pt_j1939PDU
}type record of PTCs PTCSet 

type union  PTCs{
    PTC                             ptc_type1,
    PTC_Isobus_VT_VTSTATUSCycle_CT  ptc_type2,
    PTC_Isobus_VT_CT                ptc_type3,
    PTC_Isobus_ECU_CT               ptc_type4 
}


I came up withe the following issues (see comments inside):

function f_startPhase (in e_Phase p_phase) runs on MTC {
  var integer v_i
  var integer v_amount := sizeof(v_PTCSet)
  var PhaseStartReq v_phaseStartReq := { phase := p_phase, phase_int := enum2int(p_phase)}

  for (v_i := 0; v_i < v_amount; v_i := v_i +1){
    log("MTC instance: ", self)
    pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i]  
   // above I get the error:'v_PTCSet[v_i]' Type mismatch: The type of the operand should be a component type 
   //instead of  `@Isobus_test.PTCs'
  }
}


and

  
f_addSyncSlaveSet(v_ptc_J1939VTSocketIF, v_PTCSet)
// above I get the error: 'v_ptc_J1939VTSocketIF' Type mismatch: `@Isobus_test.PTCs' and `@Isobus_test.PTC' are not compatible
f_addSyncSlaveSet(v_ptc_J1939ECUSocketIF, v_PTCSet)
// above I get the error: 'v_ptc_J1939ECUSocketIF' Type mismatch: `@Isobus_test.PTCs' and `@Isobus_test.PTC' are not compatible


where:

function f_addSyncSlaveSet (in PTCs p_slave,
  inout PTCSet p_set) {
  p_set[sizeof(p_set)] := p_slave
  return
}

[Updated on: Sun, 26 July 2020 14:17]

Report message to a moderator

Re: J1939 Synchronizing Parallel Test Components of different type [message #1830449 is a reply to message #1830447] Sun, 26 July 2020 15:31 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

yes, but you have to follow the changes in the structure: now PTCSet is a record of unions (possible choices of component type values), not component variables as before.

So now, when you are initializing the component variables, you have to do something like:

testcase tc_can_j1939_IsobusVtEcuSimulation() runs on MTC { 
:
var PTC v_ptc_J1939VTSocketIF                                 := PTC.create("PTC1_ptc_j1939VTSocketIF") alive
  var PTC v_ptc_J1939ECUSocketIF                                := PTC.create("PTC2_ptc_j1939ECUSocketIF") alive
  var PTC_Isobus_VT_CT  v_ptc_J1939VTApplication                      := PTC_Isobus_VT_CT.create("PTC1_ptc_j1939VTApplication") alive
  var PTC_Isobus_VT_VTSTATUSCycle_CT v_ptc_J1939VT_VTStatusCycle      := PTC_Isobus_VT_VTSTATUSCycle_CT.create("PTC_Isobis_VT_VTSTATUSCycle") alive
  var PTC_Isobus_ECU_CT v_ptc_J1939ECUApplication                     := PTC_Isobus_ECU_CT.create("PTC2_ptc_j1939ECUApplication") alive
  

var PTCs  v_PTCs := {ptc_type1:=v_ptc_J1939VTSocketIF}

f_addSyncSlaveSet(v_PTCs, v_PTCSet);
v_PTCs := {ptc_type1:=v_ptc_J1939ECUSocketIF}
f_addSyncSlaveSet(v_PTCs, v_PTCSet);

:

}



and when extracting the values of the component variables,
something like:
function f_startPhase (in e_Phase p_phase) runs on MTC {
  var integer v_i
  var integer v_amount := sizeof(v_PTCSet)
  var PhaseStartReq v_phaseStartReq := { phase := p_phase, phase_int := enum2int(p_phase)}

  for (v_i := 0; v_i < v_amount; v_i := v_i +1){
    log("MTC instance: ", self)

     if (ischosen(v_PTCSet[v_i].ptc_type1))   { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type1}
else if   (ischosen(v_PTCSet[v_i].ptc_type2)) { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type2}
else if   (ischosen(v_PTCSet[v_i].ptc_type3)) { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type3}
else if   (ischosen(v_PTCSet[v_i].ptc_type4)) { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type4}
else {}//something wrong, this should not happen

  }//endfor
}//endfunction 





Alternatively, select union can be used:

function f_startPhase (in e_Phase p_phase) runs on MTC {
  var integer v_i
  var integer v_amount := sizeof(v_PTCSet)
  var PhaseStartReq v_phaseStartReq := { phase := p_phase, phase_int := enum2int(p_phase)}

  for (v_i := 0; v_i < v_amount; v_i := v_i +1){
    log("MTC instance: ", self)

  select union (v_PTCSet[v_i]) {
case (ptc_type1)   { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type1}
case (ptc_type2)   { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type2}
case (ptc_type3)   { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type3}
case (ptc_type4)   { pt_sync.send(v_phaseStartReq) to v_PTCSet[v_i].ptc_type4}
case else {}//something wrong, this should not happen

} 
  }//endfor
}//endfunction 


I hope this makes sense

Best regards
Elemer

[Updated on: Sun, 26 July 2020 16:03]

Report message to a moderator

Re: J1939 Synchronizing Parallel Test Components of different type [message #1830987 is a reply to message #1830449] Fri, 07 August 2020 21:58 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

I have an MTC and multiple PTCs.

Some test components have only the purpose to exchange keep alive messages in the background as long as the test case is running.

When now the test purpose in the test component is completed (verdict set to pass) the background components have to be stopped. What is the proper way to do this?

You provided some time ago the following code for such background PTC:

function  f_behaviour1_sync()  runs on PTC1_CT
{
//periodic sending
while (condition1)
{
  port1.send(message1);
  T1.start 
  alt
  {
    []pt_sync.receive("halt") { // changed here syncport to pt_sync
      condition1:=false  }
  }
  []T1.timeout;
}
}//endwhile
}//endfunction


Is it the usual procedure, that the component sends a halt_request message to the MTC, which then sends the halt_indication message "halt" to all PTCs via pt_sync?

Where:

function f_awaitEndPhase(in e_Phase p_phase) runs on MTC {
  var integer v_amount:= sizeof(v_PTCSet);
  var integer v_i
  t_guard.start(c_guard)
  var PhaseEndInd v_PhaseEndInd

  for(v_i := 0; v_i < v_amount; v_i := v_i +1) {
    alt {
      [] pt_sync.receive (PhaseEndInd: {phase :=p_phase, phase_int := ?}){}
      // value between p_phase +1  and e_testcase_complete:
      [] pt_sync.receive (PhaseEndInd: {phase :=?, phase_int :=  (enum2int(p_phase) .. (enum2int(c_testcase_complete)))}){}
      [] t_guard.timeout {
        log("Timeout in MTC phase:", p_phase)
        setverdict(inconc)
      }
      [] pt_sync.receive (?)  -> value v_PhaseEndInd {
        log("Unexpected phase recieved: ", v_PhaseEndInd)
        log("Expected phase range: ", p_phase)
        log(" to ", c_testcase_complete)
        setverdict(inconc)        
      }
      [] any port.receive{
        log("Expected phase:", p_phase)
        setverdict(inconc)
      }
    } 
  }
  t_guard.stop
} 


and:
altstep alt_awaitPhaseStartReq(in e_Phase p_phase) runs on PTC {
  var PhaseStartReq v_PhaseStartReq;
  [] pt_sync.receive (PhaseStartReq: {phase := p_phase, phase_int := ?}){
    log("PTC name: ", self)
    log("Waits for start of phase: ", p_phase)
  }
  // between v_phase and p_phase
  [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int := (enum2int(c_firstPhase) .. enum2int(v_phase))}) -> value v_PhaseStartReq 
  { 
    //v_phase := f_incPhase(v_phase)
    log("PTC name: ", self)
    log("Waits for start of phase: ", p_phase)
    log("Received completion of phase: ", p_phase)
    f_sendPhaseEndInd()
    repeat
  }
  [] pt_sync.receive (PhaseStartReq: {phase := ?, phase_int :=?}) -> value v_PhaseStartReq
  {log("Received unexpected message:", v_PhaseStartReq);setverdict(inconc)}
}



and:
const e_Phase c_firstPhase        := e_open_socket
const e_Phase c_testcase_complete := e_testcase_complete

type record PhaseStartReq {
  e_Phase phase,
  integer phase_int
}
type record PhaseEndInd   {
  e_Phase phase, 
  integer phase_int
}

type port SyncMasterPort message {
  out PhaseStartReq
  in  PhaseEndInd
} with { extension "internal" }

type port SyncSlavePort message {
  in   PhaseStartReq
  out  PhaseEndInd
} with { extension "internal" }



Re: J1939 Synchronizing Parallel Test Components of different type [message #1831003 is a reply to message #1830987] Sat, 08 August 2020 17:14 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

the test case is executed on the MTC , so at any moment MTC will know the status of execution of the PTCs, based on the PhasEndInd received from them.

So I don't see the need of a halt_req to be sent to MTC; MTC can take this decision on it's own and can send a halt_req to each PTC at the end of the test case.
At this moment each of the PTCs will have its verdict reached , so this halt request is to terminate gracefully and avoid dynamic test case errors that
can happen when e.g. a component which has connected ports is killed.

So all you need to do on PTCs is to wait for halt at the end of the meaningful part of the function executing on them:


function  f_behaviour1()  runs on PTC1_CT

{
//does something meaningful  here; this is the main behaviour
:
alt
  {
    []pt_sync.receive("halt") { //execution   will hang here until halt is received }
  }

//when halt is received, the function  executing on the PTC  terminates and the component ends

}





I hope this answers your question

Best regards
Elemer
Re: J1939 Synchronizing Parallel Test Components of different type [message #1831005 is a reply to message #1831003] Sat, 08 August 2020 19:48 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

I am not completly sure. The test is handled in 3 step.
- Open socket (phase e_open_socket)
- Running the test case (
- Closing the socket (phase e_close_socket)

I must first send the HaltReg / HaltInd to all components before closing the socket. Thus I have to send the HaltReq and receive the HaltInd before reaching the phase e_close_socket.

Please see attached test case:

J1939_Isobus_test.tc_can_j1939_IsobusVtEcuSimulation2

Here some representative code (Search for HaltReq/HaltInd):

function f_ptc_J1939ECUApplication(in e_Phase p_phase) runs on PTC_Isobus_ECU_CT
{

  var boolean condition := true
  alt_awaitPhaseStartReq(p_phase)

  while (condition)
  {
    var J1939PDU_with_NAME v_pgn_and_pdu_with_name  

    alt 
    {
      [] pt_sync.receive (Command:"HaltInd"){
        log("PTC name: ", self)
        log("Got HaltInd command")
        condition := false
      }
      []pt_j1939PDU.receive(J1939PDU_with_NAME:{addr:= ?, name:=?,
          pdu:=t_VTStatusInd(?, ?, ?, ?, ?)}) -> value v_pgn_and_pdu_with_name 
      { 
        v_peeraddr := v_pgn_and_pdu_with_name.addr
        v_peername := v_pgn_and_pdu_with_name.name
        // store peer name
        //log incoming message 
        log("SocketCan:Expected message VTStatusReq received!", v_pgn_and_pdu_with_name)
        pt_VTStatusTick.send( true );
      }  
      [] pt_WorkingSetMaintenance.receive(t_WorkingSetMaintenanceTick(?)) {
        pt_j1939PDU.send(t_J1939PDU_with_NAME(
            J1939_NO_ADDR, /* set addr 0xFF, applies as name is set */
            v_peername,    /* set peername */
            t_WorkingSetMaintenanceInd(true, compliantWithVTVersion4)

          ))
      }

      []pt_WorkingSetMaintenance.receive(t_WorkingSetMaintenanceInitialize(true)) {
        // the ECU has received the first VTStatus message
        pt_j1939PDU.send(t_J1939PDU_with_NAME(
            J1939_NO_ADDR, /* set addr 0xFF, applies as name is set */
            v_peername,    /* set peername */
            t_GetHardwareReq
          ))    
      }

      []pt_j1939PDU.receive(J1939PDU_with_NAME:{addr:= ?, name:=v_peername,
          pdu:=t_GetHardwareRes(?, ?, ?, ?, ?)}) -> value v_pgn_and_pdu_with_name 
     ....

      []pt_j1939PDU.receive(J1939PDU_with_NAME:{addr:= ?, name:=v_peername,
          pdu:=t_EndOfObjectPoolRes(?, ?, ?,               
            /* objectPoolErrorCodes */   { 
              methodOrAttributeNotSupportedByTheVT   :=?,
              unknownObjectReference                 :=true,
              anyOtherError                          :=?,
              objectPoolWasDeletedFromVolatileMemory :=?,
              reserved4                              :=false,
              reserved5                              :=false,
              reserved6                              :=false,
              reserved7                              :=false
            })}) -> value v_pgn_and_pdu_with_name 
      { 
        log("Expected message EndOfObjectPoolRes received!", v_pgn_and_pdu_with_name)
        pt_sync.send("HaltReq")
        setverdict ( pass );
      }

      [] pt_j1939PDU.receive(J1939PDU_with_NAME:{addr:=?, name:=?,pdu:=?}) -> value v_pgn_and_pdu_with_name
      {
        log("Unexpected message received!", v_pgn_and_pdu_with_name)
      }

      [] pt_j1939PDU.receive  
      {log("Unexpected message received")} //this should catch any incoming message type not matched on the first alternatives

      [] any port.receive   
      {
        setverdict(fail)        
        log("Message received on a different port")} //this should catch any incoming message type not matched on the first alternatives on any other port
    }//endalt
  } // end while
  f_sendPhaseEndInd()
  alt_awaitPhaseStartReq(e_close_socket)
  f_sendPhaseEndInd()
}


function  f_ptc_J1939VTStatusCycleSend(in e_Phase p_phase)  runs on PTC_Isobus_VT_VTSTATUSCycleSend_CT
{
  //periodic sending
  timer VTStatusClock := 1.0
  var  boolean  condition := true
  alt_awaitPhaseStartReq(p_phase)

  while (condition)
  {
    pt_VTStatusTick.send(true);

    VTStatusClock.start 
    alt
    {
      [] pt_sync.receive (Command:"HaltInd"){
        log("PTC name: ", self)
        log("Got HaltInd command")
        condition := false
      }
      []VTStatusClock.timeout;
    }
  }//endwhile
  f_sendPhaseEndInd()
  setverdict(pass)
  alt_awaitPhaseStartReq(e_close_socket)
  f_sendPhaseEndInd()
}//endfunction


and:

function f_ptc_J1939Agent(
  in e_Phase             p_phase,
  in J1939_Priority      p_send_prio,
  in J1939_NAME          p_j1939_name_source) runs on PTCAgent {
  map(self:pt_socketCAN, system:pt_socketCAN)
  var SocketCAN_socketid v_socket_id
  var SocketCAN_ifr v_ifr

  alt_awaitPhaseStartReq(e_open_socket)
  var SocketCAN_open_j1939_result res
  res := f_open_j1939()
  v_socket_id := res.socket_id
  v_ifr := res.ifr
  var SocketCAN_bind_result v_bind_result
  v_bind_result := f_bind(v_socket_id,
    v_ifr.if_index, 
    p_j1939_name_source, 
    J1939_NO_PGN,  /* p_j1939_pgn_source */
    J1939_NO_ADDR  /* p_j1939_addr_source */)
  var SocketCAN_setsockopt_result            v_setsockopt_result
  v_setsockopt_result := f_setsockopt(v_socket_id, {j1939_prio:=p_send_prio})
  const SocketCAN_setsockopt_commandu c_commandu_activate_broadcast := {j1939_broadcast := Enable} 
  // configure broadcast:
  v_setsockopt_result := f_setsockopt(v_socket_id, c_commandu_activate_broadcast)
  f_sendPhaseEndInd()
  alt_awaitPhaseStartReq(p_phase)


  var SocketCAN_receive_j1939_message v_result
  var SocketCAN_j1939_send_data_to_result v_send_data_to_result
  var J1939PDU_with_NAME v_pgn_and_pdu_with_name
  var boolean condition := true
  var boolean v_guard :=true

  timer t_guard

  while (condition)
  {
    alt 
    {
      [] pt_sync.receive (Command:"HaltInd"){
        log("PTC name: ", self)
        log("Got HaltInd command")
        condition := false
      }
      [v_guard] pt_j1939PDU.receive(J1939PDU_with_NAME:{addr:= ?, name:=?,pdu:=?}) 
      -> value v_pgn_and_pdu_with_name 
      { 
        t_guard.start(c_guard)

        var octetstring v_j1939_pdu, v_pgn_and_pdu
        v_pgn_and_pdu := f_encode_J1939_message (v_pgn_and_pdu_with_name.pdu)
        v_j1939_pdu := substr(v_pgn_and_pdu,3,lengthof(v_pgn_and_pdu)-3)// strip PGN

        var J1939_hdr v_j1939_destination := {
          name := v_pgn_and_pdu_with_name.name, 
          pgn := substr(v_pgn_and_pdu,0,3),        // strip PDU,  pgn_destination 
          addr:= v_pgn_and_pdu_with_name.addr
        }


        pt_socketCAN.send(SocketCAN_j1939_send_data_to:{
            id                := v_socket_id,
            if_index          := v_ifr.if_index,
            j1939_destination := v_j1939_destination,
            // strip PGN
            pdu               := v_j1939_pdu});

        v_guard:=false;  //stop receiving until send confirmation received 
      }

      [not(v_guard)] pt_socketCAN.receive(a_SocketCAN_j1939_send_data_to_result(a_result(SocketCAN_SUCCESS))) -> value v_send_data_to_result
      {
        log("Sending j1939_send_data_to:", v_socket_id, ", ", v_ifr.if_index)
        v_guard:=true
        t_guard.stop
      }

      [not(v_guard)] pt_socketCAN.receive(a_SocketCAN_j1939_send_data_to_result(a_result(SocketCAN_ERROR))) 
      {
        log("Sending j1939_send_data_to failed", v_socket_id); 
        v_guard:=true
        t_guard.stop
        setverdict(fail)
      }

      [] pt_socketCAN.receive(a_SocketCAN_receive_j1939_message(
          v_socket_id,
          v_ifr,
          ?, /* any pgn */
          ?, /* any peer_addr */
          ?, /* any peer_name */
          ?  /* any j1939_pdu */)) -> value v_result
      {
        log("SocketCan:J1939 message from socket received", v_result)     
        pt_j1939PDU.send({addr:=v_result.destAddr, name:= v_result.name, 
            // concatenate received pgn and pdu
            pdu:=f_decode_J1939_message(v_result.pgn & v_result.pdu) /* concatenate pgn & pdu */}); 
      }
      [] pt_sync.receive
      {
        log("Fail:Unexpected message from port pt_sync received");
        setverdict(fail)
      }
      [v_guard] pt_socketCAN.receive
      {
        log("Fail:Unexpected message from port pt_socketCAN received")
        //this should catch any incoming message type not matched on the first alternatives
        setverdict(fail)
      }

      [v_guard] pt_j1939PDU.receive
      {
        log("Fail:Unexpected message from port pt_j1939PDU received")
        //this should catch any incoming message type not matched on the first alternatives
        setverdict(fail)
      }

      [v_guard] any port.receive   
      {
        log("Fail:Message received on a different port")
        //this should catch any incoming message type not matched on the first alternatives on any other port
        setverdict(fail)
      } 

      [not(v_guard)] t_guard.timeout {
        log("guard timeout!")
        setverdict(fail)
      }
    }//endalt
  } // end while

  f_sendPhaseEndInd()
  alt_awaitPhaseStartReq(e_close_socket)
  f_close_socket (v_socket_id)
  unmap(self:pt_socketCAN, system:pt_socketCAN)
  setverdict(pass)
  f_sendPhaseEndInd()
}


Also I'd like to know, if the following commands in the above routines are at the right place:

f_sendPhaseEndInd()
....
alt_awaitPhaseStartReq(e_close_socket)
f_sendPhaseEndInd()

Furthermore I'd like to know, of the adapter function f_ptc_J1939Agent(), which opens the socket can be implemedted as a Dual-Faced port?

Br,
Michael
Re: J1939 Synchronizing Parallel Test Components of different type [message #1831039 is a reply to message #1831005] Mon, 10 August 2020 13:20 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

sorry, but I'm confused again:

I don't see why PTCs should receive HaltInd; based on what we discussed, PTCs should receive HaltReq from MTC , and optionally may answer this with HaltInd (I said optionally, but it is indeed recommended to send HaltInd)

so the testcase goes like this:
testcase tc_something   runs on MTC_CT
{

:
:
//send NextPhaseReq  for the last phase  to all PTCs
//receive NextPhaseInd   (all PTCs finished last phase)
//send HaltReq  to all PTCs
//receive HaltInd from all PTCs
all component.done;
//unmap/disconnect test ports

}



So the MTC acts as the orchestrator of the component system.

Do you agree with this?

BR

Elemer


Re: J1939 Synchronizing Parallel Test Components of different type [message #1831045 is a reply to message #1831039] Mon, 10 August 2020 15:24 Go to previous messageGo to next message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

as for your question related to f_ptc_J1939Agent():

this is a component behaviour function with the component having several port types so I'm not sure how to fit the concept of dual ports here:
dual ports have an upper port in layer N+1 and a lower port in layer N-1 and translate between these two, converting from N+1 to N then to N-1 and vice versa.
So I'd say it's not possible.

Best regards
Elemer

Re: J1939 Synchronizing Parallel Test Components of different type [message #1831047 is a reply to message #1831005] Mon, 10 August 2020 15:40 Go to previous messageGo to next message
Michael Josenhans is currently offline Michael JosenhansFriend
Messages: 99
Registered: February 2016
Member
Hi Elemer,

I can not see your answer in the forum, however I received it per e-Mail.

Here it is:
Quote:

Hi Michael,

sorry, but I'm confused again:

I don't see why PTCs should receive HaltInd; based on what we discussed, PTCs should receive HaltReq from MTC , and optionally may answer this with HaltInd (I said optionally, but it is indeed recommended to send HaltInd)

so the testcase goes like this:

testcase tc_something runs on MTC_CT
{

:
:
//send NextPhaseReq for the last phase to all PTCs
//receive NextPhaseInd (all PTCs finished last phase)
//send HaltReq to all PTCs
//receive HaltInd from all PTCs
all component.done;
//unmap/disconnect test ports

}



So the MTC acts as the orchestrator of the component system.

Do you agree with this?

BR

Elemer


Quote:

send HaltReq to all PTCs

Ok. Upon reception of HaltReq from the MTC all PTCs will respond with HaltInd to the MTC and then leave their while loop. The adapter PTC will then close the socket. Finally the adapter PTC and all other PTCs will terminate.

Michael
Re: J1939 Synchronizing Parallel Test Components of different type [message #1831074 is a reply to message #1831047] Tue, 11 August 2020 07:42 Go to previous message
Elemer Lelik is currently offline Elemer LelikFriend
Messages: 1120
Registered: January 2015
Senior Member
Hi Michael,

on second thought I think I need to correct myself.
It should be possible to implement the adaptor PTC with translation port; however I would not recommend it right now.

With a separate component for translation you have more freedom at the expense of an extra component. The translation port
has a strict and set architecture that might be more restrictive and difficult to handle, especially if used for the first time.

So I would start with the adaptor PTC and maybe later convert to translation port and compare the two solutions.


Best regards
Elemer
Previous Topic:External functions using universal charstrings
Next Topic:Unable to walk through C++ Files in Eclipse
Goto Forum:
  


Current Time: Tue Apr 16 22:15:21 GMT 2024

Powered by FUDForum. Page generated in 0.28808 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top