嵌入式应用之-任务

举报
内核笔记 发表于 2021/06/08 23:25:00 2021/06/08
【摘要】 嵌入式应用之-任务 首先复习下前两节 1、任务进程框架 2、初始化 上一节中并没有说上电,下电,复位时单片机具体初始化哪些资源,现在补充下。 /* 上电、单片机资源初始化 * 1、喂狗 * 2、配置系统时钟 * 3、清除中断标识 * 4、屏蔽所有中断 * 5、关闭所有定时器 * 6、关闭所有通讯口 * 7、关闭按键检测 * 8、关闭AD...

嵌入式应用之-任务

首先复习下前两节

1、任务进程框架

2、初始化

上一节中并没有说上电,下电,复位时单片机具体初始化哪些资源,现在补充下。

/* 上电、单片机资源初始化 
 * 1、喂狗
 * 2、配置系统时钟
 * 3、清除中断标识
 * 4、屏蔽所有中断
 * 5、关闭所有定时器
 * 6、关闭所有通讯口
 * 7、关闭按键检测
 * 8、关闭AD
 * 9、配置4.096ms系统时基
 */ 
#define MCU_PWU_INIT()do{\
 ClearWatchDog();\
 CONFG_SYS_CLOCK();\
 CLR_ALL_IRQ_FLAG();\
 ALL_IRQ_DISABLE();\
 CLOSE_ALL_TIMER();\
 CLOSE_ALL_COMM();\
 KRM_ALL_DISABLE();\
 CLOSE_AD();\
 CONFIG_4MS();\
}while(0)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

/* 下电、单片机资源初始化 
 * 1、喂狗
 * 2、清除中断标识
 * 3、屏蔽所有中断
 * 4、关闭所有定时器
 * 5、关闭所有通讯口
 * 6、关闭按键检测
 * 7、关闭AD
 */ 
#define MCU_PWD_INIT()do{\
 ClearWatchDog();\
 CLR_ALL_IRQ_FLAG();\
 ALL_IRQ_DISABLE();\
 CLOSE_ALL_TIMER();\
 CLOSE_ALL_COMM();\
 KRM_ALL_DISABLE();\
 CLOSE_AD();\
}while(0)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

/* 初始复位、单片机资源初始化 
 * 1、喂狗
 * 2、清除中断标识
 * 3、屏蔽所有中断
 * 4、关闭所有定时器
 * 5、关闭所有通讯口
 * 6、关闭按键检测
 * 7、关闭AD
 * 8、配置系统时钟为内部8MHz,外设时钟为内部8MHz
 */ 
#define MCU_RESET_INIT()  do{\
 ClearWatchDog();\
 CLR_ALL_IRQ_FLAG();\
 ALL_IRQ_DISABLE();\
 CLOSE_ALL_TIMER();\
 CLOSE_ALL_COMM();\
 KRM_ALL_DISABLE();\
 CLOSE_AD();\
 ConfigSysClock(POWER_ON);\
}while(0)

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

