Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
pthreadの実験(ESP-WROOM-32)

概要

Arduino core for the ESP32を使った、ESP-WROOM-32開発ボードのpthreadの実験です。マルチタスクとデュアルコアについての実験も併せてご覧ください。

Arduino core for the ESP32のインストールのページはこちら。

実験

pthread_create()

単純に、pthread_create()した後、pthread_join()するだけのものです。スレッドの中では、タスク名称とどのコアで動いているかを表示させてみました。

#include <pthread.h>

void *printThreadInfo(void *id) {
  Serial.printf("Thread %d(%s) runs on core %d\n", (int)id, pcTaskGetTaskName(NULL), xPortGetCoreID());

  return NULL;
}

void setup() {
  // put your setup code here, to run once:
  const int numThread = 10;
  pthread_t threads[numThread];
  int status;

  Serial.begin(115200);


  for (int i = 0; i < numThread; i++) {
    if (pthread_create(&threads[i], NULL, printThreadInfo, (void *)i)) {
      Serial.printf("Thread %d error.\n", i);
    }
  }

  for (int i = 0; i < numThread; i++) {
    if (pthread_join(threads[i], (void**)&status) == 0) {
      Serial.printf("Thread %d join success. status = %d\n", i, status);
    } else {
      Serial.printf("Thread %d join failure.\n", i);
    }
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

プログラムの実行結果は以下の通りです。タスクの名称は"pthread"となっていて、pthreadが実行されているコアは、適当に割り振られているようです。

https://github.com/espressif/esp-idf/blob/master/components/pthread/pthread.c に、pthread_create()のソースがあったので、見てみました。

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg)
{
    TaskHandle_t xHandle = NULL;

    ESP_LOGV(TAG, "%s", __FUNCTION__);
    if (attr) {
        ESP_LOGE(TAG, "%s: attrs not supported!", __FUNCTION__);
        return ENOSYS;
    }
    esp_pthread_task_arg_t *task_arg = malloc(sizeof(esp_pthread_task_arg_t));
    if (task_arg == NULL) {
        ESP_LOGE(TAG, "Failed to allocate task args!");
        return ENOMEM;
    }
    memset(task_arg, 0, sizeof(esp_pthread_task_arg_t));
    esp_pthread_t *pthread = malloc(sizeof(esp_pthread_t));
    if (pthread == NULL) {
        ESP_LOGE(TAG, "Failed to allocate pthread data!");
        free(task_arg);
        return ENOMEM;
    }
    memset(pthread, 0, sizeof(esp_pthread_t));
    task_arg->func = start_routine;
    task_arg->arg = arg;
    BaseType_t res = xTaskCreate(&pthread_task_func, "pthread", CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT,
        task_arg, CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT, &xHandle);
    if(res != pdPASS) {
        ESP_LOGE(TAG, "Failed to create task!");
        free(pthread);
        free(task_arg);
        if (res == errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY) {
            return ENOMEM;
        } else {
            return EAGAIN;
        }
    }
    pthread->handle = xHandle;

    if (xSemaphoreTake(s_threads_mux, portMAX_DELAY) != pdTRUE) {
        assert(false && "Failed to lock threads list!");
    }
    SLIST_INSERT_HEAD(&s_threads_list, pthread, list_node);
    xSemaphoreGive(s_threads_mux);

    // start task
    xTaskNotify(xHandle, 0, eNoAction);

    *thread = (pthread_t)pthread; // pointer value fit into pthread_t (uint32_t)

    ESP_LOGV(TAG, "Created task %x", (uint32_t)xHandle);

    return 0;
}

タスクは、xTaskCreate()を使って生成されており、タスク名称は固定で"pthread"となっていました。実験の結果通りです。

その他

pthead_exit()を使おうとしたところ、"undefined reference to `pthread_exit'" と言われてしまいました。

バージョン

Arduino 1.8.4/Arduino core for the ESP32/ESP-WROOM-32



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2018 garretlab all rights reserved.
inserted by FC2 system