Lightweight Cooperative Multitasking in C

I found this MSDN article quite interesting, it was one of those things that I wanted to try out for myself, just to see what was going on. For some reason, I decided to port the example code shown in the article to C, so here is the result:

// A working C example of the code described in the article here:
// http://msdn.microsoft.com/en-us/magazine/jj553509.aspx

#include <stdio.h>

#define task_begin(name, parameter)      \
                                         \
char name(parameter)                     \
{                                        \
  char yield_ = 0;                       \
  switch (args->task_)                   \
  {                                      \
    case 0:

#define task_end                         \
                                         \
    }                                    \
    args->task_ = 0;                     \
    return 0;                            \
  }

#define task_wait_until(expression)      \
                                         \
  args->task_ = __LINE__; case __LINE__: \
  if (!(expression))                     \
  {                                      \
    return 1;                            \
  }

#define task_return()                    \
                                         \
  args->task_ = 0;                       \
  return 0;

#define task_wait_while(expression)      \
                                         \
  task_wait_until(!(expression))
#define task_wait_for(name, parameter)   \
                                         \
  task_wait_while(name(parameter))

#define task_yield_until(expression)     \
                                         \
  yield_ = 1;                            \
  args->task_ = __LINE__; case __LINE__: \
  if (yield_ || !(expression))           \
  {                                      \
    return 1;                            \
  }
#define task_yield()                     \
                                         \
  task_yield_until(1)

typedef struct input_args
{
  int *target;
  int task_;
} input_args;

typedef struct average_args
{
  int *source;
  int sum;
  int count;
  int average;
  int task_;
} average_args;

task_begin(input, input_args *args)
{
  for (;;)
  {
    printf("number: ");
    if (!scanf_s("%d", args->target))
    {
      task_return();
    }
    task_yield();
  }
}
task_end

task_begin(average, average_args *args)
{
  args->sum = 0;
  args->count = 0;
  args->average = 0;
  for (;;)
  {
    args->sum += *args->source;
    ++args->count;
    args->average = args->sum / args->count;
    task_yield();
  }
}
task_end

int main()
{
  int share = -1;
  average_args aa = { &share };
  input_args ia = { &share };

  while (input(&ia))
  {
    average(&aa);
    printf("sum=%d count=%d average=%d\n", aa.sum, aa.count, aa.average);
  }
  return 0;
}

I hope that I got it right ;-) I didn't spend very much time on it. But I thought that somebody else might find it interesting, or maybe I'd want to come back to it at some point. So I thought that I'd post it... just in case.

Using libpigpio in Mono with C#

UPDATE: you'll probably need to recompile the library from source, read here for instructions.

So, here are some instructions for using libpigpio, the shared GPIO library for the Raspberry Pi in a C# program. First, get libpigpio by downloading it from here.

Unzip it and copy the file called libpigpio.so to the /lib folder on your Raspberry Pi. You'll need elevated privileges to do that, so you'll probably type something like:

sudo cp libpigpio.so /lib.

Alternatively, you could compile the library yourself by copying the libpigpio.c file to the Raspberry Pi and using the commands listed inside the file to compile and copy it to /lib.

Once libpigpio.so is in the /lib folder the library is installed and ready to use. We can now begin programming in C#. I'm using MonoDevelop on another machine, I expect you'd probably do something similar. Create your new C# project, and add the RpiGpio class found in RpiGpio.cs or just copy and paste the code from my previous blog entry. This is the wrapper that allows the shared library to be used in C#. Now we can write some C# code to access the GPIO.

This is an example test program:

using System;
using System.Threading;
 
using LibPiGpio;
 
namespace RPiBlinky
{
    class Program
    {
        static void Main(string[] args)
        {
            int inc = 1, t = 7, last = 0;
            RpiGpio.SetOutputPins(new[] { 7, 8, 9, 10, 11 });
 
            while (!Console.KeyAvailable)
            {
                if (last != 0)
                {
                    t = t + inc;
                    if (t >= 11 || t <= 7) inc *= -1;
                    RpiGpio.Pins[last] = false;
                }
                RpiGpio.Pins[t] = true;
                last = t;
                Thread.Sleep(250);
            }
            Console.ReadKey();
        }
    }
}

If you want to test your code, you can uncomment the #define NOPI in RpiGpio.cs, which will allow you to run the code on something other than a Raspberry Pi. For example, here is the test program running like that on my virtual machine:

When you're happy with your code (making sure that you've re-commented the #define in RpiGpio.cs) simply copy the compiled C# executable to your Raspberry Pi and run it like this:

sudo mono GPIOtest.exe.

But replace GPIOtest.exe with the name of your Mono executable. You'll need to use sudo for the program to have enough permission to access the GPIO. That's it! It's quite a simple process really.

Please check everything I've said, you can't hold me responsible if you break your own stuff. Always double check your electronic connections, that will help you not to break stuff too. It's always best to check the source code and compile it yourself before you use it. But have fun, it's good to build stuff.

A simple DALIS server

A while back I wrote a simple web server and said that I could turn it into a DALIS server that would run outside of IIS. Well that's exactly what I did, take a look at this YouTube clip I've made:

In this clip I'm showing two instances of the same program running (one in IE the other in Chrome). Each program shows a kindof bouncing ball thingy in ASCII Art. This is not the kind of thing that I designed DALIS to do of course, but who cares. In the background you can see the DALIS server runnng as a console app. I've made it so that each thread servicing a web request shows up like a blinking light. This means you can see it is working - and you can tell that I still like blinking LEDs on things. Ahh, do you remember the days when you used to see blinky LEDs on the front of your modem? Good times, eh?

So anyway... whilst I have not said much about the DALIS progaming language recently, development has continued on background threads :-) I have added a few more features to the language. I have also tried to think of a better name for it, but DALIS has kinda stuck now. One day I might have the guts to tell everyone what DALIS stands for, or maybe not.

DALIS User Input

As I have mentioned before, I have been adding User Input to my new programming language, codenamed DALIS.  Because the language is designed to work in a request / response environment I wanted the language to reflect that without getting over complicated.  So this is what I have got at the moment:

WRITE "Welcome to another DALIS program."+RETURN
ASK "Type your name and press ENTER: "
name = ANSWER
IF name="Dave"
   WRITE RETURN+"Good morning Dave."
OTHERWISE
   WRITE RETURN+"Hello "+name+"."
END

The ASK ... ANSWER syntax looks pretty straightforward to me.  If I run this program, this is what happens:

Starting the program

Then I put in a name:

Entering a name

Finally, this is the end result:

The result

It seems to work fine.  Simple code which even runs on my phone.  I also have a plan to enable forms, so that you can submit several values at once.  That is for another day though...