1. 项目描述
本次要完成的是任务一:使用TC275的三个核心,轮流休眠待机,分别控制板卡上的LED灯,如core0检测按键按下,唤醒core1翻转LED1,一秒后,唤醒core2翻转LED2,系统休眠
TC275包括3个CPU核心,分别是CPU0,CPU1和CPU2,这三个核心可以分别进行工作。完成的程序实现了通过将CPU0配置为主核心实现CPU休眠的功能。程序通过系统定时器监控按键按下时唤醒CPU0。CPU0被唤醒后,由它去唤醒CPU1,CPU1执行反转LED1的任务,然后CPU1唤醒CPU2,之后CPU1休眠待机。CPU2执行后,它反转LED2,之后执行CPU整体休眠。直到下一次按键按下事件再次唤醒CPU0,就再进行一次CPU唤醒和反转LED的循环。
2. 任务分析与准备
完成本任务,主要使用了英飞凌的ILLD库函数库。对板载LED1和LED2和BUTTON进行了配置。
使用了系统定时器STM,先进行初始化,再定义按键中断唤醒CPU0的功能函数stmIsr。这里的配置参考了历程手册里的介绍。
配置STM
睡眠模式的设置步骤参考如下,以下注意在本任务的程序不需要GTM定时器。我们只用到了STM定时器。
英飞凌提供了比较丰富的用户手册,更详细的内容可以参考用户手册。
程序的逻辑也比较简单,如下所示:
3.程序部分
初始化LED1, LED2和BUTTON. 这里把2个LED配置为一个点亮一个熄灭,为了看的区别明显。
#define LED1 &MODULE_P00,5 /* Port pin for the LED1 */
#define LED2 &MODULE_P00,6 /* Port pin for the LED2 */
#define BUTTON &MODULE_P00,7 /* Port pin for the button */
IfxPort_setPinMode(LED1, IfxPort_Mode_outputPushPullGeneral);
IfxPort_setPinMode(LED2, IfxPort_Mode_outputPushPullGeneral);
/* Setup the port pin connected to the push button to input mode. This function can be used to initialize any
* port to input mode by just specifying the port number as illustrated.
*/
IfxPort_setPinMode(BUTTON, IfxPort_Mode_inputPullUp);
/* Set led 1 & 2 in different state to show the change */
IfxPort_setPinState(LED1, IfxPort_State_high);
IfxPort_setPinState(LED2, IfxPort_State_low);
初始化CPU0作为主CPU, 并定义休眠参数。设置了一个CPU标识位cpu_flag,它的作用是程序里监视按键中断的定时器一直运行,防止程序运行中按键按下造成的影响。并且程序逻辑更清楚。
#define BLOCK_SLEEP_MODE 0x1 /* Block sleep mode for STM */
#define PMSWCR1_CPUSEL 0x1 /* Set the CPU0 as CPU master */
#define PMCSR0_REQSLP 0x2 /* Request sleep mode */
IfxStm_Timer g_stmTimer; /* STM driver handle */
IFX_INTERRUPT(stmIsr, 0, ISR_PRIORITY_STM);
float32 g_stmPeriod = 20.0; /* Period in seconds at which power modes toggle */
uint8 cpu_flag = 0; /* Variable used to monitor the current working CPU */
初始化系统定时器。
IfxStm_Timer_Config timerConfig; /* Timer configuration structure */
IfxStm_Timer_initConfig(&timerConfig, &MODULE_STM0); /* Initialize it with default values */
timerConfig.base.frequency = 25; /* Interrupt rate every STM_PERIOD seconds */
timerConfig.base.isrPriority = ISR_PRIORITY_STM; /* Interrupt priority */
timerConfig.base.isrProvider = IfxSrc_Tos_cpu0; /* CPU0 to trigger the interrupt */
timerConfig.comparator = IfxStm_Comparator_0; /* Comparator 0 register is used */
IfxStm_Timer_init(&g_stmTimer, &timerConfig); /* Use timerConfig to initialize the STM */
IfxStm_Timer_run(&g_stmTimer); /* Run the STM and set the compare Value
定义按键驱动CPU0唤醒功能。
if (cpu_flag==0)
{
if (IfxPort_getPinState(BUTTON) == 0)
{
cpu_flag=1;
IfxCpu_setCoreMode(&MODULE_CPU1, IfxCpu_CoreMode_run);
}
}
CPU1被以上代码唤醒后执行反转LED1的功能,并唤醒CPU2同时自己待机。
while(1)
{
if(cpu_flag==1)
{
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, WAIT_TIME));
IfxPort_togglePin(LED1);
cpu_flag=2;
IfxCpu_setCoreMode(&MODULE_CPU2, IfxCpu_CoreMode_run);
IfxCpu_setCoreMode(&MODULE_CPU1, IfxCpu_CoreMode_idle);
}
}
CPU2唤醒后等待一秒反转LED2,然后调用cpu_req_sleep,系统休眠。
while(1)
{
if(cpu_flag==2)
{
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, WAIT_TIME)); /* Wait 1000 milliseconds */
IfxPort_togglePin(LED2);
cpu_flag=0;
//IfxCpu_setCoreMode(&MODULE_CPU2, IfxCpu_CoreMode_idle);
//initStm();
cpu_req_sleep();
}
}
void cpu_req_sleep(void)
{
/* Clear safety EndInit protection */
IfxScuWdt_clearSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
/* Clear EndInit protection */
IfxScuWdt_clearCpuEndinit(IfxScuWdt_getCpuWatchdogPassword());
STM0_CLC.B.EDIS = BLOCK_SLEEP_MODE; /* Prohibit STM to go into 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 */
/* Set safety EndInit protection */
IfxScuWdt_setSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
/* Set EndInit protection */
IfxScuWdt_setCpuEndinit(IfxScuWdt_getCpuWatchdogPassword());
}
如此循环,完成任务。
4. 功能展示
从图中可见按键按下后LED1和LED2发生反转。
5. 心得体会
TC275功能已经比较强大了。提供的板载接口还可以和其它系统相连接。能实现一些更复杂的功能。从主芯片的体积也可以看出它的强大功能。
英飞凌所附的文档也比较丰富。其中一个文档达到了5063页。是一个比较适合入门学习嵌入式编程的平台。感谢硬禾学堂提供的学习开发板的机会。