#環境
- PSoC Creator 4.2
- FreeRTOS 10.2.1
- PSoC5LP Prototyping Kit
プロジェクトを作る
PSoC Creatorを立ち上げ、File->New->Projectよりプロジェクトを作る。
デバイスは今回用いるCY8C5888LTI-LP097を選択。
テンプレートは空っぽのemptyを選択。
わかりやすい名前とディレクトリを指定してFinishする。
FreeRTOSを導入する
ダウンロード
FreeRTOSよりダウンロードできる。
2019/6/10時点で最新verは10.2.1。
zipとexeがあるが今回はzipを選択。
##導入
zipを解凍すると、いくつかのフォルダが生成される。このうち、Demoフォルダは各マイコン用のデモフォルダ、Licenseはライセンスが入っている。今回使用するSourceだけをプロジェクトのディレクトリへコピーする。
##PSoC Creatorへリンク
まずわかりやすいように、デザイン内にFreeRTOS用のフォルダを生成する。
コピーしたファイルをこのフォルダ内にリンクしていく。
必要なものを列挙すると、
- FreeRTOS/Source/下の.Cソースファイル
- FreeRTOS/include下のヘッダーファイル
- FreeRTOS/portable/MemMangのheap.cファイルどれかひとつ
- FreeRTOS/portable/GCC/ARM_CM3のソースファイル・ヘッダーファイル
をそれぞれHeader FilesとSource Filesにドラッグアンドドロップでリンクする。
FreeRTOSコンフィグファイルの作成
FreeRTOSの設定用ヘッダファイルを作成する。
解凍してできたFreeRTOS/Demo/CORTEX_CY8C5588_PSoC_Creator_GCC/FreeRTOS_Demo.cydsnディレクトリの、FreeRTOSConfig.hとdevice.hをコピーして持ってくるのが早い。
FreeRTOSConfig.hはFreeRTOSの設定ファイル、device.hはproject.hのラッパーになっている。筆者の場合めんどくさかったのでdevice.hはコピーしてこないでFreeRTOSConfig.h内の記述をいじって直接project.hをインクルードする形にした。
コピーしてきたら忘れずにPSoC Creatorにリンクしておく。
PSoC Creatorにインクルードパスを指定する
PSoC CreatorメニューバーのProject->Build SettingよりARM_GCC~->Compiler->GeneralのAdditional Include DirectoriesにFreeRTOSのヘッダファイルが存在するディレクトリを指定してやる。
portable/GCC/ARM_CM3が忘れやすいので注意すること。
以上でFreeRTOSの最低限の導入はおしまい。
Lチカする
##Top Design/Pinアサイン
今回はただのLチカなのでDigital Outputピンを一つ置くだけ。
ピンアサインは開発ボードのユーザーLEDとつながっている2.1ピンを指定する。
##プログラム
プログラムは以下のようになる。
#include "project.h"
#include "FreeRTOS.h"
#include "task.h"
void vTestTask1();//タスクとして走らせる関数
void vTestTask2();
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
//FreeRTOS用の割り込み周りの初期設定。この処理をしないと動かない。
extern void xPortPendSVHandler( void );
extern void xPortSysTickHandler( void );
extern void vPortSVCHandler( void );
extern cyisraddress CyRamVectors[];
CyRamVectors[ 11 ] = ( cyisraddress ) vPortSVCHandler;
CyRamVectors[ 14 ] = ( cyisraddress ) xPortPendSVHandler;
CyRamVectors[ 15 ] = ( cyisraddress ) xPortSysTickHandler;
//タスクを生成
xTaskCreate(vTestTask1,"test1",100,NULL,3,NULL);
xTaskCreate(vTestTask2,"test2",100,NULL,3,NULL);
//スケジューラを起動
vTaskStartScheduler();
for(;;)
{
/* Place your application code here. */
}
}
//LEDを点灯させるタスク
void vTestTask1(){
for(;;){
vTaskDelay(1000);
LED_1_Write(1);
}
}
//LEDを消灯させるタスク
void vTestTask2(){
vTaskDelay(500);
for(;;){
vTaskDelay(1000);
LED_1_Write(0);
}
}
//オーバーフローが起こった際のハンドラ
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
/* The stack space has been execeeded for a task, considering allocating more. */
taskDISABLE_INTERRUPTS();
}/*---------------------------------------------------------------------------*/
//メモリの確保に失敗したときのハンドラ
void vApplicationMallocFailedHook( void )
{
/* The heap space has been execeeded. */
taskDISABLE_INTERRUPTS();
}
FreeRTOSは、タスクとして走らせる関数を、xTaskCreate();
関数で指定してタスクを生成し、vTaskStartScheduler();
関数でスケジューラを起動することによって、生成されたタスクを走らせることができる。
xTaskCreate();
関数の引数は1項目から、走らせる関数、タスク名、スタックサイズ、タスクに渡す引数、優先度、タスクのIDになっている。
今回はtestTask1でLEDを点灯させ、testTask2で消灯させるようなプログラムにした。testTask2の方は500msのディレイを入れているので、1HzのLチカになっているはずだが、同期をとっていないのでズレる可能性もある。
無事コンパイルが通り書き込みに成功すれば、0.5秒ごとにLEDがチカチカするはず。
このLチカはFreeRTOSの(たぶん)最小構成なので、他の機能を試したい場合はデモが参考になる。