industrialNETworXnetx

kajienk

kajienk

| 12.09.2008 | 12:23 | 5 replies

Acyclic communication with PROFINET stack via DPM

Hello,

I have cifX 50-RE card running under Linux with PROFINET IO device firmware (using cifxpns.nxm from CD included to card).
Basic initialization and cyclic data are OK, but I don't know how to use asynchronous comuunication properly.

I have found documentation for PROFINET IO device API, but I expect it to be communication between rcX and stack. Is it possible to communicate with the stack the same way via DPM (mailbox) from PC?

I tried filling diagnostic alarm packet according to "PROFINET IO RT Device Protocol API.pdf" (struct PNS_IF_SEND_DIAG_ALARM_REQ_T, page 170) and sending it to netX via xChannelPutPacket();. Source code follows

//========== acyclic (alarm) ======================================
    PNS_IF_PACKET_SEND_DIAG_ALARM_REQ_T send_alarm;
  //header
  send_alarm.tHead.ulDest = 0x02;
  send_alarm.tHead.ulSrc = 0;
  send_alarm.tHead.ulDestId = 0;
  send_alarm.tHead.ulSrcId = 0;
  send_alarm.tHead.ulLen = PNS_IF_SEND_DIAG_ALARM_REQ + send_alarm.tData.usAlarmDataLen;
  send_alarm.tHead.ulId = 20;
  send_alarm.tHead.ulSta = 0;
  send_alarm.tHead.ulCmd = PNS_IF_SEND_DIAG_ALARM_REQ;	//predelat na fci jako parametr
  send_alarm.tHead.ulExt = 0;
  send_alarm.tHead.ulRout = 0;
  //data
  send_alarm.tData.hDeviceHndl = 0;	//?
  send_alarm.tData.ulApi = 0;
  send_alarm.tData.ulSlot = 1;
  send_alarm.tData.ulSubslot = 1;
  send_alarm.tData.hAlarmHandle = 0xBACE;
  send_alarm.tData.ulAlarmState = 1;	//1 appear 2 disappear
  send_alarm.tData.usStructIdent = 0x01;
  send_alarm.tData.usAlarmDataLen = 2;
  OS_Memset(send_alarm.tData.abAlarmData, 0, send_alarm.tData.usAlarmDataLen);

ret = xChannelPutPacket(p_channel, &send_alarm, PACKET_TIMEOUT);
if(CIFX_NO_ERROR != ret){
OS_Memset(buffer,0, sizeof(buffer));
xDriverGetErrorDescription(ret, buffer, sizeof(buffer));
printf("alarm state = 0x%08X (%s)\n", ret, buffer);
}



I am not sure about the content of the struckture, I just tried to send any alarm. But while compilation, following warning appears:

warning: passing argument of 'xChannelPutPacket' from incompatible pointer type.

When program runs, it returns error: 0x800C001A (I found it should be: "Mailbox too short").

The question is: is this idea all right or completely wrong?

Next I would like to ask whether is it possible to use similiar approach when using other commands from PNS_IF Tasks, such as PNS_IF_CFG_PLUG_MODULE_REQ.
And is there some standart calling sequence I have to use before calling PLUG_MODULE_REQ?

Thank you for answer

P.S. I hope I put the question into correct section of forum

Benjamin Meyer

Benjamin Meyer

Hilscher Gesellschaft fuer Systemautomation mbH

| 12.09.2008 | 13:49

hello

Yes, to use acyclic services like alarms you have to interact with the stack. In your case you should use the DPM and the mailbox-service.

In general what you do looks good.

instead of
send_alarm.tHead.ulLen = PNS_IF_SEND_DIAG_ALARM_REQ + send_alarm.tData.usAlarmDataLen;
please try
send_alarm.tHead.ulLen = PNS_IF_SEND_DIAG_ALARM_REQ_SIZE + send_alarm.tData.usAlarmDataLen;

Your deviceHandle is wrong, too.
send_alarm.tData.hDeviceHndl = 0; //?

you have to read out the device handle before you can use any other service.
to read this handle please use the service "PNS_IF_GET_DEVICE_HANDLE_REQ/CNF – Getting a Device Handle" which is described in "PROFINET IO RT Device Protocol API.pdf".

