1. 概述
大家好,我是“黄小斯”,来自山东。
多核MCU一直令我十分着迷,尤其是那些大牛使用多核心编程做出酷炫项目的时候,更是让我羡慕不已。另一个让我非常着迷的就是树莓派pico。值得庆幸的是,硬禾学堂在这两个方面均有相应的活动,让我有机会开拓眼界、提高自己。在此,感谢苏老师以及曾经帮助和启发我的人们。
在智能手表方面,之前用双核的ESP32。总体来讲,当时使用ESP32是基于Ardunio开发,效率上本身就是打了折扣的,加上Arduino的调试非常麻烦,因而多核编程变得更加困难。反观我们这次使用TC275,以及配套的开发环境,样例和说明文档,使得我这次的开发过程如虎添翼,使用十分的顺畅,试一次非常不错的开发体验。同时也非常推荐大家多使用开发文档,可以大大帮助我们理解MCU的结构和样例。
为了加快开发速度,我使用了部分原有工程中的代码,核心状态切换和GPIO的调用方面都是用官方的库来做。
2. 软件设计
这次的目标是:使用TC275的三个核心,轮流休眠待机,分别控制板卡上的LED灯,如core0检测按键按下,唤醒core1翻转LED1,一秒后,唤醒core2翻转LED2,系统休眠
2.1. 总体设计
首先使用官方的库,对GPIO口进行相关的设置,包含初始化以,状态的读取,电平设置等操作
#include <bsp_led_button.h>
#include "Bsp.h"
#include <scu_sleep.h>
/* This function initializes the port pin which drives the LED */
void GPIOs(void)
{
IfxPort_setPinMode(LED2, IfxPort_Mode_outputPushPullGeneral);
IfxPort_setPinMode(LED1, IfxPort_Mode_outputPushPullGeneral);
IfxPort_setPinMode(BUTTON, IfxPort_Mode_inputPullUp);
/* Switch OFF the LED (low-level active) */
IfxPort_setPinState(LED1, IfxPort_State_high);
IfxPort_setPinState(LED2, IfxPort_State_high);
}
/* This function toggles the port pin and wait 1000 milliseconds */
void toggle_led(Ifx_P *port, uint8 pinIndex)
{
IfxPort_togglePin(port, pinIndex);
// waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, 1000U));
}
其次是使用Ifx Cpu库,对CPU的状态进行相关的设置,调用这个函数就可以达到设置指定CPU核心休眠的效果。
#include <scu_sleep.h>
#include <bsp_uart.h>
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#define BLOCK_SLEEP_MODE 0x1 /* Block sleep mode for STM */
#define PMSWCR1_CPUSEL 0x1 /* Set the CPU0 as CPU master */
#define PMSWCR2_CPUSEL 0x2 /* Set the CPU1 as CPU master */
#define PMSWCR3_CPUSEL 0x4 /* Set the CPU2 as CPU master */
#define PMCSR0_REQSLP 0x2 /* Request sleep mode */
void Cpu0_req_sleep(void)
{
/* Clear safety EndInit protection */
IfxScuWdt_clearSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
/* Clear EndInit protection */
IfxScuWdt_clearCpuEndinit(IfxScuWdt_getCpuWatchdogPassword());
/* Set safety EndInit protection */
IfxScuWdt_setSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
/* Set EndInit protection */
IfxScuWdt_setCpuEndinit(IfxScuWdt_getCpuWatchdogPassword());
STM0_CLC.B.EDIS = BLOCK_SLEEP_MODE;
SCU_PMSWCR1.B.CPUSEL = PMSWCR1_CPUSEL; /* Set the CPU0 as CPU master to trigger a power down mode */
SCU_PMCSR0.B.REQSLP = PMCSR0_REQSLP; /* Request System Sleep Mode CPU0 */
}
核心通过调用函数来控制按键,LED以及各个核心休眠的状态
#include <bsp_led_button.h>
#include <bsp_stm.h>
#include <scu_sleep.h>
#include <bsp_uart.h>
#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
IfxCpu_syncEvent g_cpuSyncEvent = 0;
int core0_main(void)
{
IfxCpu_enableInterrupts();
/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
* Enable the watchdogs and service them periodically if it is required
*/
GPIOs();
initStm0();
Cpu0_req_sleep();
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
/* Wait for CPU sync event */
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
while(1)
{
if (_flag2 == TRUE) {
_flag2 = FALSE;
Cpu0_req_sleep();
}
}
return (1);
}
3. 硬件设计
1、LED:三个核心通过GPIO口分别调用LED1和LED2,实现控制LED状态的功能
2、按键:核心0和核心1通过GPIO口读取状态,实现监听按键状态的功能
4.实际运行情况
开机的时候第一个LED翻转,可以看到LED1亮了, 并且持续地进行闪烁
拿下按键第二个LED翻转, 可以看到LED2也点亮了,并持续闪烁
一秒后休眠, 所有地LED熄灭
5. 小结
很高兴能够参与这次Funpack活动,让我可以接触到英飞凌的MCU。没参加之前总觉得,能用Arduino就可以了,会用ESP32就可以满足很多场景了,还可以联网。但是,通过这次活动,让我迈出了第一步。不仅,让我确信自己能够开发ESP32之外基于的MCU,同时也让我领悟到TC275这款MCU的快速、高效、稳定。虽然,Funpck第2期要结束了,但我想我与TC275相伴的日子不会结束。
感谢硬禾学堂带来这么好地活动活动