How to use a common variable in multiple files in CAPL (How to replace extern) - capl

I wanted to use a variable in 5 main CAN files. I have one include file common for all 5 CAN files. So I defined and declared the variable in this include file. But when I read the value of the variable from the main files I always get 0. Unfortunately Extern is not available in CAPL. So is there a way to do this.
Thanks.

If you use CAPL with CANoe you can create a database with the Vector CANdb++ Editor and declare an Environment-Variable in the database.
You Can access this variable in all your CAPL-files like this:
putValue(YourEnvironmentVariable,12); // Assigns the value 12 to the variable
Write("%d",getValue(YourEnvironmentVariable); //Prints 12
You can also declare an event that is thrown on change of the environment variable.
on envVar YourEnvironmentVariable{//do something...}

You can use System Variables for global access.
First you want to define a new namespace and a system variable in an include file global.cin:
/* global.cin */
on Start {
// define a namespace
sysDefineNamespace("myNamespace");
// define an integer system variable with starting, minimum and maximum value
sysDefineVariableInt("myNamespace", "mySysvar", 0, 0, 99);
}
By including global.cin in the main.can file you can then access the system variable using the corresponding CAPL functions:
/* main.can */
includes
{
#include "global.cin"
}
on Start {
// set system variable value
sysSetVariableInt("myNamespace", "mySysvar", 42));
// read system variable value
write("mySysvar: %d", sysGetVariableInt("myNamespace", "mySysvar"));
}
For data types other than integer there are corresponding CAPL functions in the naming-style of
sysDefineVariable<data-type>()
sysSetVariable<data-type>()
sysGetVariable<data-type>()
You can find additional information about accessing system variables via CAPL in the documentation of CANoe / CANalyzer under CAPL Functions -> System Variables CAPL Functions

Related

How to pass an env variable in CAPL trough a function?

I would like to set environment variables with a function. Is it even possible?
void SetEnvVariable(byte env_flag, byte ret_val)
{
putValue(env_flag, ret_val);
}
I get this error:
Error 1030 at (83,14): Environment variable expected. Database missing? test.cin
the CAPL function putValue require Environment variable name (on first parameter).
you cannot pass char name/value on first parameter by user defined function to this putValue.
what you can do is an workaround with hard bind the envar to if/switch case for example:
void SetEnvVariable(byte env_flag, byte ret_val)
{
if(env_flag==1)
{
putValue(Switch_K1, ret_val);
}
if(env_flag==2)
{
putValue(Switch_K2, ret_val);
}
}
where environment variable name Switch_K1 and Switch_K2 must be exist.
Note: The creation of environment variables is no longer supported. Instead, use system variables directly in CANoe. Currently CANoe still supports the use of environment variables. This support will not be available in future versions.

SystemVerilog - How to get the number of enumerated types at compile time

I trying to find a way to get the number of possible enumerations in an enum type at compile time. I need this for initializing a templated class that uses enumerated types.
I am curious if there is a utility function (or system task) that gives this. It would be similar to $size() but for enumerated types. However, I can't seem to find a function for that. After doing a lot of research, it doesn't seem to be possible.
Here is an example I am trying to do:
typedef enum {RANDOM, STICKY, SWEEP} bias_t;
// can be parameterized to pick another enum type at random
class enum_picker #(type T = bias_t); //type must be an enumerated type
local T current_type;
local const int weights[$size(T)]; //<--- How do I get the number of enumerated types?
function T pick_type();
... some code ...
endfunction
endclass
So for the variable weights, it is an array of weights in which its size is the number of enumerated types. Right now it is 32 because of the $size() call but that is wrong; in this particular code example, the array size should be 3.
Is there a way to do this? Or is this simply not allowed in SystemVerilog?
You probably don't want to set up weights as a const; you would not be able to set values into it. You can use the num() method to get the number of enumerations.
class enum_picker #(type T = bias_t); //type must be an enumerated type
local T current_type;
local int weights[];
function new;
weights = new[current_type.num()];
foreach (weights[i]) weights[i] = $urandom_range(10);
endfunction
function T pick_type();
endfunction
endclass

Record non-scalar parameter in Omnet++

I am using a non-scalar parameter for my parameter study:
*.server.serviceTime = ${B=exponential(20ms), exponential(35ms)}
However, compared to the other scalar parameters, the B parameter is not shown in the Browse Data section of the results, which I was using until now to export the results of my parameter study:
How can I record the parameter of the exponential distribution (B) that I'm using?
The serviceTime is declared in the .ned as follows:
volatile double serviceTime #unit(s);
If I'm not mistaken you would like to record the mean value of the exponential distribution. Here is an example how the PureAlohaExperiment sample does this:
[Config PureAlohaExperiment]
...
Aloha.numHosts = ${numHosts=10,15,20}
Aloha.host[*].iaTime = exponential(${mean=1,2,3,4,5..9 step 2}s)
i.e. put the interation variable inside the exponential function.
You may put in a NED module a parameter called B. Then, you do the following in the omnetpp.ini:
**.B = ${B=exponential(20ms), exponential(35ms)}
Finally, you record the B NED parameter in the finish() function:
recordScalar("B", par("B"));
There is an option param-record-as-scalar for saving parameter as a scalar. An example of using it:
*.server.serviceTime.param-record-as-scalar = true
However, it doesn't work for volatile parameters (there is an error during finishing simulation). It seems that it is intentionally behaviour to avoid registering "meaningless" random values.
If you really need current random value of volatile parameter, you should record it as a new scalar just after reading it, for example:
double serviceTime = par("serviceTime").doubleValue();
recordScalar("serviceTime 1", serviceTime);
// ... later
serviceTime = par("serviceTime").doubleValue();
recordScalar("serviceTime 2", serviceTime);

How do I pass a global or process private global by reference to a procedure

Say I have Caché ObjectScript procedure that expects to receive a by reference array parameter:
TotalArray(Arr)
S Total=0
S K=""
F {
S K=$O(Arr(K))
Q:K=""
S Total=Total+Arr(K)
}
Q Total
I can call that procedure with a regular array by reference with the dot syntax:
S A(1)=5
S A(2)=10
W $$TotalArray(.A)
But when I try to do it with a global reference, I get a syntax error with the dot syntax:
S ^A(0)=5
S ^A(1)=10
W $$TotalArray(.^A)
What is the correct way to pass a global array by reference to an ObjectScript procedure? I also want to be able to pass process private globals (the ^||Array convention)
If you use it with indirection as Brandon suggested:
TotalArray(ArrName)
S Total=0
S K=""
F {
S K=$O(#ArrName#(K))
Q:K=""
S Total=Total+#ArrName#(K)
}
Q Total
and then you call it like this
W $$TotalArray("^A")
or even
W $$TotalArray("^A(""someIndex"")")
This is not possible. You could either
Pass the name of the global, and access it by Indirection, or
MERGE the global into a local variable (if it is small enough), and pass that by reference.

How to assign/bind a known function to a variable?

I wonder how to make a variable within IDA Pro bound to some function so the next time I double click the variable it will send me to the function.
v1 = this
*v2 = Known-Function
At Some Different location:
char __stdcall ClassA__KnownFunction(ClassA *ClassA, void a2) {
commands.....
}
I know you can set type to int, struct, dword etc. But I am looking for some method to point the variable to already known offset/function in IDA Pro.
Function pointer is merely a variable that holds the address of a function; you cannot treat a variable like a constant. You have two options:
Add the name of the function as a comment (just for the sake of documentation).
Get rid of the variable assignment, hard-code the function address by editing the hex, and then perform the analysis again.

Resources