How to add write_raw function in my iio_info structure - linux-device-driver

I am writing a driver using iio framework. So far it goes well. All the inputs and sysfs entries are working perfectly and the values measured are fine. (It is very well documented and it is easy). But I need a small extension to be able to write on one of the channels. When I add my function in iio_info the compiler issues me an error:
drivers/iio/adc/iio-ccuss.c:197:15: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.write_raw = ccuss_iio_write_raw,
^~~~~~~~~~~~~~~~~~~
It is very weird for me. I even can't believe I am asking shamelessly this here but I am very frustrated. I lost almost half day with that.
My structure is:
static const struct iio_info ccuss_iio_info = {
.driver_module = THIS_MODULE,
.attrs = &ccuss_iio_attribute_group,
.read_raw = ccuss_iio_read_raw,
.write_raw = ccuss_iio_write_raw,
};
my channel types are IIO_VOLTAGE, IIO_TEMP and IIO_HUMIDITYRELATIVE.
I am start thinking to make it as an device attribute :-( if I do not receive an answer in the next 12 hours.
Update:
just to be more visible, according Murphy's comment.
static int ccuss_iio_write_raw(struct iio_dev *iio,
struct iio_chan_spec const *channel, int *val1,
int *val2, long mask);
P.S. I do not want to remove this error by the most known way. The QA (and me) will be unhappy.
Thanks

According to the reference the write_raw() function is declared as follows:
int (*write_raw)(
struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val,
int val2,
long mask);
Your implementation is declared like this:
static int ccuss_iio_write_raw(
struct iio_dev *iio,
struct iio_chan_spec const *channel,
int *val1,
int *val2,
long mask);
So you declare the two integer parameters as pointers, but they are expected to be passed by value. I think that's the mismatch that causes the "incompatible pointer type" error.

Related

Any way to pass enum values by name as commandline args?

Is there any way to pass the value of an enum by name from the commandline? Rather what's the cleanest solution?
I tried the below,
typedef enum int unsigned { white, black, red } colour_e;
class house;
rand colour_e colour;
string n_colour = "white";
constraint c_colour {
colour.name() == n_colour;
}
endclass: house
program top;
house paradise;
initial begin
paradise = new();
void'($value$plusargs("colour=%0s", paradise.n_colour));
if (!paradise.randomize())
$display("not randomized");
else
$display("paradise.colour = %s",paradise.colour);
end
endprogram: top
I would want to pass something like this +colour=black. so that the paradise.colour is assigned black.
vcs cribbed for using enum.name() in the constraints.
below is the error.
Error-[NYI-CSTR-SYS-FTC] NYI constraint: sys function calls
T-enum_1.sv, 9 $unit, "this.colour.name" System function calls are
not yet implemented in constraints. Remove the function call or if
possible replace it with an integral state variable assigned in
pre_randomize().
while Riviera cried as below
ERROR VCP7734 "Type of 'this.colour.name()' is not allowed in a
constraint block. Only integral types are allowed in a constraint
block." "design.sv" 9 1 ERROR VCP7734 "Type of 'n_colour' is not
allowed in a constraint block. Only integral types are allowed in a
constraint block." "design.sv" 9 1 WARNING VCP7114 "STRING value
expected for format specifier %s as parameter
paradise.colour." "testbench.sv" 13 54
which brings the question to me, does everything in the contraint block has to be of integral type (just like we cannot declare a string as rand variable)?
ANyone wants to play around the code please have a look at the code at EDA playground here
Use uvm_enum_wrapper class to do the conversion from string to corresponding enum value. It is a template class wrapper defined in uvm_globals.svh (part of UVM 1.2) and you can use it as follows:
typedef enum {white, black, red} colour_e;
typedef uvm_enum_wrapper#(colour_e) colour_wrapper;
string colour_str;
void'($value$plusargs("colour=%0s", colour_str));
colour_wrapper::from_name(colour_str, paradize.n_colour);
The wrapper class uvm_enum_wrapper works by traversing the enum entries and creating an assoc array for a enum[string] map for the given enum type (supplied as template parameter). For more details take a look at the documentation.
There is another solution for the same. If you are not using UVM 1.2 version then there is like you can take string as an input argument and convert that string argument into int type. After that you can directly cast int to enum type by $cast.
Because there is no way to convert string to enum type (except UVM 1.2) so you have to add one extra step for the same.
module Test;
typedef enum {black,red,blue} color_e; //enum declaration
color_e color; //type of enum
string cmd_str; //Commandline string input
int cmd_int; //Input string is first converted into int
initial
begin
$value$plusargs("enum_c=%0s",cmd_str); //Take input argument as string it may be 0,1 or 2
cmd_int=cmd_str.atoi(); //Now convert that string argument into int type
$cast(color,cmd_int); //Casting int to enum type
$display("Value of color is --> %p",color); //Display value of enum
end
endmodule

Updating a classes' variable in a constructor through pass by reference?

Blazing ahead with newfound knowledge of SystemVerilog's inner workings I've set out to use one of these fandangled pass-by-reference features to update a classes' counter in the constructor of another class. The setup (stripped to the basics) looks somewhat like this:
class my_queue;
int unsigned num_items; //Want to track the number of items this Queue has seen.
function push_new_item();
item new_item = new(num_items);
endfunction
endclass
class parent_item;
int unsigned x_th_item;
function new(ref int unsigned num_items);
x_th_item = num_items;
num_items += 1; //This should increase the counter in num_items.
endfunction
endclass
class item extends parent_item;
function new(ref int unsigned num_items);
super.new(num_items);
endfunction
endclass
The issue is that my compiler is complaining about an
Illegal connection to the ref port 'num_items' of function/task parent_item::new, formal argument should have same type as actual argument.
I have an idea on how to fix this: Moving the increment after the call to new() in push_new_items.
But then I still won't know how to correctly use pass-by-refrence in SV so what's causing the error?
Is it the other pass-by-reference or maybe a syntactical error?
You do not need ref semantics for this, use an inout argument.
inout's are copied-in upon entry and copied-out upon return of a task or function. The type compatibility requirements are much stricter as you have seen for ref arguments.
The only occasion you must use a ref argument isin time consuming tasks and you need to see active updates to the arguments before the task returns.
task my_task(ref bit tclock);
#(posedge tclock) // this would hang if tclock was an input
endtask
Another place you might want to use a ref argument is as an optimization when the argument type is a large object like an array. But passing a single int by reference is actually slower than copying its value directly.
Qiu did point me to the issue with my code. My problem was that, whilst the variables were declared correctly on both ends, one of my constructors was written:
function new(ref int num_items);
where it should have rather been
function new(ref int unsigned num_items);
Thank you Qiu.

tesseract how to find the blob

I'd like to use tesseract-ocr making newspaper's page layout analysis, in order to find the blobs(titles, paragraphs) on iOS platform. I don't know how to achieve it and how to use the tesseract API.There are some mistakes:
tesseract::PageIterator *pageIterator = tesseract->AnalyseLayout();
error : Member access into incomplete type 'tesseract::PageIterator'
tesseract::PageIteratorLevel * level = pageIterator->level();
int *left; int *top; int *right; int *bottom;
pageIterator->BoundingBox(level,left,top,right,bottom);
error : Member access into incomplete type 'tesseract::PageIterator'
I need your advice. Thank you!
The code is going to be similar to Tess4J: How to use ResultIterator?, but at RIL_PARA or RIL_BLOCK level.

UIA: Get ControlType from control type name (string)

Using Microsoft UI Automation. I have a string which represents UIA control type, like "Window" or "Button". I would like to get a ControlType object which fits this string. How to do it? Is some enumerations exists which represents all the UIA control types? I found only that ControlType has ControlType.LookupById(int) method. But I have to know correspondence between ID and name. Of course, I can create my own switch with all the possible UIA control types, or even use reflection to get all the members of ControlType factory. But I'm sure should be easier way..
I've found such way, using PresentationCore.dll, very strange for me, that such enum doesn't exist in standart UIA DLL. Also please pay attention, that there is a bug in ControlType class, I guess due to its private static constructor. If you call ControlType.LookupById(enumId) 1st time, it will return null, but in the 2nd time will be OK. The solution is quite simple -- just call ToString before usage, it will initialize the static constructor :)
using System.Windows.Automation.Peers;
// solving the bug with static constructor of ControlType..
ControlType.Button.ToString();
string controlTypeString = "Window";
AutomationControlType typeEnum;
bool result = Enum.TryParse(controlTypeString, true, out typeEnum);
if (result) typeEnum = (AutomationControlType)Enum.Parse(typeof(AutomationControlType), controlTypeString);
int enumId = (int)typeEnum + 50000;
ControlType controlType = ControlType.LookupById(enumId);

