Doku zur Lib piControl

Rund um die Software von Revolution Pi
Post Reply
PeterS
Posts: 20
Joined: 30 Jan 2018, 15:17
Answers: 0

Doku zur Lib piControl

Post by PeterS »

Hallo Zusammen,

wo liegt die Doku zu der Library "piControl". Die meisten Funktionen findet man ja selbsterklärend in dem PiTest Beispiel.
Warum bei mir piControlGetDeviceInfoList (verwendet in PiTest) funktioniert aber piControlGetDeviceInfo (nicht verwendet in PiTest) nicht, kann ich nicht nachvollziehen. Letzten Endes verstehe ich auch nicht, wozu piControlGetDeviceInfo dient.

VG Peter
User avatar
volker
Posts: 1046
Joined: 09 Nov 2016, 15:41
Answers: 1

Re: Doku zur Lib piControl

Post by volker »

Hallo Peter,
es gibt den kommentierten Quellcode zu den Beispielen, aus dem die Verwendung weitgehend hervorgeht. Bei den ioctl Aufrufen ist leider nicht alles optimal dokumentiert. Ich hoffe, morgen kann mal einer der C-Programmierer Dir dazu näheres sagen.
Unser RevPi Motto: Don't just claim it - make it!
PeterS
Posts: 20
Joined: 30 Jan 2018, 15:17
Answers: 0

Re: Doku zur Lib piControl

Post by PeterS »

Hallo Volker,

danke für deine Info. Bei "Weitgehend" stimme ich dir zu. Es geht sicher nur um die letzten 10% ...

Danke Peter
User avatar
Mathias
Posts: 130
Joined: 29 Nov 2016, 10:46
Answers: 0

Re: Doku zur Lib piControl

Post by Mathias »

Hallo Peter,
die Doku für die ioctls ist halbfertig, im nächsten Image wird sie komplett sein. Die Vorabversion füge ich unten ein.
Der Unterschied zwischen KB_GET_DEVICE_INFO und KB_GET_DEVICE_INFO_LIST ist, dass KB_GET_DEVICE_INFO_LIST die Daten von allen Devices in ein Array schriebt, während KB_GET_DEVICE_INFO nur ein Device liefert.
Gruß
Mathias

PICONTROL_IOCTL(4) Revolution Pi Programmer's Manual PICONTROL_IOCTL(4)



?h.

NAME
picontrol_ioctl - ioctls for piControl driver

SYNOPSIS
#include <piControl.h>

int ioctl(int fd, int cmd, ...);

DESCRIPTION
The ioctl(2) call for piControl accepts many possible command arguments. Most require a third argument, of varying type, here called argp or arg.

Get information from the configuration file
The web application PiCtory is used to configure the I/O- and virtual modules. It writes the configuration to the file /etc/revpi/config.rsc. The piControl driver reads this file when it is started. Most applications can
use the following commands to retrieve some information from configuration. Then they do not need to parse the configuration file themself.

KB_GET_DEVICE_INFO_LIST SDeviceInfo *argp
This call provides information about the configured and connected modules. A pointer to an array of 64 entries of type SDeviceInfo must be passed as argument.
The return value is the number of entries filled the array.

KB_GET_DEVICE_INFO SDeviceInfo *argp
This call provides information about one module. A pointer to a structure of type SDeviceInfo must be passed as argument. Ether the element i8uAddress must be set to the address of the module which information should
be returned. Or the element i16uModuleType must be set to the type of the module. In this case it it only possible to retireve informations about the first module of that typ in the confiugration. The available types
are defined in with the defines KUNBUS_FW_DESCR_TYP_... in the file common_define.h.



The struct SDeviceInfo used by this ioctls is defined as

typedef struct SDeviceInfoStr {
uint8_t i8uAddress; // Address of module in current configuration
uint32_t i32uSerialnumber; // serial number of module
uint16_t i16uModuleType; // Type identifier of module
uint16_t i16uHW_Revision; // hardware revision
uint16_t i16uSW_Major; // major software version
uint16_t i16uSW_Minor; // minor software version
uint32_t i32uSVN_Revision; // svn revision of software
uint16_t i16uInputLength; // length in bytes of all input values together
uint16_t i16uOutputLength; // length in bytes of all output values together
uint16_t i16uConfigLength; // length in bytes of all config values together
uint16_t i16uBaseOffset; // offset in process image
uint16_t i16uInputOffset; // offset in process image of first input byte
uint16_t i16uOutputOffset; // offset in process image of first output byte
uint16_t i16uConfigOffset; // offset in process image of first config byte
uint16_t i16uFirstEntry; // index of entry
uint16_t i16uEntries; // number of entries in process image
uint8_t i8uModuleState; // fieldbus state of piGate Module
uint8_t i8uActive; // == 0 means that the module is not present and no data is available
uint8_t i8uReserve[30]; // space for future extensions without changing the size of the struct
} SDeviceInfo;


KB_FIND_VARIABLE SPIVariable *argp
Find a variable in the process image by its name. A pointer to a structure of type SPIVariable must be passed as argument. Before the call the name of the variable must be written as zero terminated string to the ele‐
ment strVarName. After a successful call i16uAddress is set to the offset of the variable in the process image. i16uLength if the length of the value in bits. It can be 1, 8, 16 or 32. If it is one, i8uBit tells
the bit position [0..7] in the byte. 2 and 4 byte values ar stored in little endian byte order. The address is not alligned to a mutiple of the variable length.

The struct SPIVariable used by this ioctl is defined as

typedef struct SPIVariableStr
{
char strVarName[32]; // Variable name
uint16_t i16uAddress; // Address of the byte in the process image
uint8_t i8uBit; // 0-7 bit position, >= 8 whole byte
uint16_t i16uLength; // length of the variable in bits.
// Possible values are 1, 8, 16 and 32
} SPIVariable;


Set and get values of the process image
KB_GET_VALUE SPIValue *argp
Read one bit or one byte from the process image. Before the call the elements i16uAddress and i8uBit must be set to the address of the value. This call is more efficient than the usual calls of seek and read because
only one function call is necessary.

KB_SET_VALUE SPIValue *argp
Write one bit or one byte to the process image. Before the call the elements i16uAddress and i8uBit must be set to the address of the value. i8uValue must set to the value to write. This call is more efficient than
the usual calls of seek and write because only one function call is necessary. If more than on application are writing bits in one output byte, this call is the only safe way to set a bit without overwriting the
other bits because this call is doning a read-modify-write-cycle.

The struct SPIValue used by this ioctl is defined as

typedef struct SPIValueStr
{
uint16_t i16uAddress; // Address of the byte in the process image
uint8_t i8uBit; // 0-7 bit position, >= 8 whole byte
uint8_t i8uValue; // Value: 0/1 for bit access, whole byte otherwise
} SPIValue;


KB_SET_EXPORTED_OUTPUTS const void *argp
Write all output values to the hardware at once.
This call is used by the main application controlling the outputs. The application must have a complete copy of the process image. It sets the output values in its own copy and calls this ioctl with a pointer to the
image as arguments. This call locks the process image and copies all output values where the export checkmark is set in PiCtory. Afterwards piControl transfers the values to the I/O modules. In the current version
only one application should call this ioctl.


KB_DIO_RESET_COUNTER SDIOResetCounter *argp
Reset counters and encoders to 0 in an input module.
Inputs of DIO and DI modules can be configured as counters or encoders in PiCtroy. After a reset they start at 0. This call can be used set one or more of the values to 0 at the same time.
The argument must be pointer of a structure of type SDIOResetCounter. The element i8uAddress must be set to the address of DIO or DI module as shown in PiCtory, e. g. 32 if the DIO is on the right of the RevPi.
The element i16uBitfield defines which counters will be reset. If a counter is configured on input I_3 and an encoder is configured on the inputs I_6 and I_7, the bits 2 and 5 must be set to 1, i16uBitfield must be
set to the value 0x0024.

The struct SDIOResetCounter used by this ioctl is defined as

typedef struct SDIOResetCounterStr
{
uint8_t i8uAddress; // Address of module in current configuration
uint16_t i16uBitfield; // bitfield, if bit n is 1, reset counter/encoder on input n
} SDIOResetCounter;



SEE ALSO
ioctl(2),

COLOPHON
A description of the project and further information can be found at https://revolution.kunbus.de/forum/.




Linux 2018-01-23 PICONTROL_IOCTL(4)
PeterS
Posts: 20
Joined: 30 Jan 2018, 15:17
Answers: 0

Re: Doku zur Lib piControl

Post by PeterS »

Hallo Mathias,

danke für die Vorabversion ...
Habt ihr schon mal über eine Funktion nachgedacht, die die Variablenliste liefert? Für die Hardware gibt es so etwas ja. Klar geht es auch durch analysieren des Konfigurationsfiles, aber ich dachte ich frage mal ...

VG Peter
User avatar
Mathias
Posts: 130
Joined: 29 Nov 2016, 10:46
Answers: 0

Re: Doku zur Lib piControl

Post by Mathias »

Hallo Peter,
das blöde ist, dass man im Treiber (kernel-space) keinen Speicher allokieren kann und an den User Space übergeben. D.h. vor dem Aufruf muss manim User Space ein Array anlegen das dann vom Treiber gefüllt wird. Die Größe kennt man aber vorher nicht. Außerdem musst du dann diese Liste selbst durchsuchen.
Die Situation ist doch folgende: Du hast ein Anwendungsprogramm das z.B. auf 10 Variablen im Prozessabbild zugreifen will. Also musst du im Moment 10 mal ioctl(KB_FIND_VARIABLE) aufrufen damit du von allen Variablen die Offsets kennst. Mit der anderen Funktion würdest du die Liste mit einem ioctl bekommen und müsstest dann selbst die 10 Variablen darin suchen. Wäre wahrschein weder schneller noch weniger Code. Also welchen Vorteil hätte man?
Das Einlesen der rsc-Datei lohnt eigentlich nur, wenn man ein virtuelle Device implementierne will das auf dem Weg zusätzliche Parameter bekommt.
Gruß
Mathias
User avatar
volker
Posts: 1046
Joined: 09 Nov 2016, 15:41
Answers: 1

Re: Doku zur Lib piControl

Post by volker »

Noch ein kleiner Nachtrag aus der Python-Ecke:
Svens Bibliothek liefert Dir in Python alles, was Du suchst. (https://revpimodio.org/)
Außerdem ist das EInlesen und parsen einer JSON Datei in Python dank der dafür bereitstehenden Bibliotheken extrem einfach, weshalb ich dort eigentlich viel lieber die rsc einlese und parse. In Python ist es nämlich umgekehrt zeimlich stressig, die ioctl-Aufrufe zu starten, denn die zu übergebenden Strukturen und Pointer sind nicht grade die Spezialität des Konzepter der Programmiersprache Python ;-)
Unser RevPi Motto: Don't just claim it - make it!
Post Reply