EFM32jg之FreeRTOS(1)中已经建好了工程,所以现在需要将功能实现,首先将安装目录下的emlib加入工程,删除多余的em_system.c文件。
1、加入驱动(时钟+gpio+uart+软时钟)
时钟使用内部高频时钟;GPIO用来做LED灯;UART用来做串口任务测试,串口使用环形数组来存贮buffer,所以数据需要初始化;软时钟作为时定时器。
2、任务设计
设计三个任务:start_task(),led0_task(),uart_task();
任务设置:
/************************************************************!
*************************************************************/
#define START_TASK_PRIO 1 //任务优先级
#define LED0_TASK_PRIO 2 //任务优先级
#define UART_TASK_PRIO 3 //任务优先级
#define START_STK_SIZE 128 //任务堆栈大小
#define LED0_STK_SIZE 50 //任务堆栈大小
#define UART_STK_SIZE 50 //任务堆栈大小
/************************************************************!
*************************************************************/
TaskHandle_t StartTask_Handler; //任务句柄
TaskHandle_t LED0Task_Handler; //任务句柄
TaskHandle_t UARTTask_Handler; //任务句柄
主函数:
int main(void)
{
/* Chip errata */
CHIP_Init();
InitBSP(); ///底层初始化
InitAPP(); ///数据初始化
//创建开始任务
xTaskCreate((TaskFunction_t )start_task, ///任务函数
(const char* )"start_task", ///任务名称
(uint16_t )START_STK_SIZE, ///任务堆栈大小
(void* )NULL, ///传递给任务函数的参数
(UBaseType_t )START_TASK_PRIO, ///任务优先级
(TaskHandle_t* )&StartTask_Handler); ///任务句柄
vTaskStartScheduler(); ///开启任务调度
}
任务函数:
//开始任务任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); ///进入临界区
//创建 LED0 任务
xTaskCreate((TaskFunction_t )led0_task,
(const char* )"led0_task",
(uint16_t )LED0_STK_SIZE,
(void* )NULL,
(UBaseType_t )LED0_TASK_PRIO,
(TaskHandle_t* )&LED0Task_Handler);
//创建UART 任务
xTaskCreate((TaskFunction_t )uart_task,
(const char* )"uart_task",
(uint16_t )UART_STK_SIZE,
(void* )NULL,
(UBaseType_t )UART_TASK_PRIO,
(TaskHandle_t* )&UARTTask_Handler);
vTaskDelete(StartTask_Handler); ///删除开始任务
taskEXIT_CRITICAL(); ///退出临界区
}
//LED0 任务函数
void led0_task(void *pvParameters)
{
while(1)
{
GPIO_PinOutToggle(LED_GPIO_PORT,LED_GPIO_PIN);
vTaskDelay(500);
}
}
//uart 任务函数
void uart_task(void *pvParameters)
{
while(1)
{
UartWrite((uint8_t *)"1",&UartTrans);
vTaskDelay(1000);
}
}
3、程序纠错运行
1)代码纠错,重复定义SysTick_Handler
将Delay_Init初始化打开的中断函数注释,保留任务中的宏定义
2)编译纠错
插入如下代码:
//空闲任务
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
static StaticTask_t IdleTaskTCB;
//定时器任务
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
static StaticTask_t TimerTaskTCB;
//空闲任务所需内存
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
*ppxIdleTaskStackBuffer=IdleTaskStack;
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
//定时器任务所需内存
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize )
{
*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
*ppxTimerTaskStackBuffer=TimerTaskStack;
*pulTimerTaskStackSize=configMINIMAL_STACK_SIZE;
}
3)下载纠错
点击下图的Debug AS中的选项,进入下载调试模式
4)如果发现下载进去程序无法运行,则需要检查,建工程时芯片信号选的对不对
任务运行成功,串口接收如下图。