PSoC 6 듀얼 코어로 Hello World (3)
마지막 회의
마지막 기사 에서는, 메세지를 송신하는 Cortex-M4측의 프로그램을 멀티 태스크풍으로 변경해, 복수의 요구가 엉망에 도착하는 모습을 보았습니다.
이번에는, 이러한 태스크가 발하는 메세지를 하드웨어 타이머의 타이밍으로 송신하도록(듯이) 변경해 갑니다.
하드웨어
이 프로젝트에서는 타이머로 MCWDT를 추가합니다.
또 하나 잊어서는 안되는 것이, 인터럽트를 수신하는 CPU의 지정입니다.
CYDWR 파일의 Interrupts 탭에서 Int_WDT 인터럽트가 Cortex-M4로 수신되도록 설정합니다.
MCWDT
Multi-Counter WatchDog Timer(MCWDT)에는 3개의 카운터가 들어 있으며, 각각을 3개의 독립된 타이머로 사용하거나, 복수의 카운터를 조합하여 주기적인 긴 타이머를 구성할 수 있습니다.
또, 이 블록은 Cortex-M0+와 Cortex-M4의 어느쪽에도 하나씩 탑재되고 있으므로, 초기화에 사용한 CPU에 탑재되고 있는 블록이 사용됩니다. 이 프로젝트에서는 메시지를 보내는 Cortex-M4 측의 타이밍을 만들므로 당연히 Cortex-M4 측의 프로그램으로 초기화를 합니다.
본 프로젝트에서는 위와 같은 설정을 하고 있습니다.
이 세 가지 요인을 하나의 인터럽트로 취급합니다.
Cortex-M0+ 측 프로그램
Cortex-M0+ 측의 프로그램은 이번에도 변경 부분은 제로입니다.
Cortex-M4 측 프로그램
Cortex-M4측의 프로그램에서는, 우선, MCWDT를 이용하기 위한 인터럽트 서비스 루틴(ISR)과 초기화 루틴을 정의하고 있습니다.
main_cm4.c
/* WDT を使った周期割り込み */
bool Int_WDT_flag0 = false;
bool Int_WDT_flag1 = false;
bool Int_WDT_flag2 = false;
void Int_WDT_isr(void) {
uint32_t status = Cy_MCWDT_GetInterruptStatus(MCWDT_HW);
if (status & CY_MCWDT_CTR0) {
Cy_MCWDT_ClearInterrupt(MCWDT_HW, CY_MCWDT_CTR0);
Int_WDT_flag0 = true;
}
if (status & CY_MCWDT_CTR1) {
Cy_MCWDT_ClearInterrupt(MCWDT_HW, CY_MCWDT_CTR1);
Int_WDT_flag1 = true;
}
if (status & CY_MCWDT_CTR2) {
Cy_MCWDT_ClearInterrupt(MCWDT_HW, CY_MCWDT_CTR2);
Int_WDT_flag2 = true;
}
}
void Int_WDT_Start(void) {
/* 割り込みコンポーネントを初期化しイネーブル */
Cy_SysInt_Init(&Int_WDT_cfg, Int_WDT_isr);
NVIC_ClearPendingIRQ((IRQn_Type) Int_WDT_cfg.intrSrc);
NVIC_EnableIRQ((IRQn_Type) Int_WDT_cfg.intrSrc);
/* MCWDT コンポーネントを起動する */
Cy_MCWDT_Init(MCWDT_HW, &MCWDT_config);
Cy_MCWDT_Enable(MCWDT_HW, MCWDT_ENABLED_CTRS_MASK, 0u);
/* MCWDT コンポーネントの割り込みマスクを設定する */
Cy_MCWDT_SetInterruptMask(MCWDT_HW,
CY_MCWDT_CTR0 | CY_MCWDT_CTR1 | CY_MCWDT_CTR2
);
}
ISR 내에서 MCWDT 블록의 세 가지 요소에 대해 각각 플래그가 지정됩니다. 메인 루프 안에 기술된 메세지 송신 프로그램이, 이러한 플래그를 이용해 타이밍을 제어하고 있습니다.
MCWDT 설정 방법은 CE219339 – PSoC 6 MCU – MCWDT and RTC Interrupts (Dual Core)을 참조하십시오.
main_cm4.c
struct Task1Context {
enum Task1State state; /* ステートマシンの状態 */
bool *flag; /* 割り込みフラグ */
uint32_t count; /* メッセージ番号 */
uint32_t side; /* 使用中バッファ面 */
const char_t *name; /* タスクの名前 */
char_t buffer[2][128]; /* ダブルバッファ */
};
void task1_init(struct Task1Context *context, const char_t *name, bool *flag) {
/* タスクの初期化 */
context->name = name;
context->count = 0;
context->side = 0;
context->flag = flag;
context->state = ST_CREATE;
}
void task1_dispatch(struct Task1Context *context) {
switch (context->state) {
case ST_CREATE:
/* 送信するメッセージを作成する */
(void)sprintf(
context->buffer[context->side],
"%s: HELLO WORLD %lu\r\n",
context->name, context->count++
);
context->state = ST_SEND;
break;
case ST_SEND:
/* フラグが立っている時のみ実行 */
if (*(context->flag)) {
/* メッセージを送る */
if (
Cy_IPC_Drv_SendMsgPtr(
ipcHandle,
CY_IPC_NO_NOTIFICATION,
context->buffer[context->side]
) == CY_IPC_DRV_SUCCESS
) {
/* バッファを切り替える */
context->side = (context->side)?(0):(1);
context->state = ST_CREATE;
/* 割り込みフラグを折る */
*(context->flag) = false;
}
}
break;
default:
CY_ASSERT(false);
}
}
Task1에 약간의 변경이 있습니다.
실행해보면
실행을 시작하면 세 가지 작업이 처리되는 방식을 알 수 있습니다.
각 태스크의 실행 빈도는 MCWDT에 지정된 주기에 따라 다릅니다. 태스크의 실행 주기가 관리되기 때문에 한 태스크만 실행되는 상황이 사라졌습니다.
관련 문헌
AN215656 – PSoC 6 MCU Dual-Core CPU System Design
AN217666 - PSoC 6 MCU 인터럽트
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)
Reference
이 문제에 관하여(PSoC 6 듀얼 코어로 Hello World (3)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/noritan_org/items/e03f958baeafeb2996e0텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)