I am working toward a PROFIBUS Master running under QNX 6.4.1. The hardware is an x86 PC with CIFX 50-PB PCI card including a master licence. Therefor I'm porting the cifX Toolkit to QNX (version 1.0.1.0). I have implemented all of the OS_* and USER_* functions. My application so far is the ToolkitSample.cpp. DMA and Interrupts are not enabled, too.
I am now able to reset the PCI card, loading the firmware and a SyCon generated configuration. The system channel is working but no communication channel. The initialisation is very similar to a working Win32 version of the ToolkitSample.cpp.
Another thread in this forum has mentioned the OS_GetMilliSecCounter function. My implementation seems reasonable to me.
I have no more ideas on how to get the communication channel working. What can I do to get it working?
I am appending the output from my ToolkitSample.cpp. I have enabled all of the Toolkit messages and added some more to my OS_* functions.
TiA
Christian
Basisadresse: 0xfd5f0000, MEM: 0xfd5f0000, Länge: 65536 Bytes.
PCI Klasse: 0xff, Vendor ID: 0x15cf, PCI Index: 0x0, IRQ: 0xb/11.
PCI MEM Bereich 0 - Basisadresse: 0xfd5f0000, Länge: 65536 Bytes.
+ DPM eingerichtet. (Vendor-ID: 0x15cf, PCI Index: 0x0). Erste Bytes: 0x42 4f 4f 54 ("BOOT").
Device Type autodetection: RAM Based Device found!
New RAM based device found, device will be reset!
cifXHardwareReset
OS_ReadPCIConfig.
- PCI-Konfigurationswert BAR0: 0xfd5f0000 (Offset: 0x10).
- PCI-Konfigurationswert BAR1: 0x00000000 (Offset: 0x14).
- PCI-Konfigurationswert BAR2: 0x00000000 (Offset: 0x18).
- PCI-Konfigurationswert Lat./../../IRQ: 0x0000010b (Offset: 0x3c).
- PCI-Konfigurationswert Command/Status: 0x02000006 (Offset: 0x4).
OS_WritePCIConfig.
- PCI-Konfigurationswert BAR0 geschrieben: 0xfd5f0000 (Offset: 0x10).
- PCI-Konfigurationswert BAR1 geschrieben: 0x00000000 (Offset: 0x14).
- PCI-Konfigurationswert BAR2 geschrieben: 0x00000000 (Offset: 0x18).
- PCI-Konfigurationswert Lat./../../IRQ geschrieben: 0x0000010b (Offset: 0x3c).
- PCI-Konfigurationswert Command/Status geschrieben: 0x02000006 (Offset: 0x4).
cifXHardwareReset - done successfully.
Downloading bootloader '/usr/local/hilscher/NETX100-BSL.bin'
Bootloader was downloaded and started successfully!
Firmware download, checking / starting: CHANNEL #0, 1 file(s)
Successfully downloaded the firmware to device '/usr/local/hilscher/cifxdpm.nxf'!
Firmware download, checking / starting: CHANNEL #1, 0 file(s)
Firmware download, checking / starting: CHANNEL #2, 0 file(s)
Firmware download, checking / starting: CHANNEL #3, 0 file(s)
Firmware download, checking / starting: CHANNEL #4, 0 file(s)
Firmware download, checking / starting: CHANNEL #5, 0 file(s)
Configuration download, checking / starting: CHANNEL#0, 1 file(s)!
No MD5 Information available. Probably the file does not exist on device. (ulState = 0xc02b002f)
Successfully downloaded the configuration to device '/etc/xi/hilio/aufbaucl.nxd'!
Configuration download, checking / starting: CHANNEL#1, 0 file(s)!
Configuration download, checking / starting: CHANNEL#2, 0 file(s)!
Configuration download, checking / starting: CHANNEL#3, 0 file(s)!
Configuration download, checking / starting: CHANNEL#4, 0 file(s)!
Configuration download, checking / starting: CHANNEL#5, 0 file(s)!
System channel is READY!
Reading Channel Info on Channel#0 (DPM Start Offset=0x00000300 Length=0x00001D00)
-------------------------------------------------------------------------
-------------------------------------------------------------------------
NO CHANNEL INFORMATION FOUND, No devices created!
---------- Board/Channel enumeration demo ----------
Found Board cifX0
DeviceNumber : 1250410
SerialNumber : 20216
Board ID : 0
System Error : 0x00000000
Channels : 0
DPM Size : 65536
Interrupt : disabled
State = 0x00000000
----------------------------------------------------
---------- System Device handling demo ----------
System Channel Info Block:
DPM Size : 8192
Device Number : 1250410
Serial Number : 20216
Manufacturer : 1
Production Date : 2574
Device Class : 3
HW Revision : 4
HW Compatibility : 0
System Mailbox State: MaxSend = 1, Pending Receive = 0
Send Packet:
Dest : 0x00000000 ID : 0x00000000
Src : 0x00000000 Sta : 0x00000000
DestID : 0x00000000 Cmd : 0x00000000
SrcID : 0x00000000 Ext : 0x00000000
Len : 0x00000000 Rout : 0x00000000
Data:
System Mailbox State: MaxSend = 1, Pending Receive = 1
Received Packet:
Dest : 0x00000000 ID : 0x00000000
Src : 0x00000000 Sta : 0xC0000004
DestID : 0x00000000 Cmd : 0x00000001
SrcID : 0x00000000 Ext : 0x00000000
Len : 0x00000000 Rout : 0x00000000
Data:
System Mailbox State: MaxSend = 1, Pending Receive = 0
State = 0x00000000
----------------------------------------------------
---------- Communication Channel demo ----------
Error opening Channel! State = 0x800A0003
----------------------------------------------------
--- Read / Write Block Information ---
Error opening Channel!
+ DPM wieder freigegeben.
On the first look it seems your firmware is not being started, which is strange as the log seems to be ok on all other points.We already tested on QNX and the toolkit worked out ok.
Good to know. Would it be possible to post the code snippets used to enable the interrupts and DMA?
Could you take a look at the function cifXStartRAMFirmware() and see if the packet RCX_CHANNEL_INSTANTIATE_REQ_T is correctly transferred to the device (line 1849)? Please check tRecv if it is really the correct answer packet (tSendCmd.ulCmd == tRecvCmd.ulCmd + 1)
Which name did you insert as "szShortFileName" during USER_GetFirmwareFile()?
The latter one was the problem - I haven't set the szShortFileName at all. Setting it to the used filename and the ToolkitSample is working the same way as the Windows variant.
Thanks a lot for your help!
If somebody else is looking at the answer packet, too, here are the values when it is working:
tSendPkt.tHead.ulCmd: 1EC4, tRecvPkt.tHead.ulCmd: 1EC5
Regards
Christian
Hilscher Gesellschaft für Systemautomation mbH
On the first look it seems your firmware is not being started, which is strange as the log seems to be ok on all other points.We already tested on QNX and the toolkit worked out ok.
Good to know. Would it be possible to post the code snippets used to enable the interrupts and DMA?
Good to hear it is working now, but I can't post code snippets here, as there will be a non-free QNX driver release.
I can only give you a hint which QNX functions might be useful for implementing IRQ and DMA, so take a closer look at the functions "InterruptAttach" and "mmap" (for allocating physical memory buffers).
Regards
MT
DMA is now working, too. Thanks.
I have had a problem with the Image Read/Write functions. The ToolkitSample application works on Windows because it does not reset the PCI card. After the hardware reset the firmware needs some time (about 3 s in my setup) before it is allowed to perform the xChannelIORead. Therefore I get two different errors from the Toolkit.
To accomodate this behavior I have had to add tests for the required conditions in front of the first call to xChannelIORead.
The first test is used to avoid the error CIFX_DEV_NOT_RUNNING (0x800C0012). The second test avoids the error CIFX_DEV_NO_COM_FLAG (0x800C0021).
if (!DEV_IsRunning((PCHANNELINSTANCE)hChannel)) // Channel schon da? ggf. warten
{
printf("Communication channel not in running state! Waiting some time ...\r\n");
do
{
printf(".\n");
OS_Sleep(1000);
}
while (!DEV_IsRunning((PCHANNELINSTANCE)hChannel));
}
{
int32_t lRetComm = CIFX_NO_ERROR;
DEV_IsCommunicating((PCHANNELINSTANCE)hChannel, &lRetComm);
if (CIFX_NO_ERROR != lRetComm) // auf das COM flag prüfen und ggf. warten
{
printf("Communication channel not communicating! Waiting some time ...\r\n");
while (CIFX_NO_ERROR != lRetComm)
{
printf(".\n");
OS_Sleep(1000);
DEV_IsCommunicating((PCHANNELINSTANCE)hChannel, &lRetComm);
}
}
}
It would be helpful to add the error text to the status messages, too. It took me some time to recognize that there are two different error codes, because one ends with 21 and the other one was 12. I used this quick hack to get a more meaningfull message:
char pszErrMsg[1024] = {0};
xDriverGetErrorDescription(lRet, pszErrMsg, sizeof(pszErrMsg));
printf(" State = 0x%08X (%s)\r\n", lRet, pszErrMsg);
I would like to get an "ok" or empty message for 0 == , too, e.g. by adding this to s_atErrorToDescrTable:
{CIFX_NO_ERROR ,"ok"},
This aims to get a valid string for every status code.
Regards
Christian
Hilscher Gesellschaft für Systemautomation mbH
This has nothing to do with the hardware reset itself. Depending on the running firmware it depends how long it takes for the firmware to load the configuration (until this time the error CIFX_DEV_NOT_RUNNING is returned).
This is not done in the toolkit, cause it does not know anything about the firmware.
CIFX_DEV_NO_COM_FLAG means that bus communication has not been established yet and this error will not be evaluated inside the toolkit, as it depends on the user's bus layout / startup behaviour (Bus on / off).
Usually the user knows how to wait for these events. A user should not call the DEV_XXX functions directly, but the cifX API functions, as the DEV_XXX functions may change without further notice, as they are used internally.
If you incorporated that code into the toolkit it is specific to your application and does not conform to the cifX API definition (xChannelIORead/Write does not wait for bus communication to start. Note that some users may want to write their output image once, before starting the bus manually). Usually it is sufficient to call xChannelIORead and evaluate the return code to see the current bus state and wait for the appropriate events. Alternatively you can call xChannelInfo() and evaluate the flags manually.
Regards
MT
M T
Hilscher Gesellschaft für Systemautomation mbH
On the first look it seems your firmware is not being started, which is strange as the log seems to be ok on all other points.We already tested on QNX and the toolkit worked out ok.
Could you take a look at the function cifXStartRAMFirmware() and see if the packet RCX_CHANNEL_INSTANTIATE_REQ_T is correctly transferred to the device (line 1849)? Please check tRecv if it is really the correct answer packet (tSendCmd.ulCmd == tRecvCmd.ulCmd + 1)
Which name did you insert as "szShortFileName" during USER_GetFirmwareFile()?
There's also a "ulBootError" variable in the SYSTEM_CHANNEL_SYSTEM_STATUS_BLOCK which is valid if the bootloader (NETX100-BSL.bin) recognizes any errors.
Regards
MT