基本ライブラリ
デジタルIO
アナログIO
拡張IO
時間
数学
三角関数
乱数
ビットバイト操作
割り込み
シリアル通信
標準ライブラリ
Ethernet
サーボモーター
ステッピングモーター
キャラクタ液晶表示
SPI通信
I2C通信(Wire)
SD
SD(File操作)
周期処理(MsTimer2)
時計(RTC)
PPG(パルス生成)
WiFiEsp
ICS(シリアルサーボ)
FreeRTOS Tips
FreeRTOS 割り込み管理
割り込みはOSのスケジューラが把握できないイベントです。このイベントをセマフォ(長さが1のキューのようなもの)によって、スケジューラがタスク管理できるようにします。
GR-ROSEのSDKにおける割り込み処理としては、attachInterruptによる外部割り込み、RTCライブラリによるアラーム割り込みがあります。これらの割り込みとタスクを結びつける場合にセマフォを使用します。
以下は、RTCライブラリのアラーム割り込みが発生したときに、それを通知するタスク処理の例です
#include <Arduino.h>
#include <RTC.h>
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
RTC rtc;
int g_year = 2019;
int g_mon = 5;
int g_day = 29;
int g_hour = 9;
int g_min = 20;
int g_sec = 55;
int g_week = RTC_WEEK_WEDNESDAY;
void rtcAlarmISR();
SemaphoreHandle_t xBinarySemaphore;
void vHandlerTask(void *pvParameters);
void vPeriodicTask(void *pvParameters);
void setup(){
Serial.begin(9600);
pinMode(PIN_LED1, OUTPUT); // led for alarm
digitalWrite(PIN_LED1, LOW); //turn off
rtc.begin();
rtc.setDateTime(g_year, g_mon, g_day, g_hour, g_min, g_sec, g_week);
rtc.attachAlarmHandler(rtcAlarmISR);
rtc.setAlarmTime(g_hour, g_min + 1, g_week);
rtc.alarmOn();
xBinarySemaphore = xSemaphoreCreateBinary();
xTaskCreate( vHandlerTask, "Handler", 512, NULL, 3, NULL );
xTaskCreate( vPeriodicTask, "Periodic", 512, NULL, 2, NULL );
}
void loop(){
delay(100); // entering Blocked State
}
void rtcAlarmISR()
{
xSemaphoreGiveFromISR( xBinarySemaphore, pdFALSE );
}
void vHandlerTask(void *pvParameters){
while(1){
xSemaphoreTake(xBinarySemaphore, portMAX_DELAY);
Serial.println("Got semaphore for alarm ");
digitalWrite(PIN_LED1, HIGH);// led for alarm
}
}
void vPeriodicTask(void *pvParameters){
while(1){
rtc.getDateTime(g_year, g_mon, g_day, g_hour, g_min, g_sec, g_week);
Serial.print(g_year, DEC);Serial.print("/");
Serial.print(g_mon, DEC); Serial.print("/");
Serial.print(g_day, DEC); Serial.print(" ");
Serial.print(g_hour, DEC); Serial.print(":");
Serial.print(g_min, DEC); Serial.print(":");
Serial.println(g_sec, DEC);
delay(1000);
}
}
出力結果:
2019/5/29 9:20:55
2019/5/29 9:20:56
2019/5/29 9:20:57
2019/5/29 9:20:58
2019/5/29 9:20:59
Got semaphore for alarm
2019/5/29 9:21:0
2019/5/29 9:21:1
上記の例で、アラーム割り込みは"rtcAlarmISR()"です。これはOSとして管理しておらず、この処理自身を長くするとOSのスケジューリングに影響を及ぼします。
アラーム割り込みではセマフォを"Give"するxSemaphoreGiveFromISR()のみ実行しています。タスク"vHandlerTask"の中でxSemaphoreTake()によってセマフォが"Take"できるまで待ちます。
このようにすることで、割り込み処理は最小限にし、OSのスケジューリングのもとでタスクを実行することができます。