how to loop over multiple registers in linux device tree node? - c

I implemented a generic driver, in the driver I just want to go over each registered device and do something.
my driver is generic so I don't want to know anything in advance about the devices.
I have some device tree nodes:
uart0: uart#1000000 {
compatible = "generic-driver";
reg = <0x1000000 0x1000>,<0x1001000 0x1000>,<0x1002000 0x1000>;
};
uart1: uart#2000000 {
compatible = "generic-driver";
reg = <0x2000000 0x1000>,<0x2001000 0x1000>,<0x2002000 0x1000>;
};
in the driver I know how to get first offset and size with platform_get_resource, but what if I have multiple ranges?
I saw an option to get it by add reg-names:
reg = <0x2000000 0x1000>,<0x2001000 0x1000>,<0x2002000 0x1000>;
reg-names = "uart0_0","urat0_1","uart0_2";
so in the driver I can use platform_get_resource_byname, but there I need to know in the driver the regs names in advance - but it'll be no more generic - unwanted!!
so my question is, is there a way to loop over these regs without early information in the driver?
Thanks in advance!!

If you go through the definition for platform_get_resource you will find that the last parameter is the resource number. So, for the example you gave resource numbers will range from 0 to 2.
In case you don't know the number of resource then you can run an loop till you get a NULL as response to platform_get_resource.

Related

Data output from the device

I am working on a project,in which I need to extract data from the device: InertialUnit.
I get a single value in real time, but I need data for the first 10 s and in 1 ms increments, or all the data for the entire cycle of the device. Please help me implement this if possible.
Webots controllers are like any other programs, so you can easily get the values of the inertial unit and save them in a file at each step.
Here is a very simple example in Python:
from controller import Robot
robot = Robot()
inertial_unit = robot.getInertialUnit('inertial unit')
inertial_unit.enable(10)
while robot.step(10) != -1:
values = inertial_unit.getValues()
with open('values.txt','a') as f:
f.write('\n'.join(values))

Rewriting cpufreq_frequency_table initialization for legacy cpufreq_driver

