LoginSignup
1
0

More than 3 years have passed since last update.

PSoC 6 のデュアルコアでHello World (5)

Posted at

前回のあらすじ

前回の記事では、Cortex-M4側のデータをPIPEの仕組みを使ってCortex-M0+側に送信しました。ところが、頻繁にメッセージを受け取ってしまうと受信側の処理が間に合わないため、PIPE全体を止めるという方法で解決をしました。これでは、他の用途にPIPEを使うことができません。
今回は、メッセージの送信をセマフォという仕組みを使って管理します。

ハードウェア

本プロジェクトでは、前回の記事と同様にタイマとしてMCWDTを使用します。

GS003394.png

セマフォの利用方法

セマフォは、PSoC 6 のデュアルコアでLチカ (2)でも使用しました。複数のプロセッサがひとつのリソースを共有する仕組みです。
ここでは、「メッセージを送信する権利」というリソースを複数のタスクが取り合うという構図を実現しました。

まず、Cortex-M4側のあるタスクが、「メッセージを送信する権利」セマフォを獲得します。すると、他のタスクはメッセージを送信できなくなります。

セマフォを獲得したタスクがメッセージを送信したあと、通常であればセマフォを開放して「メッセージを送信する権利」を放棄します。しかしながら、今回のモデルでは獲得したセマフォを放置します。

放置されたセマフォは、誰のものでもなくなりますが、メッセージを送信したことで「メッセージを受信したCortex-M0+側に譲渡された」と解釈します。つまり、「メッセージを送信する権利」を受信側が獲得したとみなします。

メッセージを受信したCortex-M0+側は、もちろん「メッセージを送信する権利」を行使するわけではありません。行使しないことで、後続メッセージが到着するのを防ぎます。

Cortex-M0+側でメッセージの処理が終わったら、「メッセージを送信する権利」を開放します。これで、他のタスクがメッセージを送信できるようになります。

Cortex-M0+側のプログラム

まず、セマフォ番号を決めます。ここでは、8番を使っています。

main_cm0p.c
#define SEMAPHORE_SENDER        (8) /* メッセージを送信する権利 */

Cortex-M0+側が「メッセージを送信する権利」を譲渡されるとき、セマフォを放置することにより譲渡を実現しているので、何かをする必要があるわけではありません。

main_cm0p.c
void pipeUartTxCallback(uint32_t *message) {
    CY_ASSERT(
        txCharsLeft == 0
    );

    /* 受信成功:急いでデータをバッファにコピー */
    strcpy(txBuffer, (char_t *)(&message[1]));
    txCharsLeft = strlen(txBuffer);
    txColumn = 0;
}

むしろ、PIPEを停止する処理がなくなったのですっきりしました。

一方、メッセージの処理が終わった時にセマフォを開放する必要があります。

main_cm0p.c
    for (;;) {
        /* UART制御ブロック */
        if (txCharsLeft > 0) {
            /* バッファのデータを一文字ずつちんたら送り出す。 */
            UART_Put(txBuffer[txColumn]);
            txColumn++;
            txCharsLeft--;

            if (txCharsLeft <= 0) {
                /* すべて送り出したらセマフォを開放する */
                while (
                    Cy_IPC_Sema_Clear(SEMAPHORE_SENDER, false) != CY_IPC_SEMA_SUCCESS
                ) ;
            }
        }
        /* 一文字当たり10msの低速処理 */
        CyDelay(10);
    }

メインループの中で、メッセージの受付を再開した部分でセマフォを開放しています。

Cortex-M4側のプログラム

Cortex-M4側でも同じセマフォ番号を宣言します。

main_cm4.c
#define SEMAPHORE_SENDER        (8) /* メッセージを送信する権利 */

メッセージの送信前に「メッセージを送信する権利」を獲得する処理が追加されました。

main_cm4.c
        case ST_SEND:
            /* フラグが立っている時のみ実行 */
            if (! *(context->flag)) break;
            /* セマフォを獲得する */
            if (Cy_IPC_Sema_Set(SEMAPHORE_SENDER, false) == CY_IPC_SEMA_SUCCESS) {
                /* メッセージを送る */
                if (
                    Cy_IPC_Pipe_SendMessage(
                        CY_IPC_EP_CYPIPE_CM0_ADDR,
                        CY_IPC_EP_CYPIPE_CM4_ADDR,
                        (uint32_t *)(&context->message[context->side]),
                        0  
                    ) == CY_IPC_PIPE_SUCCESS
                ) {
                    /* バッファを切り替える */
                    context->side = (context->side)?(0):(1);
                    context->state = ST_CREATE;
                    /* 割り込みフラグを折る */
                    *(context->flag) = false;
                } else {
                   /* メッセージの送信に失敗したので、セマフォを開放する */
                    while (
                        Cy_IPC_Sema_Clear(SEMAPHORE_SENDER, false) != CY_IPC_SEMA_SUCCESS
                    ) ;
                }
            }
            break;

セマフォが獲得出来たらメッセージを送ります。獲得したセマフォ
は、メッセージと共にCortex-M4側に譲渡されたと解釈しますので、他の処理は必要ありません。

万が一メッセージの送信に失敗した場合には、セマフォを開放します。

関連文献

AN215656 - PSoC 6 MCU Dual-Core CPU System Design
AN217666 - PSoC 6 MCU Interrupts
CE216795 - PSoC(R) 6 MCU Dual-Core Basics
CE219339 - PSoC 6 MCU - MCWDT and RTC Interrupts (Dual Core)
PSoC 6 MCU: PSoC 63 with BLE Architecture Technical Reference Manual

関連記事

PSoC 6 のデュアルコアでLチカ (1)
PSoC 6 のデュアルコアでLチカ (2)
PSoC 6 のデュアルコアでLチカ (3)
PSoC 6 のデュアルコアでLチカ (4)
PSoC 6 のデュアルコアでLチカ (5)
PSoC 6 のデュアルコアでLチカ (6)
PSoC 6 のデュアルコアでLチカ (7)
PSoC 6 のデュアルコアでHello World (1)
PSoC 6 のデュアルコアでHello World (2)
PSoC 6 のデュアルコアでHello World (3)
PSoC 6 のデュアルコアでHello World (4)

リポジトリ

github Repository

1
0
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
0