How to create timer inside a thread


#1

Hi,

I have a thread that poll events on a GPIO.
Depending the value of the GPIO I want to start or stop a timer.

Unfortunately my timer is never started / stopped even if the le_timer_Start/Stop returns 0.

Here is the code of my thread:

void* adxl_intHandler(void* context) {
	unsigned char value;
	struct pollfd fdset[1];
	int nfds = 1;
	int gpio_fd, timeout, rc;
	unsigned int gpio = 9;

	le_clk_Time_t clk = { .sec = 0, .usec = 100000 };
	le_timer_Ref_t adxlPollingTimer = le_timer_Create("ADXL_TIMER");
	le_timer_SetRepeat(adxlPollingTimer, 0);
	le_timer_SetInterval(adxlPollingTimer, clk);
	le_timer_SetHandler(adxlPollingTimer, tmrHandler);

	gpio_export(gpio);
	gpio_set_dir(gpio, GPIO_IN);
	gpio_set_edge(gpio, GPIO_EDGE_RISING);
	gpio_fd = gpio_fd_open(gpio);

	memset((void*) fdset, 0, sizeof(fdset));

	fdset[0].fd = gpio_fd;
	fdset[0].events = POLLPRI;
	timeout = 100;

	while (1) {
		rc = poll(fdset, nfds, timeout);
		if (rc < 0) {
			printf("\npoll() failed!\n");
		}
		if (fdset[0].revents & POLLPRI) {
			char buf[64];
			int res =-1 ;
			read(fdset[0].fd, buf, 64);
			adxl_read_register(0x30, &value);
			if (value & 0x08) {
				printf("**stop detected\n");
				res = le_timer_Stop(adxlPollingTimer);
			}
			else if (value & 0x10) {
				printf("**start detected\n");
				res = le_timer_Start(adxlPollingTimer);
			}
			printf("timer start/stop status: %d\n", res);
		}
	}
	return NULL;
}

and the (very complex ) code of my timer’s handler:

static void tmrHandler(le_timer_Ref_t timerRef) {
	printf("INSIDE TIMER\n");
}

And here the result of the execution of my app:

As you can see, the “INSIDE TIMER” log is never printed

Note: I deliberately use printf instead of LE_DEBUG for this kind of debug in order to not miss any logs.

Thanks for your help

David


#2

Here is legato traces with timers traces enables

[quote]
08:58:22 timers | AccelerometerEXE[22709]/framework T=ADXL_INT_POLLER | timer.c le_timer_Start() 730 | Starting timer 'ADXL_TIMER’
08:58:22 DBUG | AccelerometerEXE[22709]/framework T=ADXL_INT_POLLER | timer.c le_timer_Start() 742 | threadRecPtr->timerFD=-1
08:58:22 DBUG | AccelerometerEXE[22709]/framework T=ADXL_INT_POLLER | timer.c le_timer_Start() 750 | threadRecPtr->timerFD=12
08:58:22 timers | AccelerometerEXE[22709]/framework T=ADXL_INT_POLLER | timer.c RestartTimerFD() 309 | timer ‘ADXL_TIMER’ started
08:58:27 timers | AccelerometerEXE[22709]/framework T=ADXL_INT_POLLER | timer.c le_timer_Stop() 821 | Stopping the first active timer
08:58:27 timers | AccelerometerEXE[22709]/framework T=ADXL_INT_POLLER | timer.c le_timer_Stop() 842 | timerFD=12 stopped[/quote]


#3

Hi, David,

The Legato Timer API is integrated with the Legato Event Loop. Your thread is not running the Legato Event Loop, so the timer expiry never gets handled.

You can fix this in either of two ways:
[ul]
[li] Instead of using your own loop, with poll(), use the Legato event loop by calling le_event_RunLoop() in your thread.[/li]
[li] Use le_event_GetFd() to fetch an event loop file descriptor that will become “ready to read” (POLLIN) when there’s something that the Legato event loop needs to process, and then call le_event_ServiceLoop() when the event loop fd becomes ready to read.[/li][/ul]

Cheers,

–Jen