PSoC 6 のデュアルコアでLチカ (1)


これは、PSoC Advent Calendar 2017の1日目に突っ込まれた記事です。

CPUが二つ入ったPSoC 6

さきごろ発表されたPSoC 6には、Cortex-M4Cortec-M0+の二つのCPUが搭載されています。この記事では、二つのCPUを駆使したプログラムを使い、Lチカを行います。

CPUサブシステムの構成

PSoC 6には、CPUとCPUに近いモジュールから構成されるCPUサブシステムと呼ばれるブロックがあります。

二つのCPUコアは、FlashやRAMと共に単一のバスに接続されています。このため、メモリとすべての周辺モジュールは、どちらのCPUからも平等にアクセス可能です。なんと公平なんでしょう。
反面、すべてのリソースをユーザ側のソフトウェアで割り振る必要があるので、それなりのソフトウェア技量が必要になってしまいます。

ハードウェアはCY8CKIT-062-BLE

ここで使用されるハードウェアは、PSoC® 6 BLE Pioneer Kit CY8CKIT-062-BLEです。

この評価ボード上のLEDを点滅(Lチカ)させます。

プロジェクトを作ります。

すでに、ソフトウェアでLチカするプロジェクトの作り方とプログラムの方法は、PSoC 6 Pioneer Kit で、Lチカしてみる (1)で紹介されています。そこで、この記事では、ソフトウェアのみについて言及します。

最初は、Cortex-M0+で実行されるプログラムです。

main_cm0p.c
#include "project.h"

int main(void)
{
    __enable_irq(); /* 全体の割り込みを許可する */
    /* Cortex-M4 を叩き起こして CY_CORTEX_M4_APPL_ADDR から実行させる。 */
    Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR); 

    for(;;)
    {
        /* GPIO 出力をクリア (Low) する。 */
        Cy_GPIO_Clr(Pin_LEDR_PORT, Pin_LEDR_NUM);
        /* 1000m秒待つ */
        CyDelay(1000);
    }
}

PSoC 6では、最初にCortex-M0+が立ち上がります。そしてCy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);を実行することでCortex-M4での実行を開始します。

その後、LEDが接続されているGPIO出力を1000m秒ごとにLowに設定します。普通のLチカでしたら、LowとHighを交互に出力するのですが、このプログラムでは、Lowのみ出力します。では、Highを出力するのは誰かというと、Cortex-M0+に叩き起こされたCortex-M4が実行する以下のプログラムです。

main_cm4.c
#include "project.h"

int main(void)
{
    __enable_irq(); /* 全体の割り込みを許可する */

    /* 500m秒待つ */
    CyDelay(500);

    for(;;)
    {
        /* GPIO 出力をセット (High) する。 */
        Cy_GPIO_Set(Pin_LEDR_PORT, Pin_LEDR_NUM);
        /* 1000m秒待つ */
        CyDelay(1000);
    }
}

このプログラムの無限ループ部分では、1000m秒ごとにGPIO出力をHighに設定しています。Highにするタイミングは、無限ループ直前のCyDelay(500);で作り出しています。これによりCortex-M0+がGPIOをLowにしてからおおむね500m秒後にCortex-M4がHighにするため、50%デューティーのLチカが実現できます。まさに、二つのCPUによる共同作業というわけです。

問題点

このシステムでは、Cortex-M0+Cortex-M4が、自分勝手なタイミングでGPIOをHigh/Lowしています。タイミングを作っているのはソフトウェアによる遅延なので、もしかしたら次第にずれていってしまうかもしれません。
これらのタイミングがずれないようにするには、CPUの間で通信を行い同期をとる必要があります。

関連文献

AN215656 – PSoC 6 MCU Dual-Core CPU System Design