I am not sure if
send_alarm.tHead.ulDest = 0x02;
is okay. I would expect (but am not sure)
send_alarm.tHead.ulDest = 0x20;

The approch of sending requests to the firmware using mailbox and DPM is correct. This should work with any othe request contained in "PROFINET IO RT Device Protocol API.pdf".
Note: Requests like PNS_IF_CFG_PLUG_MODULE_REQ are only allowed on startup. If you want to change the module configuration afterwards please use PNS_IF_PLUG_MODULE_REQ instead.

kajienk

kajienk

| 12.09.2008 | 16:21

Thank you for answer, now it works !!

I have some more questions.

Is there a way how to find out, which slots (and subslots) are plugged (something more elegant than querring slots one by one with PNS_IF_PLUG and checking answer status)?
Or which modules are plugged during initialization by warmstart.dat file?
(Considering usage of precompiled firmware and for example IO data length 2 (2B input, 2B output). In HW config of PROFINET IO controller, there are just one 2B input and 2B output expected.)

Next I don't understand the meaning of variable ulId. It is used in structure TLR_PACKET_HEADER. Its description suggests, that it is optional. Is it correct, that this value doesn't matter?
(Considering structures used in PNS_IF*..).

best regards

Benjamin Meyer

Benjamin Meyer

Hilscher Gesellschaft fuer Systemautomation mbH

| 12.09.2008 | 17:24

if you use the warmstart message to configure the stack then the stack will automatically configure its modules to those the IO-Controller expects.
This means that the module configuration which is sent to the stack by the IO-Controller on connection establishment is stored and used to configure the stack.
This also means that the until a connect request from IO-Controller is received there is no module plugged in the stack!

As far as i know using this configuration method (warmstart message) you can not simply read out this configuration.

If you do not use a warmstart message and instead fully configure the stack on your own (Set_Device_Info, Open_Device, Add_Api, Plug_Module etc.) you exactly know which modules are plugged. In this case the stack will not configure itself to the needs of the IO-Controller.

Regarding the field ulId i think you can simly ignore it when using the Profinet IO-Device stack. But here i am not sure.

kajienk

kajienk

| 16.01.2009 | 10:57

Hello,

I have one more question concerning acyclic communication

I have acyclic communication running without problem, thanks to this forum thread. However only in polling mode, when I enable interrupts, acyclic messages do not work. I use following code (example when getting device handle)

  //fill packet header
  fill_header( &(p_handle_req.tHead), 0x20, 0, PNS_IF_GET_DEVICE_HANDLE_REQ );
  //send packet to mailbox
  ret = xChannelPutPacket(p_channel, (CIFX_PACKET*)&p_handle_req, PACKET_TIMEOUT);
  if( ret==CIFX_NO_ERROR ){
    //wait for reply
    ret = xChannelGetPacket(p_channel, sizeof(PNS_IF_PACKET_GET_DEVICE_HANDLE_CNF_T), 
    			    (CIFX_PACKET*)&p_handle_cnf, PACKET_TIMEOUT);
    if( ret==CIFX_NO_ERROR && p_handle_cnf.tHead.ulCmd==PNS_IF_GET_DEVICE_HANDLE_RES ){
      return p_handle_cnf.tData.hDeviceHndl;
    }
  }

My problem is, that no reply arrives. xChannelGetPacket() returns 0x800C0019 (mailbox empty). Without IRQ this function works without any problem.
So my question is, is there some difference in acyclic communication between polling mode and IRQ?

All sample codes I found on CD attached to board or on Your web pages, were written for C-toolkit without IRQ. So I don't know what to do.

Thank You for answer

M T

M T

Hilscher Gesellschaft für Systemautomation mbH

| 30.01.2009 | 15:45

You wrote that you are using the stack from Linux?

So I assume you have ported the Toolkit to Linux. You will need to write an Interrupt handler that calls cifXTKitISRHandler and cifXTKitDSRHandler (in interruptible context) to make sure the toolkit gets the IRQs. As it is OS independent it cannot handle Interrupts by itself, it will always need a user to provide the layer between Physical IRQ, OS and Toolkit.

PS: The Examples have nothing to do with the interrupt, as the interrupts are hidden behind der cifX driver API (respectively inside the toolkit). The application calling the cifX driver API does not care about IRQ or polling mode.

Regards

MT

Login