Commit 6867b35d authored by Claes Sjofors's avatar Claes Sjofors

Profinet, Added functionality for acyclic write to a device

parent 37612708
......@@ -30,3 +30,4 @@
110429 cs profibus Profibus gsd Bit and BitArea syntax fix for space between Bit and (
110531 cs profinet Recall buffer added to profinet configurator.
110531 cs profinet Script functions GetIoDeviceData and SetIoDeviceData to modify profinet configuration added.
110909 rk profinet Added functionality for acyclic write to a device
\ No newline at end of file
......@@ -220,6 +220,7 @@ static pwr_tStatus IoAgentInit (
pn_subslot_data = new PnSubmoduleData;
pn_subslot_data->subslot_number = dev_data->slot_data[jj]->subslot_data[kk]->subslot_number;
pn_subslot_data->ident_number = dev_data->slot_data[jj]->subslot_data[kk]->submodule_ident_number;
pn_subslot_data->api = dev_data->slot_data[jj]->subslot_data[kk]->api;
if (dev_data->slot_data[jj]->subslot_data[kk]->io_input_length > 0) {
pn_subslot_data->io_in_data_length = dev_data->slot_data[jj]->subslot_data[kk]->io_input_length;
pn_subslot_data->type = PROFINET_IO_SUBMODULE_TYPE_INPUT ;
......@@ -261,7 +262,7 @@ static pwr_tStatus IoAgentInit (
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
sts = wait_service_con(local, ap);
if (sts == PNAK_OK) {
/* Loop through devices and calculate offset for io */
......@@ -324,7 +325,7 @@ static pwr_tStatus IoAgentInit (
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
sts = wait_service_con(local, ap);
}
/* Set mode online */
......@@ -393,7 +394,7 @@ static pwr_tStatus IoAgentInit (
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
sts = wait_service_con(local, ap);
}
}
......@@ -484,6 +485,8 @@ static pwr_tStatus IoAgentWrite (
unsigned char *io_datap;
unsigned char *clean_io_datap;
PnSubmoduleData *submodule;
io_sRack *slave_list;
pwr_sClass_PnDevice *sp;
unsigned short data_length, ii, jj, kk, ll;
unsigned char *status_datap;
......@@ -492,6 +495,9 @@ static pwr_tStatus IoAgentWrite (
/* Write i/o for all devices fetch it first from clean io data area */
/* Iterate over the slaves. */
slave_list = ap->racklist;
for (ii = 1; ii < local->device_data.size(); ii++) {
if (local->device_data[ii]->device_state == PNAK_DEVICE_STATE_CONNECTED) {
......@@ -520,6 +526,36 @@ static pwr_tStatus IoAgentWrite (
sts = pnak_set_iocr_data(0, pn_iocr_data->identifier, pn_iocr_data->io_data, pn_iocr_data->io_data_length);
}
}
if (slave_list != NULL) {
sp = (pwr_sClass_PnDevice *) slave_list->op;
slave_list = slave_list->next;
/* Check if there is a write request pending ?? */
if (sp->WriteReq.SendReq) {
if ((sp->WriteReq.Length > 0) && (sp->WriteReq.Length <= sizeof(sp->WriteReq.Data))) {
for (jj = 0; jj < local->device_data[ii]->module_data.size(); jj++) {
if (local->device_data[ii]->module_data[jj]->slot_number == sp->WriteReq.SlotNumber) {
for (kk = 0; kk < local->device_data[ii]->module_data[jj]->submodule_data.size(); kk++) {
if (local->device_data[ii]->module_data[jj]->submodule_data[kk]->subslot_number == sp->WriteReq.SubslotNumber) {
if (local->device_data[ii]->module_data[jj]->submodule_data[kk]->api > 0) {
sp->WriteReq.Api = local->device_data[ii]->module_data[jj]->submodule_data[kk]->api;
}
pack_write_req(&local->service_req_res, local->device_data[ii]->device_ref, &sp->WriteReq);
sts = pnak_send_service_req_res(0, &local->service_req_res);
break;
}
}
break;
}
}
}
sp->WriteReq.SendReq = 0;
}
}
}
}
......
......@@ -74,7 +74,7 @@ class PnIOCRData {
class PnSubmoduleData {
public:
PnSubmoduleData() : subslot_number(0), subslot_idx(0), type(0), state(0), ident_number(0), phys_ident_number(0) {}
PnSubmoduleData() : subslot_number(0), subslot_idx(0), type(0), state(0), ident_number(0), phys_ident_number(0), api(0) {}
unsigned short subslot_number;
unsigned short subslot_idx;
......@@ -82,6 +82,7 @@ class PnSubmoduleData {
unsigned short state;
unsigned int ident_number;
unsigned int phys_ident_number;
unsigned int api;
unsigned short io_in_data_length; // bytes of pure io-data
unsigned short offset_io_in; // offset in io-data area for this iocr
......
......@@ -242,6 +242,54 @@ void pack_get_device_state_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned s
}
void pack_write_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short device_ref, pwr_sClass_PnWriteReq *wr_req)
{
unsigned offset = 0u;
T_PNAK_SERVICE_DESCRIPTION *service_desc;
T_PN_SERVICE_WRITE_REQ *pWR;
unsigned char *pData;
memset(ServiceReqRes, 0, sizeof(T_PNAK_SERVICE_REQ_RES));
ServiceReqRes->NumberEntries = 1;
ServiceReqRes->ServiceEntry[0].ServiceOffset = 0;
service_desc = (T_PNAK_SERVICE_DESCRIPTION *) &ServiceReqRes->ServiceChannel[offset];
service_desc->DeviceRef = device_ref;
service_desc->Instance = PN_CONTROLLER;
service_desc->Service = PN_SERVICE_WRITE;
service_desc->Primitive = PNAK_SERVICE_REQ;
service_desc->ClientId = 0;
service_desc->InvokeId = 0;
/* Calculate length of service */
service_desc->DataLength = sizeof(T_PN_SERVICE_GET_DEVICE_STATE_REQ) + wr_req->Length;
pWR = (T_PN_SERVICE_WRITE_REQ *) service_desc + 1;
pWR->VersionHighByte = 1;
pWR->VersionLowByte = 0;
pWR->APIHighWordHighByte = _PN_U32_HIGH_HIGH_BYTE(wr_req->Api);
pWR->APIHighWordLowByte = _PN_U32_HIGH_LOW_BYTE(wr_req->Api);
pWR->APILowWordHighByte = _PN_U32_LOW_HIGH_BYTE(wr_req->Api);
pWR->APILowWordLowByte = _PN_U32_LOW_LOW_BYTE(wr_req->Api);
pWR->SlotNumberHighByte = _PN_U16_HIGH_BYTE(wr_req->SlotNumber);
pWR->SlotNumberLowByte = _PN_U16_LOW_BYTE(wr_req->SlotNumber);
pWR->SubSlotNumberHighByte = _PN_U16_HIGH_BYTE(wr_req->SubslotNumber);
pWR->SubSlotNumberLowByte = _PN_U16_LOW_BYTE(wr_req->SubslotNumber);
pWR->IndexHighByte = _PN_U16_HIGH_BYTE(wr_req->Index);
pWR->IndexLowByte = _PN_U16_LOW_BYTE(wr_req->Index);
pWR->LengthHighByte = _PN_U16_HIGH_BYTE(wr_req->Length);
pWR->LengthLowByte = _PN_U16_LOW_BYTE(wr_req->Length);
pData = (unsigned char *) pWR + 1;
memcpy(pData, wr_req->Data, wr_req->Length);
}
void pack_get_los_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes)
{
unsigned offset = 0u;
......@@ -724,11 +772,6 @@ void pack_download_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, GsdmlDeviceData *d
memcpy(pData, dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data, dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length);
pData += dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length;
/* if (((dev_data->slot_data[ii]->subslot_data[jj]->data_record[kk]->data_length % 2) > 0) &&
(kk != dev_data->slot_data[ii]->subslot_data[jj]->data_record.size() - 1)) {
length++;
pData++;
} */
pDataRecord = (T_PN_DATA_RECORD *) pData;
}
}
......@@ -737,7 +780,7 @@ void pack_download_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, GsdmlDeviceData *d
service_desc->DataLength = length;
if (device_ref != 0) {
/* if (device_ref != 0) {
pData = (char *) (pSDR);
printf("Download of device: %s\n", dev_data->device_name);
......@@ -748,7 +791,7 @@ void pack_download_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, GsdmlDeviceData *d
}
printf("\n");
printf("\n");
}
}*/
}
int unpack_get_los_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local)
......@@ -833,6 +876,34 @@ int unpack_get_los_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local)
return -1;
}
int unpack_write_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local)
{
if (pSdb->Result == PNAK_RESULT_POS) {
return PNAK_OK;
}
else if (pSdb->Result == PNAK_RESULT_NEG) {
T_PN_SERVICE_ERROR_CON* pErrorCon = (T_PN_SERVICE_ERROR_CON*) (pSdb + 1);
printf(
"channel %d: write.con [-] (%d)\r\n"
" code : %d (0x%02x)\r\n"
" detail : %d (0x%02x)\r\n"
" add. detail: %d (0x%02x)\r\n"
" area : %d (0x%02x)\r\n",
0,
pSdb->DeviceRef,
pErrorCon->Code, pErrorCon->Code,
pErrorCon->Detail, pErrorCon->Detail,
pErrorCon->AdditionalDetail, pErrorCon->AdditionalDetail,
pErrorCon->AreaCode, pErrorCon->AreaCode
);
}
return -1;
}
int unpack_get_alarm_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local, io_sAgent *ap)
{
......@@ -1309,16 +1380,9 @@ int unpack_download_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local)
int handle_service_con(io_sAgentLocal *local, io_sAgent *ap)
{
T_PNAK_WAIT_OBJECT wait_object;
int sts;
unsigned short ii;
wait_object = PNAK_WAIT_OBJECT_SERVICE_CON;
sts = pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (sts == PNAK_OK) {
memset(&local->service_con, 0, sizeof(T_PNAK_SERVICE_CON));
sts = pnak_get_service_con(0, &local->service_con);
......@@ -1338,8 +1402,12 @@ int handle_service_con(io_sAgentLocal *local, io_sAgent *ap)
}
case PN_SERVICE_SET_IDENTIFICATION:
case PN_SERVICE_READ :
case PN_SERVICE_READ : {
break;
}
case PN_SERVICE_WRITE : {
sts = unpack_write_con(pSdb, local);
break;
}
......@@ -1407,11 +1475,26 @@ int handle_service_con(io_sAgentLocal *local, io_sAgent *ap)
}
}
}
}
return sts;
}
int wait_service_con(io_sAgentLocal *local, io_sAgent *ap)
{
T_PNAK_WAIT_OBJECT wait_object;
int sts;
wait_object = PNAK_WAIT_OBJECT_SERVICE_CON;
sts = pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
}
return sts;
}
void handle_exception (io_sAgentLocal *local) {
return;
......@@ -1459,7 +1542,7 @@ void handle_device_state_changed (io_sAgentLocal *local, io_sAgent *ap) {
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
sts = wait_service_con(local, ap);
}
}
}
......@@ -1491,14 +1574,14 @@ void handle_alarm_indication (io_sAgentLocal *local, io_sAgent *ap) {
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
sts = wait_service_con(local, ap);
if (sts == PNAK_OK) {
pack_alarm_ack_req(&local->service_req_res, local->device_data[ii]->alarm_ref, local->device_data[ii]->alarm_data.alarm_prio, local->device_data[ii]->device_ref);
sts = pnak_send_service_req_res(0, &local->service_req_res);
if (sts == PNAK_OK) {
sts = handle_service_con(local, ap);
sts = wait_service_con(local, ap);
}
}
}
......@@ -1526,7 +1609,7 @@ void *handle_events(void *ptr) {
/* Do forever ... */
while (1) {
wait_object = PNAK_WAIT_OBJECTS_EVENT_IND | PNAK_WAIT_OBJECTS_OTHER;
wait_object = PNAK_WAIT_OBJECTS_EVENT_IND | PNAK_WAIT_OBJECTS_OTHER | PNAK_WAIT_OBJECT_SERVICE_CON;
sts = pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (sts == PNAK_OK) {
......@@ -1564,6 +1647,11 @@ void *handle_events(void *ptr) {
// What to do if interrupted ???;
}
if (wait_object & PNAK_WAIT_OBJECT_SERVICE_CON) {
// printf("Service con !!");
sts = handle_service_con(local, ap);
}
}
else if ( (sts == PNAK_ERR_FATAL_ERROR ) ||
(sts == PNAK_EXCEPTION_THROWN) ) {
......
......@@ -63,6 +63,8 @@ void pack_set_identification_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes);
void pack_get_device_state_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short device_ref);
void pack_write_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short device_ref, pwr_sClass_PnWriteReq *wr_req);
void pack_get_los_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes);
void pack_get_alarm_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short ref);
......@@ -71,6 +73,8 @@ void pack_alarm_ack_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, unsigned short re
void pack_download_req(T_PNAK_SERVICE_REQ_RES *ServiceReqRes, GsdmlDeviceData *dev_data, unsigned short device_ref);
int unpack_write_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local);
int unpack_get_los_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local);
int unpack_get_alarm_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local, io_sAgent *ap);
......@@ -80,6 +84,8 @@ int unpack_download_con(T_PNAK_SERVICE_DESCRIPTION* pSdb, io_sAgentLocal *local)
int handle_service_con(io_sAgentLocal *local, io_sAgent *ap);
int wait_service_con(io_sAgentLocal *local, io_sAgent *ap);
void handle_exception (io_sAgentLocal *local);
void handle_state_changed (io_sAgentLocal *local);
......
Volume Profibus $ClassVolume 0.0.250.7
Body SysBody 05-SEP-2005 17:51:40.00
Attr NextOix = "_X209"
Attr NextCix = "_X19"
Attr NextCix = "_X20"
Attr NextTix[0] = "_X12"
EndBody
Object Type $TypeHier 55 16-JAN-2006 10:07:43.21
......@@ -2803,6 +2803,97 @@ Volume Profibus $ClassVolume 0.0.250.7
EndObject
EndObject
!/**
! Sends an acyclic write request to a device
! for a certain slot and subslot.
!*/
Object PnWriteReq $ClassDef 19 07-SEP-2011 08:49:46.86
Body SysBody 07-SEP-2011 08:49:30.59
Attr Editor = 0
Attr Method = 0
Attr Flags = 16
EndBody
Object RtBody $ObjBodyDef 1 07-SEP-2011 08:49:53.46
Body SysBody 07-SEP-2011 08:49:53.46
Attr StructName = "PnWriteReq"
Attr NextAix = "_X8"
EndBody
!/**
! Application Process Identifier, usually 0 but can be
! defined to other by a device profile.
!*/
Object Api $Attribute 1 07-SEP-2011 08:50:09.27
Body SysBody 07-SEP-2011 08:50:29.19
Attr PgmName = "Api"
Attr TypeRef = "pwrs:Type-$UInt32"
EndBody
EndObject
!/**
! Number of slot to write to.
!*/
Object SlotNumber $Attribute 2 07-SEP-2011 08:50:58.89
Body SysBody 07-SEP-2011 08:50:58.89
Attr PgmName = "SlotNumber"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Number of subslot to write to.
!*/
Object SubslotNumber $Attribute 3 07-SEP-2011 08:50:58.89
Body SysBody 07-SEP-2011 08:50:58.89
Attr PgmName = "SubslotNumber"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Unique ID of record data object to write to.
!*/
Object Index $Attribute 4 07-SEP-2011 08:51:20.46
Body SysBody 07-SEP-2011 08:51:21.42
Attr PgmName = "Index"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! Bytes of data to write.
!*/
Object Length $Attribute 5 07-SEP-2011 08:55:25.16
Body SysBody 07-SEP-2011 08:55:25.53
Attr PgmName = "Length"
Attr Flags = 1024
Attr TypeRef = "pwrs:Type-$UInt16"
EndBody
EndObject
!/**
! The data to write.
!*/
Object Data $Attribute 6 07-SEP-2011 08:56:03.58
Body SysBody 07-SEP-2011 08:56:48.30
Attr PgmName = "Data"
Attr Flags = 1026
Attr Elements = 256
Attr TypeRef = "pwrs:Type-$UInt8"
EndBody
EndObject
!/**
! Send the write request.
!*/
Object SendReq $Attribute 7 07-SEP-2011 09:13:01.58
Body SysBody 07-SEP-2011 09:13:16.75
Attr PgmName = "SendReq"
Attr TypeRef = "pwrs:Type-$Boolean"
EndBody
EndObject
EndObject
Object Template PnWriteReq 2152693760 01-JAN-1970 01:00:00.00
Body RtBody 01-JAN-1970 01:00:00.00
EndBody
EndObject
EndObject
!/**
! @Author Robert Karlsson
! @Version 1.0
! @Group IO
......@@ -2929,7 +3020,7 @@ Volume Profibus $ClassVolume 0.0.250.7
Object RtBody $ObjBodyDef 1 21-APR-2009 13:41:08.17
Body SysBody 21-APR-2009 13:41:08.17
Attr StructName = "PnDevice"
Attr NextAix = "_X105"
Attr NextAix = "_X106"
EndBody
!/**
! Description.
......@@ -3107,6 +3198,16 @@ Volume Profibus $ClassVolume 0.0.250.7
Attr TypeRef = "Profibus:Class-PnAlarm"
EndBody
EndObject
!/**
! Request to write data to a subslot
!*/
Object WriteReq $Attribute 105 07-SEP-2011 10:24:03.67
Body SysBody 07-SEP-2011 10:24:13.69
Attr PgmName = "WriteReq"
Attr Flags = 16908288
Attr TypeRef = "Profibus:Class-PnWriteReq"
EndBody
EndObject
EndObject
Object ConfiguratorPosnn $Menu 122 21-APR-2009 13:41:08.17
Object Pointed $Menu 123 21-APR-2009 13:41:08.17
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment