usage of driver_data member of I2C device id table - linux-device-driver

I am trying to understand I2C client drivers. As per my understanding before registering I2C driver we have to define i2c_device_id table and device tree compatible table.
I have following doubts. Could please help me to understand.
1) The definition of i2c_device_id structure contains two members (name, driver_data). The 1st member (name) is used to define the device name which will be used during driver binding, what is the use of the 2nd member (driver_data).
2) Driver binding will happen based on i2c_device_id table or device tree compatible string.
Thanks in advance.

1) The definition of i2c_device_id structure contains two members (name, driver_data). The 1st member (name) is used to define the device name which will be used during driver binding, what is the use of the 2nd member (driver_data).
First you define the table (array) of i2c_device_id structures, like it's done in max732x.c driver:
static const struct i2c_device_id max732x_id[] = {
{ "max7319", 0 },
{ "max7320", 1 },
{ "max7321", 2 },
{ },
};
MODULE_DEVICE_TABLE(i2c, max732x_id);
In your driver probe function you have one element of this array (for your particular device) as second parameter:
static int max732x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
Now you can use id->driver_data (which is unique to each device from the table) for your own purposes. E.g. for "max7320" chip driver_data will be 1.
For example, if you have features which are specific to each device, you can create the array of features like this:
static uint64_t max732x_features[] = {
[0] = FEATURE0,
[1] = FEATURE1 | FEATURE2,
[2] = FEATURE2
};
and you can obtain features of your particular device from this array like this:
max732x_features[id->driver_data]
Of course, you can use driver name for the same reason. But it would take more code and more CPU time. So basically if you don't need driver_data for your driver -- you just make it 0 for all devices (in device table).
2) Driver binding will happen based on i2c_device_id table or device tree compatible string.
To figure this out you can take a look at i2c_device_match() function (for example here). As you can see, first I2C core tries to match device by compatible string (OF style, which is Device Tree). And if it fails, it then tries to match device by id table.

Related

Using pysnmp for Juniper OIDs (with octets)

The Juniper knowledge base says that you can hit jnxOperatingCPU.x.x.x.x to get the memory usage from the device, and the x.x.x.x are "the last 4 octets", in my case "9.1.0.0".
I don't seem to be able to get results like this using pysnmp's getCmd() method. I have the JUNIPER-MIB in place, but the script returns:
No symbol JUNIPER-MIB::jnxOperatingCPU.9.1.0.0 at < pysnmp.smi.builder.MibBuilder object at 0x198b810>
I have another SNMP monitoring tool in place that can reach this OID, so I know it's valid on this device. I can also use the full numeric OID to get the value, but I'd rather have the pretty name.
Might anyone have an example of using such an OID with pysnmp.hlapi?
From the error message it looks like you are using the ObjectIdentity class incorrectly (pasting code snippet would be helpful though).
According to the JUNIPER-MIB the jnxOperatingCPU object belongs to the jnxOperatingTable table which has these indices:
jnxOperatingEntry OBJECT-TYPE
SYNTAX JnxOperatingEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry of operating status table."
INDEX { jnxOperatingContentsIndex,
jnxOperatingL1Index,
jnxOperatingL2Index,
jnxOperatingL3Index }
::= { jnxOperatingTable 1 }
All four indices are of type Integer32.
Therefore try this:
ObjectIdentity('JUNIPER-MIB', 'jnxOperatingCPU', 9, 1, 0, 0)
Here is the documentation on the ObjectIdentity class.

OPC UA How to read a datatype from the server

I can't seem to figure this one out:
Before writing to a tag I need to know what data type it is expecting(the value that mywrite function receives is always a string).
I realise you have to read the datatype from the server and here's my code to do so, but I'm at a loss as to how to use the information returned:
var nodesToRead = BuildReadValueIdCollection(node.DisplayName, Attributes.DataType);
DataValueCollection readResults;
DiagnosticInfoCollection diag;
_session.Read(
requestHeader: null,
maxAge: 0,
timestampsToReturn: TimestampsToReturn.Neither,
nodesToRead: nodesToRead,
results: out readResults,
diagnosticInfos: out diag);
var val = readResults[0];
What do I do with val to determine what the datatype is?
Do I use Val.Value or Val.WrappedValue or Val.WrappedValue.Value (whatever the difference is ?)
The tag I've been using to test has returned Val = "i=6".....
What is this referring to?
What datatype is "6" and
how do I convert val to something I can use.
Any help would be greatly appreciated.
Thanks
Reading from the DataType attribute returns a NodeID of the OPC UA type. It can be one of the "standard" types defined in the OPC UA spec, or something specific to the server. The standard types reside in namespace 0, which is your case (as there is no "ns=..." part in the displayed Node ID), and "i=6" stands for Int32.
There are many types with pre-defined Node IDs, and you need to consult the OPC UA specs, or the nodeset files that come with the stacks/SDKs (e.g. Opc.Ua.NodeSet.xml), to figure out what they mean.
The value is a NodeId referring to the data type node. You can compare the value to known NodeId values (DataTypeIds in .NET or something, not sure about this right away) or you will need to find the data type node from the address space.
In recent version, node-opcua client has been extended with a utility function ClientSession#getBuiltInDataType that does this for you.
var nodeId = coerceNodeId("ns=411;s=Scalar_Simulation_Int64");
session.getBuiltInDataType(nodeId,function(err,dataType){
if(!err){
console.log("Use data Type",dataType," to write into UAVariable", nodeId.toString();
}
});
We use this extension method to determine the C# type of nodes:
public static Type GetSystemType(this Session session, NodeId nodeId)
{
var currentValue = session.ReadValue(nodeId);
var builtInType = currentValue.WrappedValue.TypeInfo.BuiltInType;
var valueRank = currentValue.WrappedValue.TypeInfo.ValueRank;
return TypeInfo.GetSystemType(builtInType, valueRank);
}
It is somewhat a hack but it works well.

Write a struct into a DICOM header

I created a private DICOM tag and I would like to know if it is possible to use this tag to store a struct in a DICOM file using dicomwrite (or alike), instead of creating a field inside the DICOM header for each struct field.
(Something like saving a Patient's name, but instead of using a char data, I would use double)
Here is an example:
headerdicom = dicominfo('Test.dcm');
a.a = 1; a.b = 2; a.c = 3;
headerdicom.Private_0011_10xx_Creator = a;
img = dicomread('Test.dcm');
dicomwrite(img, 'test_modif.dcm', 'ObjectType', 'MR Image Storage', 'WritePrivate', true, headerdicom)
Undefined function 'fieldnames' for input arguments of type 'double'.
Thank you all in advance,
Depending on what "struct" means, here are your options. As you want to use a private tag which means no application but yours will be able to interpret it, you can choose the solution which is technically most appropriate. Basically your question is "which Value Representation should I assign to my private attribute using the DICOM toolkit of my choice?":
Sequence:
There is a DICOM Value Representation "Sequence" (VR=SQ) which allows you to store a list of attributes of different types. This VR is closest to a struct. A sequence can contain an arbitrary number of items each of which has the same attributes in the same order. Each attribute can have its own VR, so if your struct contains different data types (like string, integer, float), this would be my recommendation
Multi-value attribute:
DICOM supports the concept of "Value Multiplicity". This means that a single attribute can contain multiple values which are separated by backslashes. As the VR is a property of the attribute, all values must have the same type. If I understand you correctly, you have a list of floating point numbers which could be encoded as an array of doubles in one field with VR=FD (=Floating Point Double): 0.001\0.003\1.234...
Most toolkits support an indexed access to the attributes.
"Blob":
You can use an attribute with VR=OB (Other Byte) which is also used for encoding pixel data. It can contain up to 4 GB of binary data. The length of the attribute tells you of how many bytes the attribute's value consists. If you just want to copy the memory from / to the struct, this would be the way to go, but obviously it is the weakest approach in terms of type-safety and correctness of encoding. You are going to lose built in methods of your DICOM toolkit that ensure these properties.
To add a private attribute, you have to
reserve a range for the attribute specifying an odd group number and a prefix (2 hex digits) for the element numbers. (e.g. group = 0x0011, Element = 0x10xx) reserves a range from (0x0011, 0x10xx) - (0x0011, 0x10ff). This is done by specifying a Private Creator DICOM tag which holds a manufacturer name. So I suspect that instead of
headerdicom.Private_0011_10xx_Creator = a;
it should read e.g.
headerdicom.Private_0011_10xx_Creator = "Gabs";
register your private tags in the private dictionary, most of the time by specifying the Private Creator, group, element and VR (one of the options above)
Not sure how this can be done in matlab.

Getting the column name (sspace) from an ospace property name

I can see from the following example how to get the table name of an OSpace type:
https://lowrymedia.com/2014/06/10/ef6-1-mapping-between-types-tables-including-derived-types/
But how do I go about getting the SSpace column name from an OSpace property name (i.e. CLR type property)?
By browsing the MetadataProperties from the corresponding CSpace property, I can see there is a "Configuration" entry containing the column name if changed using the Fluid API or ColumnAttribute, but the value of the entry is an internal class on EF's part. Is it at all possible?
I have browsed a few answers regarding this topic, but none of them take into account the Fluid API configuration.
P.S. the specific property I'm looking for is scalar, if that can simplify things...
Column Name
To get the column name, you have to first get the EdmProperty associated with that column in the “structural space” (SSpace). I provide code to do that below. Once you have the EdmProperty, the name of the column is simply EdmProperty.Name:
string GetColumnName(DbContext context, PropertyInfo property) {
return GetStructuralSpaceEdmProperty(context, property).Name;
}
Structural Space Property
This is based on an article. That article gives you enough information to map all the way to the structural EntityType. I added a bit at the end to do the actual property mapping to get the EdmProperty representing the column. As the article states, these APIs require ≥EntityFramework-6.1.
EdmProperty GetStructuralSpaceEdmProperty(DbContext context, PropertyInfo property) {
IObjectContextAdapter adapter = context;
var metadata = adapter.ObjectContext.MetadataWorkspace;
// First, you map the Object Space to the Conceptual Space.
var objectItemCollection = (ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace);
var objectEntityType = metadata.GetItems<EntityType>(DataSpace.OSpace)
.Single(oet => objectItemCollection.GetClrType(oet) == property.DeclaringType);
// Note: we are assuming that CSpace and OSpace name their properties the
// same instead of trying to use EF’s own OSSpace mappings here.
var conceptualEntityType = metadata.GetItems<EntityType>(DataSpace.CSpace)
.Single(cet => objectEntityType.Name == cet.Name);
var conceptualEdmProperty = conceptualEntityType.Properties
.Single(ep => ep.Name == property.Name);
// Then you map the conceptual space onto the structural space.
var entitySet = metadata.GetItems<EntityContainer>(DataSpace.CSpace)
.Single().EntitySets
.Single(es => es.ElementType.Name == conceptualEntityType.Name);
var entityMapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace)
.Single().EntitySetMappings
.Single(esm => esm.EntitySet == entitySet);
// The entity may be split to different tables or fragments.
var fragments = entityMapping.EntityTypeMappings
.SelectMany(etm => etm.Fragments);
var propertyMappings = fragments.SelectMany(f => f.PropertyMappings);
// Normal properties will be “ScalarPropertyMapping”.
// Depending on what information you are seeking or your
// model, you may be interested in other PropertyMapping.
var structuralSpaceProperty = propertyMappings
.OfType<ScalarPropertyMapping>()
.Single(pm => pm.Property == conceptualEdmProperty).Column;
return structuralSpaceProperty;
}
Note that once you have EdmProperty in structural space, there are a bunch of other useful properties you can read from it. For example, for SQL Server, EdmProperty.IsUnicode will be true for NVARCHAR/NCHAR and false for VARCHAR/CHAR types whereas this property is not set to a useful value in the conceptual space.
Random Information
Spaces in EF
Alex D. James’s blog post “Tip 10 — How to understand Entity Framework jargon” explains some of the terms of the API which do not make sense on their own. DataSpace.OSpace stands for “Object Space”, meaning the .net POD classes. DataSpace.SSpace stands for “Structural Space”, probably named after “structured” in the term “SQL” and thus meaning it most directly describes the backend database. DataSpace.CSpace stands for “Conceptual Space” which seems intended to be a neutral space which both the “Object Space” and “Structural Space” can map into. DataSpace.OCSpace stands for the mapping from the object space onto the conceptual space. We bypass this mapping because we assume that property names in the object space are the same as in our .net types. DataSpace.CSSpace stands for the mapping of conceptual space onto structural space. We use this mapping because the model may be configured to use a different column name via the fluent API or ColumnAttribute.
API Confusion
The metadata API of EF seems to assume that the consumer of the API has an understanding of the internals of EF to an extent. It is not made in a very type safe way which helps consumers. For example, the fact that we had to use Enumerable.OfType<TResult> to get to ScalarPropertyMapping means that one has to know to expect the collection to have ScalarPropertyMapping instances in it. Likewise, the MetadataWorkspace.GetItems<T>() method requires us to know that the sorts of items one would find in the metadata include EntityType. Thus, a deep understanding of the internals of EF or complete examples are necessary to write code that consumes the mapping portion of these APIs.

MIDL marshaling array of structures using size_is in unmanaged c++

I’m trying to retrieve an array of structures through a COM interface. It works when the number of structures is 1. When the number of structures is greater than 1, only the first structure is marshaled correctly. The remaining structures in the array have garbage data.
My interface looks like this:
typedef struct tagINTOBJINTERFACE
{
long lObjectId;
IMyObject* pObj;
} INTOBJINTERFACE;
[
object,
uuid(<removed>),
dual,
nonextensible,
helpstring("Interface"),
pointer_default(unique)
]
interface IMyInterface : IUnknown {
HRESULT CreateObjects(
[in] VARIANT* pvDataStream,
[out]long* Count,
[out,size_is(,*Count)] INTOBJINTERFACE** ppStruct
);
};
I allocate the structure memory like this:
long lCountInterfaces = listInterfaces.GetCount();
long lMemSize = lCountInterfaces * sizeof(INTOBJINTERFACE);
INTOBJINTERFACE* pstruct = (INTOBJINTERFACE*) CoTaskMemAlloc( lMemSize );
And then fill in the members of each structure in the array. I can see in the debugger that all members of all array elements are properly assigned.
After filling in the structures, I assign “*ppStruct = pstruct” to pass the array out.
I can also see that the out parameter “*Count” is properly set to the correct number of elements.
Why doesn’t this work?
Reason:
Your application uses the universal marshaller from windows for mashalling.
The universal marshaller reads the meta data from your typelib (*.tlb).
The generated typelib doesn't support size_is.
Todo:
You should use the Proxy/Stub dll generated by Visual Studio (...PS project).
- Build the Proxy/Stub dll
- call "regsvr32 "
- remove the "TypeLib = s '{?????-...-????}'" entry from your servers "*.rgs"
file
In addition to Joerg's answer that using size_is is not possible, here is what's possible: SAFEARRAY.
Keywords: Safearray of UDT
Explanation and examples are here
Short summary:
Define structure with a GUID.
Create object of type IRecordInfo that describes your structure using the type library.
Use SafeArrayCreateEx to create SAFEARRAY of type VT_RECORD.
Fill it with data.
Retrieve on the other side.