1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FreeRTOSをVScode環境で動かす②CMSIS_RTOSラッパーを被せる

Posted at

FreeRTOSをVScode環境で動かす①環境構築 の続きです。

概要

以前紹介した記事でFreeRTOSを用いてWindowsPC上で2つのタスクを実行する環境を作成しました。
もともとやりたかった事として、ARMマイコン用ファームの予備検証環境をWindowsで構築する という前提があります。

具体的に何のARMマイコンなの?

STマイクロ製ARM cortexF7 シリーズをターゲットとしています。

ここで、

STマイクロのマイコンでRTOSを動かしたい場合は APIを CMSIS_RTOS に合わせておく という制約があります。

今回はCMSIS_RTOSのラッパーを被せていく作業を紹介します。
(CMSIS_RTOSが何者なのかは他のが詳しく紹介記事を書かれているので割愛します)

使用する機能

CMSISの全ての機能を使用するとエラー等が出てきたりして、初心者には苦しい状況になるかと思います。。。
今回は最低限の機能だけ使用して、動作する状況を作っていきたいと思います。

有効にする構造体など

  • enum
    • osPriority
    • osStatus
  • typedef
    • os_pthread
    • TaskHandle_t
  • struct
    • osThreadDef_t

使用するカーネルコントロール関数

CMSIS_RTOS関数名 機能
osKernelInitialize スケジューラーの初期化
osKernelStart スケジューラーの起動
osKernelRunning スケジューラーが動作中か否かの判定

使用するスレッドマネージメント関数

CMSIS_RTOS関数名 機能
osThreadCreate  スレッドをスケジューラーに登録
osThreadGetId 実行中のスレッドIDの取得
osThreadTerminate スレッドの停止

使用するウェイト関連関数

CMSIS_RTOS関数名 機能
osDelay 指定時間だけ待つ
osDelayUntil 基準時刻から指定した時間だけ待つ

コンフィグヘッダの設定

プライオリティの設定を7にします

FreeRTOSConfig.h
# define configMAX_PRIORITIES					(7)

理由は cmsis_os.h の中でプライオリティの設定が↓の通り、7段階定義されているため、これに合わせる必要があります。

cmsis_os.h
typedef enum  {
  osPriorityIdle          = -3,          ///< priority: idle (lowest)
  osPriorityLow           = -2,          ///< priority: low
  osPriorityBelowNormal   = -1,          ///< priority: below normal
  osPriorityNormal        =  0,          ///< priority: normal (default)
  osPriorityAboveNormal   = +1,          ///< priority: above normal
  osPriorityHigh          = +2,          ///< priority: high
  osPriorityRealtime      = +3,          ///< priority: realtime (highest)
  osPriorityError         =  0x84        ///< system cannot determine priority or thread has illegal priority
} osPriority;

ユーザー関数

参考までに私の作った関数を紹介します。

  • タスクは2つ
  • task1は1秒周期でprint
  • task1は2秒周期でprint
  • 5週したらtask停止
main.c
# include "UserTaskDef.h"
# include <stdio.h>
//===================================================================
//
//===================================================================
int main(){
	if( 0 == TaskInit() ){
		printf("task initialize OK\n");
	}else{
		printf("task initialize ON!!!!!!\n");
	};
	 /* Start scheduler */
	UserTaskStart();

	while (1)
	{
	}
}
UserTaskDef.h
# ifndef _DUMMY_TASK_H_
# define _DUMMY_TASK_H_

int TaskInit(void);
void UserTaskStart();

# endif  // include gurde
UserTaskDef.c
# include "cmsis_os.h"
# include "UserTaskDef.h"
# include <stdio.h>

//--------------------------------------------------------
// static functions
//--------------------------------------------------------
static void dummyTask1Func(void const *arg);
static void dummyTask2Func(void const *arg);
static osThreadId 			taskHandle1;
static osThreadId 			taskHandle2;

//--------------------------------------------------------
// task Definition
//--------------------------------------------------------
//          Task Name     Entry Function    Priority         instance   Stack Size
osThreadDef(dummyTask1   ,dummyTask1Func   ,osPriorityHigh  , 0       , 0x800);
osThreadDef(dummyTask2   ,dummyTask2Func   ,osPriorityHigh  , 0       , 0x800);

//--------------------------------------------------------
// task Registration
//--------------------------------------------------------
int TaskInit(void){
    if( 1 == osKernelRunning() ){
        return 1;//error
    }

    taskHandle1 = osThreadCreate(osThread(dummyTask1), NULL);
    taskHandle2 = osThreadCreate(osThread(dummyTask2), NULL);
    return 0;//
}
//--------------------------------------------------------
// task Start
//--------------------------------------------------------
void UserTaskStart(){
    if( 0 == osKernelRunning() ){
        osKernelStart();
	}
}
//--------------------------------------------------------
// task1
//--------------------------------------------------------
static void dummyTask1Func(void const *arg){
  uint32_t PreviousWakeTime;
	for(int i=0; i<5; i++){
		printf("dummy_task1\n");
    	osDelayUntil(&PreviousWakeTime , 1000);//1秒周期
	}
  osThreadTerminate(taskHandle1);//タスク停止
}
//--------------------------------------------------------
// task2
//--------------------------------------------------------
static void dummyTask2Func(void const *arg){
  uint32_t PreviousWakeTime;
	for(int i=0; i<5; i++){
		printf("           dummy_task2\n");
    	osDelayUntil(&PreviousWakeTime , 2000);//2秒周期
	}
  osThreadTerminate(taskHandle2);
}
//--------------------------------------------------------
//
//--------------------------------------------------------
void vApplicationMallocFailedHook( void ){
	/* vApplicationMallocFailedHook() will only be called if
	configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
	function that will get called if a call to pvPortMalloc() fails.
	pvPortMalloc() is called internally by the kernel whenever a task, queue,
	timer or semaphore is created.  It is also called by various parts of the
	demo application.  If heap_1.c, heap_2.c or heap_4.c is being used, then the
	size of the	heap available to pvPortMalloc() is defined by
	configTOTAL_HEAP_SIZE in FreeRTOSConfig.h, and the xPortGetFreeHeapSize()
	API function can be used to query the size of free heap space that remains
	(although it does not provide information on how the remaining heap might be
	fragmented).  See http://www.freertos.org/a00111.html for more
	information. */
	vAssertCalled( __LINE__, __FILE__ );
}

動作結果

image.png

  • 2つのタスクが平行して走っていることが確認できました。
  • task1の終了と同時にプログラム全体が停止しました。
  • task1の終了後もtask2が5回呼ばれてからプログラム全体が終了を期待していたのですが。。。

今後の課題

ここまでで windowsPC上でFreeRTOSにCMSIS_OSラッパーを被せて動作確認ができました。
次はARMマイコンとのクロスコンパイル環境の構築を目指てみます。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?