15.2 任务功能划分 前面第三章已经将任务功能划分好:
根据这个功能划分,创建所需要的任务。 15.2.1 主函数创建 在main.c文件实现: - /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: 标准c程序入口。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int main(void)
- {
- /*
- 在启动调度前,为了防止初始化STM32外设时有中断服务程序执行,这里禁止全局中断(除了NMI和HardFault)。
- 这样做的好处是:
- 1. 防止执行的中断服务程序中有FreeRTOS的API函数。
- 2. 保证系统正常启动,不受别的中断影响。
- 3. 关于是否关闭全局中断,大家根据自己的实际情况设置即可。
- 在移植文件port.c中的函数prvStartFirstTask中会重新开启全局中断。通过指令cpsie i开启,__set_PRIMASK(1)
- 和cpsie i是等效的。
- */
- __set_PRIMASK(1);
-
- /* 硬件初始化 */
- bsp_Init();
-
- /* 1. 初始化一个定时器中断,精度高于滴答定时器中断,这样才可以获得准确的系统信息 仅供调试目的,实际项
- 目中不要使用,因为这个功能比较影响系统实时性。
- 2. 为了正确获取FreeRTOS的调试信息,可以考虑将上面的关闭中断指令__set_PRIMASK(1); 注释掉。
- */
- vSetupSysInfoTest();
-
- /* 创建任务通信机制 */
- AppObjCreate();
-
- /* 创建任务 */
- AppTaskCreate();
-
- /* 启动调度,开始执行任务 */
- vTaskStartScheduler();
-
- /*
- 如果系统正常启动是不会运行到这里的,运行到这里极有可能是用于定时器任务或者空闲任务的
- heap空间不足造成创建失败,此要加大FreeRTOSConfig.h文件中定义的heap大小:
- #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) )
- */
- while(1);
- }
复制代码主函数中做的工作比较多,下面依次为大家做个说明: 调用函数bsp_Init()做硬件初始化 硬件外设的初始化函数bsp_Init是在 bsp.c 文件实现:
调用函数vSetupSysInfoTest()初始化系统信息调试功能 这个函数涉及到的内容比较多,需要大家专门看我们FreeRTOS教程的第8章,有详细讲解: 调用函数AppObjCreate()创建任务通信机制 实现代码如下,其中事件标志的创建比较重要,emWin任务和数字信号处理任务之间通信要使用。 - /*
- *********************************************************************************************************
- * 函 数 名: AppObjCreate
- * 功能说明: 创建任务通信机制
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AppObjCreate (void)
- {
- /* 创建互斥信号量 */
- xMutex = xSemaphoreCreateMutex();
-
- if(xMutex == NULL)
- {
- /* 没有创建成功,用户可以在这里加入创建失败的处理机制 */
- }
-
- /* 创建事件标志组 */
- xCreatedEventGroup = xEventGroupCreate();
-
- if(xCreatedEventGroup == NULL)
- {
- /* 没有创建成功,用户可以在这里加入创建失败的处理机制 */
- }
-
- /* 动态内存申请部分,省略未贴 */
- }
复制代码
调用函数AppTaskCreate()创建任务 创建了如下五个任务: - /*
- *********************************************************************************************************
- * 函 数 名: AppTaskCreate
- * 功能说明: 创建应用任务
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AppTaskCreate (void)
- {
- xTaskCreate( vTaskGUI, /* 任务函数 */
- "vTaskGUI", /* 任务名 */
- 1024, /* 任务栈大小,单位word,也就是4字节 */
- NULL, /* 任务参数 */
- 1, /* 任务优先级*/
- xHandleTaskGUI ); /* 任务句柄 */
-
- xTaskCreate( vTaskTaskUserIF, /* 任务函数 */
- "vTaskUserIF", /* 任务名 */
- 512, /* 任务栈大小,单位word,也就是4字节 */
- NULL, /* 任务参数 */
- 2, /* 任务优先级*/
- &xHandleTaskUserIF ); /* 任务句柄 */
-
- xTaskCreate( vTaskMsgPro, /* 任务函数 */
- "vTaskMsgPro", /* 任务名 */
- 512, /* 任务栈大小,单位word,也就是4字节 */
- NULL, /* 任务参数 */
- 3, /* 任务优先级*/
- &xHandleTaskMsgPro ); /* 任务句柄 */
-
- xTaskCreate( vTaskStart, /* 任务函数 */
- "vTaskStart", /* 任务名 */
- 512, /* 任务栈大小,单位word,也就是4字节 */
- NULL, /* 任务参数 */
- 4, /* 任务优先级*/
- &xHandleTaskStart ); /* 任务句柄 */
-
- xTaskCreate( vTaskDSO, /* 任务函数 */
- "vTaskDSO", /* 任务名 */
- 1024, /* 任务栈大小,单位word,也就是4字节 */
- NULL, /* 任务参数 */
- 5, /* 任务优先级*/
- &xHandleTaskStart ); /* 任务句柄 */
- }
复制代码
15.2.2 启动任务(触摸和按键)启动任务实现的功能比较简单,主要是按键扫描和触摸扫描: - /*
- *********************************************************************************************************
- * 函 数 名: vTaskStart
- * 功能说明: 启动任务,主要实现按键检测和触摸检测。
- * 形 参: pvParameters 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级: 5
- *********************************************************************************************************
- */
- static void vTaskStart(void *pvParameters)
- {
- uint8_t ucCount = 0;
-
-
- while(1)
- {
- /* 1ms一次触摸扫描,电阻触摸屏 */
- if(g_tTP.Enable == 1)
- {
- TOUCH_Scan();
-
- /* 按键扫描 */
- ucCount++;
- if(ucCount == 10)
- {
- ucCount = 0;
- bsp_KeyScan();
- }
- vTaskDelay(1);
- }
-
- /* 10ms一次触摸扫描,电容触摸屏GT811 */
- if(g_GT811.Enable == 1)
- {
- bsp_KeyScan();
- GT811_OnePiontScan();
- vTaskDelay(10);
- }
-
- /* 10ms一次触摸扫描,电容触摸屏FT5X06 */
- if(g_tFT5X06.Enable == 1)
- {
- bsp_KeyScan();
- FT5X06_OnePiontScan();
- vTaskDelay(10);
- }
- }
- }
复制代码 知识点拓展 新版emWin教程第4章或者第5章,对触摸的实现做了详细讲解:
15.2.3 信号处理任务 信号处理任务的实现如下: 根据接收到的不同任务消息来处理不同的功能,要处理的消息分为三类: 1、双通道波形数据处理 主要实现软件触发,计算FFT ,FIR ,RMS,最大值,最小值,平均值和峰峰值。两个通道都进行了处理。具体实现方法已经在前面章节为大家做了讲解。 2、简单电压测量处理 这个功能比较简单,就是获取一组ADC数值,然后求平均。 3、打印任务执行情况 通过串口打印任务栈的使用情况和各个任务的CPU利用率。 15.2.4 GUI任务emWin任务的实现代码如下: - /*
- *********************************************************************************************************
- * 函 数 名: vTaskGUI
- * 功能说明: emWin任务
- * 形 参: pvParameters 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级: 1 (数值越小优先级越低,这个跟uCOS相反)
- *********************************************************************************************************
- */
- static void vTaskGUI(void *pvParameters)
- {
- while (1)
- {
- MainTask();
- }
- }
复制代码emWin的代码都是在函数MainTask里面实现,这样做是方便在main.c文件里面统一管理任务。关于GUI部分最重要的界面优化,波形刷新优化,波形浏览等,在前面章节已经都做了讲解,我们这里不再赘述。更详细的实现,需要结合前面章节的讲解去看源码。
15.2.5 用户接口任务这个任务暂时未执行任何功能,保留供以后升级使用。代码如下: - /*
- *********************************************************************************************************
- * 函 数 名: vTaskTaskUserIF
- * 功能说明: 保留,暂时未用到。
- * 形 参: pvParameters 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级: 2
- *********************************************************************************************************
- */
- static void vTaskTaskUserIF(void *pvParameters)
- {
- while(1)
- {
- vTaskDelay(1000);
- }
- }
复制代码
15.2.6 文件系统处理任务当前文件系统处理任务主要用来做截图功能,将GUI界面以BMP格式存储到SD卡里面: - /*
- *********************************************************************************************************
- * 函 数 名: vTaskMsgPro
- * 功能说明: 实现截图功能,将图片以BMP格式保存到SD卡中
- * 形 参: pvParameters 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级: 4
- *********************************************************************************************************
- */
- static void vTaskMsgPro(void *pvParameters)
- {
- uint8_t Pic_Name = 0;
- uint32_t ulStart, ulEnd;
- char buf[20];
-
- while(1)
- {
- ulTaskNotifyTake( pdTRUE, /* 此参数设置为pdTRUE,接收到的notification value清零 */
- portMAX_DELAY ); /* 无限等待 */
-
- sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
-
- /* 记录截图前起始时间 */
- ulStart = xTaskGetTickCount();
-
- /* 开启调度锁 */
- //vTaskSuspendAll();
-
- /* 如果SD卡中没有PicSave文件,会进行创建 */
- result = f_mkdir("0:/PicSave");
- /* 创建截图 */
- result = f_open(&file, buf, FA_WRITE|FA_CREATE_ALWAYS);
- /* 向SD卡绘制BMP图片 */
- GUI_BMP_Serialize(_WriteByte2File, &file);
-
- /* 创建完成后关闭file */
- result = f_close(&file);
-
- /* 关闭调度锁 */
- //xTaskResumeAll ();
-
- /* 记录截图后时间并获取截图过程耗时 */
- ulEnd = xTaskGetTickCount();
- ulEnd -= ulStart;
-
- App_Printf("截图完成,耗时 = %dms\r\n", ulEnd);
- Pic_Name++;
- }
- }
复制代码后期这个任务将被升级,用于将波形数据以CSV文件格式存储到SD卡里面。
|