Re: [Q] Frequency & duty cycle measurement?

From: Csókás Bence
Date: Wed Feb 05 2025 - 04:30:53 EST


Hi,

On 2025. 02. 05. 0:37, William Breathitt Gray wrote:
Are you still having trouble with this? Is "X" the
capture{0,1}_component_id value?

X is 0/1 from `/sys/bus/counter/devices/counter0/count0/capture{0,1}`, which is also equal to the respective `capture{0,1}_component_id`, since I don't have any other counters. I checked that beforehand.

I apologize, the Generic Counter character device interface is
underdocumented so it can be a bit confusing at first; I'll submit a
patch improving the documentation later this cycle when I get a chance.
For now, let's walk through how to create an appropriate Counter watch
for the capture extension components you have.

After much tinkering and reading of the `counter-chrdev.c` code, I now see *something*, although it's much slower to make a measurement than the sysfs `reopen()` hack.

The first step is to decide which event we'll monitor and on which
channel: we want to monitor Capture events so that's
COUNTER_EVENT_CAPTURE, and we want event channel 0 (n.b. 0 because
that's the channel parameter value passed to counter_push_event() in the
driver).

The next step is to choose the components you wish to watch: Count 0's
capture0 and capture1 extensions. So type is COUNTER_COMPONENT_EXTENSION
because we want to watch extensions, scope is COUNTER_SCOPE_COUNT
because we want Count extensions, and parent is 0 because we want
Count 0's Count extensions.

Finally, we need to set the component id for each extension. You get a
particular component's id by reading the respective *_component_id sysfs
attribute: so for capture{0,1} you would read capture{0,1}_component_id
respectively. These component id values potentially can change with
future driver updates, so for robustness your userspace application
should read the respective *_component_id sysfs attribute itself rather
than hardcoding the component id in the Counter watch.

However, for the sake of simplicity in this example, I'll assume the
component ids are 42 and 43 respectively for capture0 and capture1. That
gives us the following two watches:

{
.component.type = COUNTER_COMPONENT_EXTENSION,
.component.scope = COUNTER_SCOPE_COUNT,
.component.parent = 0,
.component.id = 42,
.event = COUNTER_EVENT_CAPTURE,
.channel = 0,
},
{
.component.type = COUNTER_COMPONENT_EXTENSION,
.component.scope = COUNTER_SCOPE_COUNT,
.component.parent = 0,
.component.id = 43,
.event = COUNTER_EVENT_CAPTURE,
.channel = 0,
},

Does this resolve your chardev read issue? If you're still having
troubling, just let me know and we can troubleshoot further to figure
out what's going on.

I had no success using `channel = 0`, only data from `capture0` comes back. If I set both `channel` AND `component.id` to X, then I start to see similar values than what I get from reading sysfs. (For now I hard-coded all values; I agree that the correct way would be to read component IDs from sysfs, but this is still a PoC...)

Did I do something wrong in implementing the driver maybe? (See the submitted patches.) And any idea as to why I might be seeing the slowdown?

Bence