Error "Expected specifier-qualifier-list before" at struct constructor

I am trying to write some code to optimize some Open GL functions for a program I'm writing, unfortunately, I am not exactly a C or C++ veteran, but that's partially why I'm doing this project!
So I'm creating a struct to handle 3x3 matrices and I am defining the struct as follows:
#ifndef MATRIX3BY3_H
#define MATRIX3BY3_H
struct Matrix3by3
{
float ix, jx, kx;
float iy, jy, ky;
float iz, jz, kz;
Matrix3by3() {}
Matrix3by3(const Matrix3by3 &matrix)
{
ix = matrix.ix;
jx = matrix.jx;
kx = matrix.kx;
iy = matrix.iy;
jy = matrix.jy;
ky = matrix.ky;
iz = matrix.iz;
jz = matrix.jz;
kz = matrix.kz;
}
Matrix3by3 (const float _ix, const float _jx, const float _kx,
const float _iy, const float _jy, const float _ky,
const float _iz, const float _jz, const float _kz) :
ix(_ix), jx(_jx), kx(_kx),
iy(_iy), jy(_jy), ky(_ky),
iy(_iz), jx(_jz), kz(_kz) {}
};
#endif
And I get the error (twice)
Expected specifier-qualifier-list
before 'Matrix3by3'
On the line of the first constructor. I have tried to look around for answers for this, and it seems that it has to do with the compiler not knowing that this is a type. So I have tried the following, I'll remove the innards for brevity:
typedef struct Matrix3by3 { ... };
struct Matrix3by3 { struct Matrix3by3() {} ... };
struct Matrix3by3 { ... } Matrix3by3;
typdef struct Matrix3by3;
struct Matrix3by3 { ... };
Which are all solutions that were suggested on blogs and articles that I saw for this error. I also saw that it may arise because of a circular dependency, but this file has no includes that include anything else, and I've even removed them just to be certain from time to time - no change.
I could write this in a objective-c class, I'm sure, but it will probably take a tiny bit more memory and cycles, and that's exactly what I'm trying to avoid. The only thing I can think of left is some compiler/project setting that I have set by default that precludes my using this type of structure. Entirely possible, as I'm learning the language/environment.
Can any one provide some help?
Thanks!
C does not support constructors or member functions of structs. There is no way you will get this to compile as C or Objective-C. You need to compile this as C++ or Objective-C++, at which point it will almost compile: you have an error in your 3rd constructor, in that you're attempting to initialize the members iy and jx multiple times. Once you fix those typos, it compiles just fine.
typedef struct { ... } Matrix3by3;
should work. It declares the anonymous struct as a type.
And use class instead of struct :)
What language/compiler are you translating your program with? I'd guess that you are trying to compile the code as C, while the language features you are trying to use are strictly C++-specific.
The error "Expected specifier-qualifier-list before 'Matrix3by3'" is a GCC-ism and it means that the token "Matrix3by3" is unknown. This is typically the case when you have a type that the compiler doesn't recognize, either because you mistyped it or because you forgot a header. In your case, it's because the type "Matrix3by3" really doesn't exist. You have two options:
Stop using Matrix3by3 directly and start using struct Matrix3by3 instead, as that's the actual type you defined.
Give your struct a typedef. It will look something like
typedef struct {
// fields here
} Matrix3by3