本帖最后由 席萌0209 于 2018-7-11 15:52 编辑
14.2 任务功能划分前面第三章已经将任务功能划分好: 根据这个功能划分,创建所需要的任务。
14.2.1 主函数创建 在main.c文件实现: - /*
- *********************************************************************************************************
- * 函 数 名: main
- * 功能说明: 标准c程序入口。
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- int main(void)
- {
- OS_ERR err;
-
- /* 动态内存分配 */
- MallocInit();
-
- /* 初始化uC/OS-III 内核 */
- OSInit(&err);
-
- /* 创建一个启动任务(也就是主任务)。启动任务会创建所有的应用程序任务 */
- OSTaskCreate((OS_TCB *)AppTaskStartTCB, /* 任务控制块地址 */
- (CPU_CHAR *)"App Task Start", /* 任务名 */
- (OS_TASK_PTR )AppTaskStart, /* 启动任务函数地址 */
- (void *)0, /* 传递给任务的参数 */
- (OS_PRIO )APP_CFG_TASK_START_PRIO, /* 任务优先级 */
- (CPU_STK *)&AppTaskStartStk[0], /* 堆栈基地址 */
- (CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE / 10, /* 堆栈监测区,这里表示后10%作为监测区 */
- (CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE, /* 堆栈空间大小 */
- (OS_MSG_QTY )0, /* 本任务支持接受的最大消息数 */
- (OS_TICK )0, /* 设置时间片 */
- (void *)0, /* 堆栈空间大小 */
- (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
-
- /* 定义如下:
- OS_OPT_TASK_STK_CHK 使能检测任务栈,统计任务栈已用的和未用的
- OS_OPT_TASK_STK_CLR 在创建任务时,清零任务栈
- OS_OPT_TASK_SAVE_FP 如果CPU有浮点寄存器,则在任务切换时保存浮点寄存器的内容
- */
- (OS_ERR *)&err);
-
- /* 启动多任务系统,控制权交给uC/OS-III */
- OSStart(&err);
-
- (void)&err;
-
- return (0);
- }
复制代码在主函数中,首先是初始化任务所需的栈空间以及部分全局变量所需的空间,通过函数MallocInit实现(详情看本章节14.4小节)。然后就是创建一个启动任务,其它外设初始化,任务创建,任务消息创建等,都是在启动任务里面实现。
14.2.2 启动任务(触摸和按键) 启动任务实现的功能比较简单,主要是按键扫描和触摸扫描: 在启动任务里,首先做了硬件外设初始化,任务间通信创建和任务创建。然后是触摸和按键扫描。
知识点拓展 新版emWin教程第4章或者第5章,对触摸的实现做了详细讲解:
硬件外设的初始化函数bsp_Init是在 bsp.c 文件实现: - /*
- *********************************************************************************************************
- * 函 数 名: bsp_Init
- * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次
- * 形 参:无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_Init(void)
- {
- /*
- 由于ST固件库的启动文件已经执行了CPU系统时钟的初始化,所以不必再次重复配置系统时钟。
- 启动文件配置了CPU主时钟频率、内部Flash访问速度和可选的外部SRAM FSMC初始化。
-
- 系统时钟缺省配置为168MHz,如果需要更改,可以修改 system_stm32f4xx.c 文件
- */
- /* 使能CRC 因为使用STemWin前必须要使能 */
- RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
-
- /* 优先级分组设置为4,可配置0-15级抢占式优先级,0级子优先级,即不存在子优先级。*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
-
- SystemCoreClockUpdate(); /* 根据PLL配置更新系统时钟频率变量 SystemCoreClock */
-
- bsp_InitUart(); /* 初始化串口 */
- bsp_InitKey(); /* 初始化按键变量(必须在 bsp_InitTimer() 之前调用) */
-
- bsp_InitI2C(); /* 配置I2C总线 */
-
- bsp_InitExtSDRAM(); /* 初始化SDRAM */
- bsp_DetectLcdType(); /* 检测触摸板和LCD面板型号, 结果存在全局变量 g_TouchType, g_LcdType */
-
- TOUCH_InitHard(); /* 初始化配置触摸芯片 */
- LCD_ConfigLTDC(); /* 初始化配置LTDC */
-
- DSO_ConfigCtrlGPIO(); /* 初始化示波器模块的引脚配置 */
-
- bsp_InitADC(); /* 初始化ADC1,ADC2和ADC3 */
- bsp_InitDAC1(); /* 初始化DAC1 */
-
- g_DAC1.ucDuty = 50; /* 初始化DAC配置,用于信号发生器 */
- g_DAC1.ucWaveType = 0;
- g_DAC1.ulAMP = 4095;
- g_DAC1.ulFreq = 10000;
- dac1_SetSinWave(g_DAC1.ulAMP, g_DAC1.ulFreq);
-
- MountSD(); /* 挂载SD卡 */
-
- TIM8_MeasureTrigConfig(); /* 初始化TIM8用于记录一段波形 */
- }
复制代码任务间的通信创建如下: - /*
- *********************************************************************************************************
- * 函 数 名: AppObjCreate
- * 功能说明: 创建任务通讯
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AppObjCreate (void)
- {
- OS_ERR err;
-
- /*
- 创建信号量数值为1的时候可以实现互斥功能,也就是只有一个资源可以使用
- 本例程是将串口1的打印函数作为保护的资源。防止串口打印的时候被其它任务抢占
- 造成串口打印错乱。
- */
- OSSemCreate((OS_SEM *)&AppPrintfSemp,
- (CPU_CHAR *)"AppPrintfSemp",
- (OS_SEM_CTR )1,
- (OS_ERR *)&err);
-
- /* 创建计数值为0,用于实现任务同步功能 */
- OSSemCreate((OS_SEM *)&SEM_SYNCH,
- (CPU_CHAR *)"SEM_SYNCH",
- (OS_SEM_CTR )0,
- (OS_ERR *)&err);
- }
复制代码任务创建如下: - /*
- *********************************************************************************************************
- * 函 数 名: AppTaskCreate
- * 功能说明: 创建应用任务
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- *********************************************************************************************************
- */
- static void AppTaskCreate (void)
- {
- OS_ERR err;
-
- /**************创建MsgPro任务*********************/
- OSTaskCreate((OS_TCB *)AppTaskMsgProTCB,
- (CPU_CHAR *)"App Task MsgPro",
- (OS_TASK_PTR )AppTaskMsgPro,
- (void *)0,
- (OS_PRIO )APP_CFG_TASK_MsgPro_PRIO,
- (CPU_STK *)&AppTaskMsgProStk[0],
- (CPU_STK_SIZE )APP_CFG_TASK_MsgPro_STK_SIZE / 10,
- (CPU_STK_SIZE )APP_CFG_TASK_MsgPro_STK_SIZE,
- (OS_MSG_QTY )0,
- (OS_TICK )0,
- (void *)0,
- (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP),
- (OS_ERR *)&err);
-
- /**************创建USER IF任务*********************/
- OSTaskCreate((OS_TCB *)AppTaskUserIFTCB,
- (CPU_CHAR *)"App Task UserIF",
- (OS_TASK_PTR )AppTaskUserIF,
- (void *)0,
- (OS_PRIO )APP_CFG_TASK_USER_IF_PRIO,
- (CPU_STK *)&AppTaskUserIFStk[0],
- (CPU_STK_SIZE )APP_CFG_TASK_USER_IF_STK_SIZE / 10,
- (CPU_STK_SIZE )APP_CFG_TASK_USER_IF_STK_SIZE,
- (OS_MSG_QTY )0,
- (OS_TICK )0,
- (void *)0,
- (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
- (OS_ERR *)&err);
-
- /**************创建GUI任务*********************/
- OSTaskCreate((OS_TCB *)AppTaskGUITCB,
- (CPU_CHAR *)"App Task GUI",
- (OS_TASK_PTR )AppTaskGUI,
- (void *)0,
- (OS_PRIO )APP_CFG_TASK_GUI_PRIO,
- (CPU_STK *)&AppTaskGUIStk[0],
- (CPU_STK_SIZE )APP_CFG_TASK_GUI_STK_SIZE / 10,
- (CPU_STK_SIZE )APP_CFG_TASK_GUI_STK_SIZE,
- (OS_MSG_QTY )0,
- (OS_TICK )0,
- (void *)0,
- (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP),
- (OS_ERR *)&err);
-
- /**************创建DSO任务*********************/
- OSTaskCreate((OS_TCB *)AppTaskDsoTCB,
- (CPU_CHAR *)"App Task DSO",
- (OS_TASK_PTR )AppTaskDSO,
- (void *)0,
- (OS_PRIO )APP_CFG_TASK_DSO_PRIO,
- (CPU_STK *)&AppTaskDsoStk[0],
- (CPU_STK_SIZE )APP_CFG_TASK_DSO_STK_SIZE / 10,
- (CPU_STK_SIZE )APP_CFG_TASK_DSO_STK_SIZE,
- (OS_MSG_QTY )5,
- (OS_TICK )0,
- (void *)0,
- (OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR | OS_OPT_TASK_SAVE_FP),
- (OS_ERR *)&err);
- }
复制代码
14.2.3 信号处理任务 信号处理任务的实现如下: 根据接收到的不同任务消息来处理不同的功能,要处理的消息分为三类: 1、双通道波形数据处理 主要实现软件触发,计算FFT ,FIR ,RMS,最大值,最小值,平均值和峰峰值。两个通道都进行了处理。具体实现方法已经在前面章节为大家做了讲解。 2、简单电压测量处理 这个功能比较简单,就是获取一组ADC数值,然后求平均。 3、打印任务执行情况 通过串口打印任务栈的使用情况和各个任务的CPU利用率。 14.2.4 GUI任务 emWin任务的实现代码如下: - /*
- *********************************************************************************************************
- * 函 数 名: AppTaskGUI
- * 功能说明: GUI任务,最低优先级
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- * 优 先 级: OS_CFG_PRIO_MAX - 4u
- *********************************************************************************************************
- */
- static void AppTaskGUI(void *p_arg)
- {
- (void)p_arg; /* 避免编译器告警 */
-
- while (1)
- {
- MainTask();
- }
- }
复制代码emWin的代码都是在函数MainTask里面实现,这样做是方便在main.c文件里面统一管理任务。关于GUI部分最重要的界面优化,波形刷新优化,波形浏览等,在前面章节已经都做了讲解,我们这里不再赘述。更详细的实现,需要结合前面章节的讲解去看源码。
14.2.5 用户接口任务 这个任务暂时未执行任何功能,保留供以后升级使用。代码如下: - /*
- *********************************************************************************************************
- * 函 数 名: AppTaskUserIF
- * 功能说明: 保留,暂未使用。
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- 优 先 级: 5
- *********************************************************************************************************
- */
- static void AppTaskUserIF(void *p_arg)
- {
- OS_ERR err;
-
- (void)p_arg; /* 避免编译器报警 */
-
-
- while (1)
- {
- OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
- }
- }
复制代码
14.2.6 文件系统处理任务 当前文件系统处理任务主要用来做截图功能,将GUI界面以BMP格式存储到SD卡里面: - /*
- *********************************************************************************************************
- * 函 数 名: AppTaskMsgPro
- * 功能说明: 实现截图功能,将图片以BMP格式保存到SD卡中
- * 形 参: p_arg 是在创建该任务时传递的形参
- * 返 回 值: 无
- 优 先 级: 4
- *********************************************************************************************************
- */
- static void AppTaskMsgPro(void *p_arg)
- {
- uint32_t ulStart, ulEnd;
- OS_ERR err;
- uint8_t Pic_Name = 0;
- char buf[20];
-
- (void)p_arg;
-
- while(1)
- {
- /* 等待获取信号量同步消息,接收到后实现截图功能,将图片以BMP格式保存到SD卡中 */
- OSSemPend((OS_SEM *)&SEM_SYNCH,
- (OS_TICK )0,
- (OS_OPT )OS_OPT_PEND_BLOCKING,
- (CPU_TS )0,
- (OS_ERR *)&err);
-
- if(err == OS_ERR_NONE)
- {
- sprintf(buf,"0:/PicSave/%d.bmp",Pic_Name);
-
- /* 记录截图前起始时间 */
- ulStart = OSTimeGet(&err);
-
- /* 开启调度锁 */
- //OSSchedLock(&err);
-
- /* 如果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);
-
- /* 开启调度锁 */
- //OSSchedUnlock(&err);
-
- /* 记录截图后时间并获取截图过程耗时 */
- ulEnd = OSTimeGet(&err);
- ulEnd -= ulStart;
-
- App_Printf("截图完成,耗时 = %dms\r\n", ulEnd);
- Pic_Name++;
- }
- }
- }
复制代码后期这个任务将被升级,用于将波形数据以CSV文件格式存储到SD卡里面。
|