void SystemInit(void);
__INLINE void SystemInit(void)
{
DisableAllInt();// 关闭总中断
SET_CHIP_RAM_ROM(); // 容量选择
#if ((USE_MCU==MCU_ML610Q496A)&&(USE_COMPILE==IDEU8))
WatchDogInit(); // 看门狗设置
#endif
ClearWatchDog();// 喂狗
MCU_RESET_INIT();   // 初始配置
InitGui(POWER_OFF_AFTER);   // 配置引脚为低功耗状态
SystemPowerCheckInit(); // 开启电源检测


ucPowerOnStatus = GAL_NO;  // 电源状态
gSystemRunMode = SYSTEM_RESET; // 系统状态 ucSystemBusy = 0;
#if (CONFIG_METER_POWERRESIDUE_PRICE_RECORD_MODE_ENABLE == CONFIG_METER_POWERRESIDUE_PRICE_RECORD_MODE)
INITMeterFlag = PLUSERESIDUE_CHECKWORD;//电表上电初始化完成标志 jingcheng@20161208
#endif

#if (CONFIG_SYSTEM_STATE==GAL_YES)
if (IF_WATCHDOG_RESET())  // 看门狗标识在POR复位时清零
{
CLEAR_WATCHDOG_RESET();
SystemState.ResetWatchdog++;  // 看门狗复位次数 需要减去电源复位次数
WriteDataDouble((u8*)&SystemState.ResetWatchdog, EPL_SYSTEM_ERROR_STATUS_BLOCK+52, 4);
}
else
{
// 从eeprom恢复
ReadDataDouble(EPL_SYSTEM_ERROR_STATUS_BLOCK, sizeof(SystemState), (u8*)&SystemState);
SystemState.ResetAbnormal++;  // 异常复位次数
WriteDataDouble((u8*)&SystemState.ResetAbnormal, EPL_SYSTEM_ERROR_STATUS_BLOCK+56, 4);
}
#endif

if(GetACPowerStableStatus(&ucPowerOnStatus)==AC_POWER_OFF)// 下电,电池短接
{
if ((RunCPUToDifferentPowerMode(SYSTEM_RESET) == GAL_YES) // 先配置寄存器
 && (InitializeVariable(SYSTEM_RESET) == GAL_YES))// 再配置变量
{
}
else
{
// 初始化中发生了上电
#if (CONFIG_SYSTEM_STATE==GAL_YES)
SystemState.ResetPower++;  // 电源复位次数
WriteDataDouble((u8*)&SystemState.ResetPower, EPL_SYSTEM_ERROR_STATUS_BLOCK+48, 4);
#endif
RESET();
}
gSystemRunMode=POWER_OFF;
}
else  // 上电
{
gSystemRunMode=POWER_ON;

if ((RunCPUToDifferentPowerMode(POWER_ON) == GAL_YES) // 先配置寄存器
 && (InitializeVariable(POWER_ON) == GAL_YES))// 再配置变量
{
EnableAllInt();   // 配置成功,开启总中断
#if (CONFIG_METER_POWERRESIDUE_PRICE_RECORD_MODE_ENABLE == CONFIG_METER_POWERRESIDUE_PRICE_RECORD_MODE)
INITMeterFlag = 0;
#endif
}
else
{
OverPowerOnIntial();  // 配置过程中掉电,进行下电初始化,为防止误存,不进行掉电保存
}
}
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

现在将其简化:任务去掉了子任务。

void main( )
{
SystemInit();   // 系统初始化
InitilaRunTask();   // 任务初始化
 while(1)
{ ClearWatchDog(); // 掉电检测 if (IfPowerDown()) { CheckPowerDownAgain(); // 再检一次,稳定后进入低功耗模式,否则跳出 } else { if (gSystemRunMode == POWER_OFF) // 由下电到上电 { // 去抖动 if (GetACPowerStableStatus(&ucPowerOnStatus) == AC_POWER_ON) { gSystemRunMode=POWER_ON; #if (CONFIG_SYSTEM_STATE==GAL_YES) SystemState.ResetPower++;  // 电源复位次数 WriteDataDouble((u8*)&SystemState.ResetPower, EPL_SYSTEM_ERROR_STATUS_BLOCK+48, 4); #endif RESET(); // 电源稳定,复位以重新配置时钟 yxy2015.4.7 } } // 主循环中需要每个循环都要进行通信数据处理;以提高通信任务的实时性;zpf_2015.8.5 RunCommunicate(); // 主循环中需要每个循环都要进行时钟模块的运行,以提高软时钟的精确度,以及秒任务的及时性;zpf_2015.8.5 RunRTC(POWER_ON); // 运行其他条件满足 if(ConditLim[RunTaskTab[RunNO].ConditLimNO]()==GAL_YES) { RunTaskTab[RunNO].RunTask(); } if (++RunNO >= RUN_TASK_NUM) // END of the task table { RunNO = 0x00; if(gucSystemRestOk<=CON_SYSTEM_REST_OK) { gucSystemRestOk++; } SystemIdle(); } } }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

最后这里分析下任务:

const STR_RUN_TASK_TAB RunTaskTab[]=
{
//   运行的任务名称运行的条件限制  
{TaskPack1,0},  // 任务包1
{PriceSwitchMode,  0},  // 费率切换  
{TaskEnergyCal,0},  // 电量处理(计算,累加)
{FreezeMode,   0},  // 瞬时冻结/整点/日冻结/定时冻结
{RestoreMode,  0},  // 结算
{ModeMeter,0},  // 计量芯片 
{TaskPack2,1},  // 任务包2 
{ProgramEventMode, 0},  // 清零回调函数 
{CoefPowerCheck,   0},  // 参变量校验
{Rcomm645Control,  0},  // 通讯处理
{Display,  0},  // 显示处理 {TaskPrepay,   0},  // 预付费 必须放在通信程序的后面
{TaskRecord,   0},  // 负荷记录
};

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

我们这里先看看显示任务:

void Display(void)
{
#if defined(__AP_DISPLAY__)||defined(__SYSTEM_MINIMUM__)
if(displayControl.displayRefalshEn)  /* 显示刷新标志 */
{
MamageExtInput(); // 非循显显示的判断,屏幕内容有变还是模式改变,上下翻什么的置flag=1
DisplayTimeManage();  // displayFlag=1 lcdswich =1 模式切换了 置displayRefalshFlag
}
if(displayControl.displayRefalshFlag)  //刷新内容DisplayTimeManage 和 按键循显澹通过RefeshDispFlgBySec置displayflag每秒或者按键1屏结束(通过置displayflag) 刚上电
{
displayControl.displayRefalshFlag = 0; DisplayTurnPage();   //turn page 翻屏

memset(apiDisMemory.disStatus, 0x00, sizeof(UN_DIS_STATUS)); // yxy 2015.12.23

if(!DisplayPrivateSegment())//display private segment; include data and symbol
{
DisplayPublicSegment();  
ReflashDisplayMemory();  
}
}
#endif
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

待续——-

文章来源: xuesong.blog.csdn.net,作者:内核笔记,版权归原作者所有,如需转载,请联系作者。

原文链接:xuesong.blog.csdn.net/article/details/78144225

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。