Tool/software:
Hi,
We are developing the device using am62x with processor SDK 09.02.01.10.
Is there a way to monitor events emitted by eQEP e.g. COUNTER_EVENT_OVERFLOW, COUNTER_EVENT_UNDERFLOW?
According to the following page, this is possible by using COUNTER_ADD_WATCH_IOCTL.
https://docs.kernel.org/driver-api/generic-counter.html#userspace
When I tried to get an OVERFLOW event using tools/counter/counter_example.c in linux-ti-staging, the kernel was unable to read the event and displayed the following message.
"Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010"
If you have any advice or ideas please let me know.
The source code for counter_example.c is attached.
// SPDX-License-Identifier: GPL-2.0-only
/* Counter - example userspace application
*
* The userspace application opens /dev/counter0, configures the
* COUNTER_EVENT_INDEX event channel 0 to gather Count 0 count and Count
* 1 count, and prints out the data as it becomes available on the
* character device node.
*
* Copyright (C) 2021 William Breathitt Gray
*/
#include <errno.h>
#include <fcntl.h>
#include <linux/counter.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <poll.h>
static struct counter_watch watches[1] = {
{
/* Component data: Count 0 count */
.component.type = COUNTER_COMPONENT_COUNT,
.component.scope = COUNTER_SCOPE_COUNT,
.component.parent = 0,
/* Event type: overflow */
.event = COUNTER_EVENT_OVERFLOW,
/* Device event channel 0 */
.channel = 0,
},
};
int main(void)
{
int fd;
int ret;
int i;
struct counter_event event_data[1];
fd = open("/dev/counter0", O_RDWR);
if (fd == -1) {
perror("Unable to open /dev/counter0");
return 1;
}
for (i = 0; i < 1; i++) {
ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + i);
if (ret == -1) {
fprintf(stderr, "Error adding watches[%d]: %s\n", i,
strerror(errno));
return 1;
}
}
ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
if (ret == -1) {
perror("Error enabling events");
return 1;
}
struct pollfd fds = {
.fd = fd,
.events = POLLIN,
};
for (;;) {
printf("polling\n");
int ret = poll(&fds, 1, -1);
if (ret >= 1) {
printf("read start\n");
ret = read(fd, event_data, sizeof(event_data));
printf("read end\n");
if (ret == -1) {
perror("Failed to read event data");
return 1;
}
if (ret != sizeof(event_data)) {
fprintf(stderr, "Failed to read event data\n");
return -EIO;
}
printf("Timestamp 0: %llu\tCount 0: %llu\n"
"Error Message 0: %s\n",
event_data[0].timestamp, event_data[0].value,
strerror(event_data[0].status));
} else {
perror("poll()");
close(fd);
return -1;
}
}
return 0;
}
Best regards,
Takayuki