Spresense SDK の Example を見ていると、いくつかのサンプルでスレッドを使っています。NuttX にはスレッドを生成する関数があるようです。



http://nuttx.org/Documentation/NuttxUserGuide.html#taskcreate

#include &ltsched.h>

int task_create(char *name, int priority, int stack_size, main_t entry, char * const argv[])


Input Parameters


name:The name of the new task


priority:The priority of the new task


stack_size:The size (in bytes) of the stack needed


entry:The entry point of a new task


argv:A pointer to an array of input parameters.
The array should be terminated with a NULL argv[] value.
If no parameters are required, argv may be NULL.




Returned Value


Returns the non-zero task ID of the new task
or ERROR if memory is insufficient or the task cannot be created (errno is not set).




これを使って SPRESENSE の四つのLEDをそれぞれのスレッドでコントロールするスケッチを書いてみました。



#include &ltsched.h> /*** for task_create **/
#include &ltstdlib.h> /*** for atoi ***/

#define MAXLOOP 60
static int gMainLoop = 0;

// Thread
static int led_thread(int argc, char* argv[]) {
if (argc != 4) {
Serial.println("Invalid argument number at led0_thread: " + String(argc));
return;
}

String func = String(argv[0]);
int led = atoi(argv[1]);
int durationH = atoi(argv[2]);
int durationL = atoi(argv[3]);

Serial.println("========================================");
Serial.println("Task name : " + func);
Serial.println("LED" + String(led) + " blink interval");
Serial.println("High duration: " + String(durationH) + " msec");
Serial.println("Low duration: " + String(durationL) + " msec");
Serial.println("========================================\n");

if (led > 3 || led < 0) {
Serial.println("Error: number of LED is " + String(led));
return -1;
}

int pin_num = 0;

switch(led) {
case 0: pin_num = LED0; break;
case 1: pin_num = LED1; break;
case 2: pin_num = LED2; break;
case 3: pin_num = LED3;
}

while (gMainLoop < MAXLOOP) {
digitalWrite(pin_num, HIGH);
usleep(durationH * 1000); // msec to usec
digitalWrite(pin_num, LOW);
usleep(durationL * 1000); // msec to usec
/* You cannot use "delay(msec)" because it is *
* a busywait that will not yield the process */
}

Serial.println("Exit " + func);
return 0;
}


void setup() {
char* param[4];
String str[3];
int i;

Serial.begin(115200);

pinMode(LED0, OUTPUT);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);

str[0] = String("0"); /* LED number */
str[1] = String("100"); /* LED HIGH duration in msec */
str[2] = String("200"); /* LED LOW duration in msec */
for (i = 0; i < 3; ++i) {
param[i] = str[i].c_str();
}
param[3] = NULL; // the last array must NULL terminatz
task_create("led0 thread", 130, 1024, led_thread, param);

str[0] = String("1"); /* LED number */
str[1] = String("200"); /* LED HIGH duration in msec */
str[2] = String("200"); /* LED LOW duration in msec */
for (i = 0; i < 3; ++i) {
param[i] = str[i].c_str();
}
param[3] = NULL; // the last array must NULL terminate
task_create("led1 thread", 130, 1024, led_thread, param);

str[0] = String("2"); /* LED number */
str[1] = String("500"); /* LED HIGH duration in msec */
str[2] = String("100"); /* LED LOW duration in msec */
for (i = 0; i < 3; ++i) {
param[i] = str[i].c_str();
}
param[3] = NULL; // the last array must NULL terminate
task_create("led2 thread", 130, 1024, led_thread, param);

str[0] = String("3"); /* LED number */
str[1] = String("100"); /* LED HIGH duration in msec */
str[2] = String("500"); /* LED LOW duration in msec */
for (i = 0; i < 3; ++i) {
param[i] = str[i].c_str();
}
param[3] = NULL; // the last array must NULL terminate
task_create("led3 thread", 130, 1024, led_thread, param);

}

void loop() {
++gMainLoop;
Serial.println("MainLoop: " + String(gMainLoop));
sleep(1);

if (gMainLoop >= MAXLOOP) {
sleep(1); // wait for the end of all processes
Serial.println("End of all processes");
while (1);
}
}


スケッチの中でも記述していますが、スレッド内で delay() を使うことはできないようです。どうも delay関数は、busy-wait のようなのでタスクを握って離しません。Spresense SDK のサンプルでも usleep を使っていますので、usleep を使うようにしましょう。

また、プライオリティは高いほど優先度が高いようです。肝心の loop 関数の優先度がよくわからないのが困りものですが、いろいろ試してみたら 120 位のようです。

動作の様子は地味なので動画にしてませんSPRESENSEを持っている方は試してみてくださいねー。
(^^)/~