2020年1月19日日曜日

PSoC5LPでFreeRTOSを動かす。

今回はPSoC5LPでFreeRTOS V10を動かすことを行った。
以前はCypressのアプリケーションノートの中にFreeRTOSへ適用の仕方が書かれていたと記憶していた。今回調べたところ、アプリケーションノートがそのものがサイト等から消えてしまっていた。FreeRTOSのサイトにはPSoC5LPのサンプルコードがあるため、それをたたき台としてFreeRTOS V10をPSoC5LPへ適用することとした。
 サンプルコードは余計な内容が書かれていた。このままの状態では動作ができないので動作に必要となるコードを取り出して、適用することとした。必須となるスーパーバイザーコールとシスティックの部分はmain.c内に書かれていたので、新しい適用もこれに沿えば大丈夫だと思われる。使い方はスレッドスタートやタスクの登録以前に実行する。
下記はスーパーバイザーコールとシスティックのプログラム部分となる。
extern void xPortPendSVHandler( void );
extern void xPortSysTickHandler( void );
extern void vPortSVCHandler( void );
extern cyisraddress CyRamVectors[];

/* Install the OS Interrupt Handlers. */
CyRamVectors[ 11 ] = ( cyisraddress ) vPortSVCHandler;
CyRamVectors[ 14 ] = ( cyisraddress ) xPortPendSVHandler;
CyRamVectors[ 15 ] = ( cyisraddress ) xPortSysTickHandler;

あとはFreeRTOSでダウンロードしたソースファイルからCortexM3用のFreeRTOSデータをまとめれば、FreeRTOSに必要なデータがそろう。注意が必要な点はportableディレクトリ内のデータとなる。このディレクトリはCPUのコアとコンパイラ毎に異なったシスティックのプログラムとスーパーバイザーコールのプログラムが保存されている。さらにFreeRTOSが使うメモリー管理アルゴリズムのプログラムもここに格納されている。システィックのプログラムとスーパーバイザーコールのプログラムが書かれたファイルは、すべて同じファイル名となっている。つまり、ファイルの操作を間違えるとプログラムが変質することになる。
下記は今回参照したファイルのディレクトリ構造
FrerRTOSv10.2.1
┣FreeRTOS
┃┣Demo(MCUごとに作られたデモプログラムの一式)
┃┣License
┃┗Source(FreeRTOSの本体)
┃ ┣include
┃ ┗portable
┃  ┣MemMang(heap_1 heap_2 heap_3 heap_4 heap_5のいずれかが必要)
┃  ┣GCC
┃  ┃┣ARM_CM3(port.c portmacro.hがある。)
┃  ┃┗そのほかのCPU用ディレクトリ
┃  ┗そのほかのコンパイラ用ディレクトリ
┗FreeRTOS+Plus

下記はFreeRTOSのソースファイルから構成したファイル
freertos
┣inc
┃┗


┣src
┃┗

freeRTOSConfig.h

構成したソースファイルはエクステンディングアイテムを用いてPSoCCreatorに導入した。ビルドはFreeRTOSを入れたのでそれらを参照できるように設定を行った。

動作確認はLEDの点滅を行った。下記はそのプログラムとなる。
#include "project.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

void vLEDtask();
xTaskHandle xLEDtask;
uint8_t ucParameterLED;

int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    /* Port layer functions that need to be copied into the vector table. */

    extern void xPortPendSVHandler( void );
    extern void xPortSysTickHandler( void );
    extern void vPortSVCHandler( void );
    extern cyisraddress CyRamVectors[];

/* Install the OS Interrupt Handlers. */
CyRamVectors[ 11 ] = ( cyisraddress ) vPortSVCHandler;
CyRamVectors[ 14 ] = ( cyisraddress ) xPortPendSVHandler;
CyRamVectors[ 15 ] = ( cyisraddress ) xPortSysTickHandler;
 
    xTaskCreate(vLEDtask,"ledtask",configMINIMAL_STACK_SIZE,&ucParameterLED,tskIDLE_PRIORITY + 1,&xLEDtask);
 
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
 
    vTaskStartScheduler();
    for(;;)
    {
        /* Place your application code here. */
    }
}

void vLEDtask()
{

    for(;;)
    {
        Pin_1_Write(1);
        vTaskDelay(250);
        Pin_1_Write(0);
        vTaskDelay(250);
    }
}

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
/* The stack space has been execeeded for a task, considering allocating more. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*---------------------------------------------------------------------------*/

void vApplicationMallocFailedHook( void )
{
/* The heap space has been execeeded. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*---------------------------------------------------------------------------*/



PSoC5LPはPSoC6で使われているPDLが使われていない。PLDがあるとFreeRTOSの適用が楽なのだが、それらしいオプションも見当たらなかった。PSoC5LPでFreeRTOSの開発を進める場合はこれを参照に進めればよいと思われる。

0 件のコメント:

コメントを投稿