PSoC 6 のデュアルコアでHello World (5)
前回のあらすじ
前回の記事では、Cortex-M4側のデータをPIPEの仕組みを使ってCortex-M0+側に送信しました。ところが、頻繁にメッセージを受け取ってしまうと受信側の処理が間に合わないため、PIPE全体を止めるという方法で解決をしました。これでは、他の用途にPIPEを使うことができません。
今回は、メッセージの送信をセマフォという仕組みを使って管理します。
ハードウェア
本プロジェクトでは、前回の記事と同様にタイマとしてMCWDTを使用します。
セマフォの利用方法
セマフォは、PSoC 6 のデュアルコアでLチカ (2)でも使用しました。複数のプロセッサがひとつのリソースを共有する仕組みです。
ここでは、「メッセージを送信する権利」というリソースを複数のタスクが取り合うという構図を実現しました。
まず、Cortex-M4側のあるタスクが、「メッセージを送信する権利」セマフォを獲得します。すると、他のタスクはメッセージを送信できなくなります。
セマフォを獲得したタスクがメッセージを送信したあと、通常であればセマフォを開放して「メッセージを送信する権利」を放棄します。しかしながら、今回のモデルでは獲得したセマフォを放置します。
放置されたセマフォは、誰のものでもなくなりますが、メッセージを送信したことで「メッセージを受信したCortex-M0+側に譲渡された」と解釈します。つまり、「メッセージを送信する権利」を受信側が獲得したとみなします。
メッセージを受信したCortex-M0+側は、もちろん「メッセージを送信する権利」を行使するわけではありません。行使しないことで、後続メッセージが到着するのを防ぎます。
Cortex-M0+側でメッセージの処理が終わったら、「メッセージを送信する権利」を開放します。これで、他のタスクがメッセージを送信できるようになります。
Cortex-M0+側のプログラム
まず、セマフォ番号を決めます。ここでは、8番を使っています。
#define SEMAPHORE_SENDER (8) /* メッセージを送信する権利 */
Cortex-M0+側が「メッセージを送信する権利」を譲渡されるとき、セマフォを放置することにより譲渡を実現しているので、何かをする必要があるわけではありません。
void pipeUartTxCallback(uint32_t *message) {
CY_ASSERT(
txCharsLeft == 0
);
/* 受信成功:急いでデータをバッファにコピー */
strcpy(txBuffer, (char_t *)(&message[1]));
txCharsLeft = strlen(txBuffer);
txColumn = 0;
}
むしろ、PIPEを停止する処理がなくなったのですっきりしました。
一方、メッセージの処理が終わった時にセマフォを開放する必要があります。
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側でも同じセマフォ番号を宣言します。
#define SEMAPHORE_SENDER (8) /* メッセージを送信する権利 */
メッセージの送信前に「メッセージを送信する権利」を獲得する処理が追加されました。
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)
リポジトリ
Author And Source
この問題について(PSoC 6 のデュアルコアでHello World (5)), 我々は、より多くの情報をここで見つけました https://qiita.com/noritan_org/items/15fc7625fb865a2539f0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .