# include "ch.h"
# include "hal.h"
# define CONSOLE_WA_SIZE		 THD_WORKING_AREA_SIZE(4096)
# define cputs(msg)			  chMsgSend(cdtp, (msg_t) msg)
static MUTEX_DECL(m1);
static thread_t * cdtp;
static THD_FUNCTION(console_thread, arg)
{
	(void) arg;
	while (!chThdShouldTerminateX())
	{
		thread_t * tp = chMsgWait();
		puts((char *) chMsgGet(tp));
		fflush(stdout);
		chMsgRelease(tp, MSG_OK);
	}
}
static THD_WORKING_AREA(waThread1, 1024);
static THD_FUNCTION(Thread1, arg)
{
	(void) arg;
	chRegSetThreadName("green");
	while (TRUE)
	{
		chMtxLock(&m1);
		cputs("green on");
		chThdSleepMilliseconds(1000);
		cputs("green off");
		chMtxUnlock(&m1);
	}
}
static THD_WORKING_AREA(waThread2, 1024);
static THD_FUNCTION(Thread2, arg)
{
	(void) arg;
	chRegSetThreadName("yellow");
	while (TRUE)
	{
		chMtxLock(&m1);
		cputs("yellow on");
		chThdSleepMilliseconds(1000);
		cputs("yellow off");
		chMtxUnlock(&m1);
	}
}
static THD_WORKING_AREA(waThread3, 1024);
static THD_FUNCTION(Thread3, arg)
{
	(void) arg;
	chRegSetThreadName("red");
	while (TRUE)
	{
		chMtxLock(&m1);
		cputs("red on");
		chThdSleepMilliseconds(1000);
		cputs("red off");
		chMtxUnlock(&m1);
	}
}
int main(void)
{
	halInit();
	chSysInit();
	chMtxObjectInit(&m1);
	cdtp = chThdCreateFromHeap(NULL, CONSOLE_WA_SIZE, NORMALPRIO, console_thread, NULL);
	chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 1, Thread1, NULL);
	chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO + 1, Thread2, NULL);
	chThdCreateStatic(waThread3, sizeof(waThread3), NORMALPRIO + 1, Thread3, NULL);
	while (!chThdShouldTerminateX())
	{
		chThdSleepMilliseconds(990);
	}
	return 0;
}