long time listener, first time caller.
I've been backporting features from upstream code as recent as 4.12-rc-whatever to a 3.4-base kernel for an older Qualcomm SoC board (apq8064, ridiculous undertaking I know).
Thus far I've been successful in almost every core api, with any compatibility issues solved by creative shims and ducttape, with the exception of cpufreq.
Keep in mind that I'm still using legacy platform drivers and clocking, no dt's or common clock frame work.
My issue begins with the inclusion of stuct cpufreq_frequency_table into struct cpufreq_policy, as part of the move from percpu to per-policy in the api. In 3.13, registering a platform's freq_table becomes more difficult for unique cases, as using cpufreq_frequency_table_get_attr is no longer an option.
In my case, the cpufreq_driver's init is generic, and relies on my platform's scaling driver (acpuclock-krait) to register the freq_table, which is fine for the older api, but becomes incompatible with the per-policy setup. The upstream so I requires the driver to manually initialize policy->freq_table and mine uses both a cpu, and an array of 35 representing the tables in the platform code. As well, it accounts for the 6 different speedbin/pvs values when choosing a table. I'm considering either dropping the "cpu" param from it and using cpumask_copy, and perhaps even combining the two drivers into one and making the clock driver a probe, but yeah, thus far init is a mystery for me. Here is the snippet of my table registration, if anyone can think of something hackable, I'd be eternally grateful...
ifdef CONFIG_CPU_FREQ_MSM
static struct cpufreq_frequency_table.freq_table[NR_CPUS][35];
extern int console_batt_stat;
static void __init cpufreq_table_init(void)
{
int cpu;
int freq_cnt = 0;
for_each_possible_cpu(cpu) {
int i;
/* Construct the freq_table tables from acpu_freq_tbl. */
for (i = 0, freq_cnt = 0; drv.acpu_freq_tbl[i].speed.khz != 0
&& freq_cnt < ARRAY_SIZE(*freq_table)-1; i++) {
if (drv.acpu_freq_tbl[i].use_for_scaling) {
freq_table[cpu][freq_cnt].index = freq_cnt;
freq_table[cpu][freq_cnt].frequency
= drv.acpu_freq_tbl[i].speed.khz;
freq_cnt++;
}
}
/* freq_table not big enough to store all usable freqs. */
BUG_ON(drv.acpu_freq_tbl[i].speed.khz != 0);
freq_table[cpu][freq_cnt].index = freq_cnt;
freq_table[cpu][freq_cnt].frequency = CPUFREQ_TABLE_END;
/* Register table with CPUFreq. */
cpufreq_frequency_table_get_attr(freq_table[cpu], cpu);
}
dev_info(drv.dev, "CPU Frequencies Supported: %d\n", freq_cnt);
}
UPDATE!!! I wanted to update the initial registration BEFORE merging all the core changes back in, and am pretty certain that I've done so. Previously, the array in question referenced a percpu dummy array that looked like this: freq_table[NR_CPUS][35] that required the cpu parameter to be listed as part of the table. I've made some changes here that allows me a percpu setup AND the platform-specific freq management( which cpufreq doesn't need to see), but with a dummy table representing the "index," which cpufreq does need to see. Commit is here, next one fixed obvious mistakes: https://github.com/robcore/machinex/commit/59d7e5307104c2396a2e4c2a5e0b07f950dea10f

D3DKMTOpenAdapterFromDeviceName and DeviceName

I'm looking for the way to communicate with display driver, and found this function, its a bit poorly documented in msdn. I need to use this, because it will return me the handle which later i can use to display the gpu load in my application. But there is a problem, what i did is i looked in my Device Manager, and copied the value of the "the path to the device instance" in my gpu properties. it looks like so:
PCI\VEN_1002&DEV_6798&SUBSYS_04481043&REV_00\4&72ACCB3&0&0008
Here is the example of D3DKMTOpenAdapterFromDeviceName which i found:
D3DKMT_OPENADAPTERFROMDEVICENAME name = { _T("\\\\?\\pci#ven_10de&dev_0a2b&subsys_9072104d&rev_a2#4&12796cb&0&0008#{1ca05180-a699-450a-9a0c-de4fbe3ddd89}") };
HMODULE hGdi32 = LoadLibrary(_T("gdi32.dll"));
PD3DKMTOpenAdapterFromDeviceName D3DKMTOpenAdapterFromDeviceName = (PD3DKMTOpenAdapterFromDeviceName)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromDeviceName");
NTSTATUS status = D3DKMTOpenAdapterFromDeviceName(&name);
In this example they have some GUID at the end of the device #{1ca05180-a699-450a-9a0c-de4fbe3ddd89}. So which GUID from the device manager properties of my GPU i should use? I tried to use like half of the GUIDS from my VideoCard properties in Device Manager and always get - "STATUS_INVALID_PARAMETER"
{1ca05180-a699-450a-9a0c-de4fbe3ddd89} is the identifier of GUID_DISPLAY_DEVICE_ARRIVAL
So you can compose your name like:
"\\\\?\\" + deviceName + "#{1ca05180-a699-450a-9a0c-de4fbe3ddd89}"
replacing your "\" for #; example with yours:
"\\\\?\\" + "PCI#VEN_1002&DEV_6798&SUBSYS_04481043&REV_00#4&72ACCB3&0&0008"+"#{1ca05180-a699-450a-9a0c-de4fbe3ddd89}"
And then to find this programatically you can do a COM search like this:
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_VideoController"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
And taking PNPDeviceID which is the string you've found at your Device Manager; take in account of being sure it's your currently in use graphic card, as it's possible to have more than one.

Hash-based logger for embedded application

Currently I am sending the UART the strings I want to log and reading it on the host with any terminal.
In order to reduce the logging time and hopefully the image size as well (my flash is tiny), I figured out that the strings are unused in the embedded system, so why storing them on the flash?
I want to implement a server, whom I can send a hashed-key of any string (for example - it's ROM address) and the string will be output to file or screen.
My questions are:
How to create the key2string converter out of the image file (the OS is CMX, but can be answered generally)
Is there a recomended way to generate image, that will know the strings addresses but will exclude them from ROM?
Is there a known generic (open-source or other) that implemented a similar logger?
Thanks
Rather than holding hard-coded strings, then trying to hash the answers and sent it via a UART, then somehow remove the strings from the resulting image, I suggest the following.
Just send an index for an error code. The PC side can look up that index and determine what the string is for that condition. If you want the device code to be more clear, the index can be an enumeration.
For example:
enum errorStrings
{
ES_valueOutOfLimits = 1,
ES_wowItsGettingWarm = 2,
ES_randomError = 3,
ES_passwordFailure = 4
};
So, if you were sending data to the UART via printf, you could do the following:
printf("%d\n",(int)ES_wowItsGettingWarm);
Then your PC software just needs to decode the "2" that comes across the UART back into a useful string of "Wow it's getting warm."
This keeps the firmware small, but you need to manually keep the file containing the enum and the file with the strings in sync.
My solution is sending file name and line (which should be 14-20 Byte) and having a source parser on the server side, which will generate map of the actual texts. This way the actual code will contain no "format" strings, but single "filename" string for each file. Furthermore, file names can be easily replaced with enum (unlike replacing every string in the code) to reduce the COMM throughput.
I hope the sample psaudo-code will help clarifying the idea:
/* target code */
#define PRINT(format,...) send(__FILE__,__LINE__,__VA_ARGS__)
...
/* host code (c++) */
void PrintComm(istream& in)
{
string fileName;
int line,nParams;
int* params;
in>>fileName>>line>>nParams;
if (nParams>0)
{
params = new int[nParams];
for (int i=0; i<nParams; ++i)
in>>params[i];
}
const char* format = FindFormat(fileName,line);
...
delete[] params;
}

How to find which device is attached to a USB-serial port in Linux using C?

We are making a device and it has 8 serial ports. It runs on the Monta Vista Pro5 kernel. And we are working in C.
Suppose: A device gets attached to ttyUSB0, ttyUSB1 and ttyUSB2. The next device gets connected to ttyUSB3 and another to ttyUSB4. How can I know which device gets attached to which port ?? ie ttyUSB0 or ttyUSB1 or so on. Is there a way to directly query the device and find which port it is attached to. Or, in C, open ttyUSB0, query it somehow and get some reply as to which device it is ??
A rather complicated way: do a stat of, say /dev/ttyUSB0. Get the device number. And search for this in /proc/bus/usb/devices and find the vendor id or something to identify the device.
Or: Is there some way to reserve ttyUSB0,ttyUSB1 and ttyUSB2 for one device, ttyUSB3 for another and so on when they are plugged in ? This way I will know which device is connected to which port.
Help please..... :)
Thanks in advance.
Nubin Stanley
You can use udev rules to create symbolic links just to your device:
(these rules go in /etc/udev/rules.d/-name.rules -- look at your udev documentation
KERNEL=="ttyUSB*", ATTRS{idVendor}=="<vendorid>", MODE="0666", SYMLINK+="mydev"
You have to specify your vendor id and/or product id for your device. Then those devices will be available at /dev/mydev in the above example.
You can also use various other parameters to create appropriate unique symbolic links for your use. Check udev man page.
Here's my code, based on Alex Robinson's, but without global "except":
import os
from os.path import join
def find_tty_usb(idVendor, idProduct):
"""find_tty_usb('067b', '2302') -> '/dev/ttyUSB0'"""
# Note: if searching for a lot of pairs, it would be much faster to search
# for the enitre lot at once instead of going over all the usb devices
# each time.
for dnbase in os.listdir('/sys/bus/usb/devices'):
dn = join('/sys/bus/usb/devices', dnbase)
if not os.path.exists(join(dn, 'idVendor')):
continue
idv = open(join(dn, 'idVendor')).read().strip()
if idv != idVendor:
continue
idp = open(join(dn, 'idProduct')).read().strip()
if idp != idProduct:
continue
for subdir in os.listdir(dn):
if subdir.startswith(dnbase+':'):
for subsubdir in os.listdir(join(dn, subdir)):
if subsubdir.startswith('ttyUSB'):
return join('/dev', subsubdir)
This Python code seems to find the /dev/ttyUSB number for the given vendor ID and product ID. Not hard to translate it to C. Parsing the output from hwinfo --usb can do the trick, too. The regx is:
"\s\sVendor:\susb\s0x([0-9a-f]{4}).*?\s\sDevice:\susb\s0x([0-9a-f]{4}).*?\s\sDevice\sFile:\s/dev/ttyUSB([0-9]+)"
import glob
import os
import re
def find_usb_tty(vendor_id = None, product_id = None) :
tty_devs = []
for dn in glob.glob('/sys/bus/usb/devices/*') :
try :
vid = int(open(os.path.join(dn, "idVendor" )).read().strip(), 16)
pid = int(open(os.path.join(dn, "idProduct")).read().strip(), 16)
if ((vendor_id is None) or (vid == vendor_id)) and ((product_id is None) or (pid == product_id)) :
dns = glob.glob(os.path.join(dn, os.path.basename(dn) + "*"))
for sdn in dns :
for fn in glob.glob(os.path.join(sdn, "*")) :
if re.search(r"\/ttyUSB[0-9]+$", fn) :
#tty_devs.append("/dev" + os.path.basename(fn))
tty_devs.append(os.path.join("/dev", os.path.basename(fn)))
pass
pass
pass
pass
except ( ValueError, TypeError, AttributeError, OSError, IOError ) :
pass
pass
return tty_devs
print find_usb_tty()
The best way to do this is would be to use libusb, but if that doesn't give you enough information about your devices (which it may not), then you'll have to use the /proc filesystem which the kernel makes available, specifically /proc/bus/usb/.
Have a read of this information on /proc/bus/usb: in particular on /proc/bus/usb/devices. But as you say, this is all a bit hacky!

Resources