October 6, 2016

A Kyu tutorial - A first example - blink an LED.

To run this example, download the code using the link above, rename it to user.c (replacing the user.c distributed with Kyu) and rebuild Kyu. This is how you add your code to Kyu, you provide your own user_init() function in the user.c file.

We could just do a printf of hello world that you could admire on the console, but that would be lame. So we will blink one of the user LED's instead using Kyu facilities. Here is the code.

#include <kyu.h>
#include <thread.h>

static struct thread *user_thread;
static int count;

static void
ticker ( void )
{
	++count;
	if ( count > 49 ) {
	    thr_unblock ( user_thread );
	    count = 0;
	}
}

void
user_init ( int xx )
{
	int led = 0;

	count = 0;
	user_thread = thr_self ();
	gpio_led_init ();
	timer_hookup ( ticker );

	for ( ;; ) {
	    thr_block ( WAIT );
	    gpio_led_set ( led );
	    led = (led+1) % 2;
	}
}
Observe the calls to gpio_led_init() and gpio_led_set() that initialize then manipulate the state of the LED. Then take note of the calls with a thr_ prefix. The call to thr_self() gets a handle for the current thread. Then thr_block() is called to block the current thread. The thread gets unblocked by the call to thr_unblock() in the "ticker" function. The ticker function is a timer callback that is connected to timer interrupts by the call to timer_hookup(). Once this is done, the ticker routine gets called (at interrupt level no less) at the timer rate (which is by default 1000 Hz). Every 50 ticks this routine will unblock the waiting thread, which then changes the state of the LED and blocks again.

For many, this may be a new way of thinking about things. The first thing to know is that blocking is your friend! The purpose of every thread is to block and wait for some event it is expected to act upon. When a thread blocks, the scheduler gets invoked and will try to find some other thread to run in the meanwhile. If there is none, it will go loose itself in the idle thread. This is much better than running a delay loop as is so often done, at least it is better if there are other threads that might want to be running.


Have any comments? Questions? Drop me a line!

Kyu / tom@mmto.org