[uCOS/RTOS]

RTOS 电源管理设计

[复制链接]
1208|7
手机看帖
扫描二维码
随时随地手机跟帖
leihen0525|  楼主 | 2018-8-22 10:46 | 显示全部楼层 |阅读模式
讨论一个问题,小弟从事汽车电子行业多年,最近手头项目上了我历时几个月写的实时操作系统,考虑是电动车项目,功耗必然是个大问题,在OS设计之初的时候并没有把电源管理当回事,结果电源管理部分很难和OS完美融合,参考目前众多RTOS的电源管理,似乎这一块设计都很薄弱,感觉并没有把嵌入式的低功耗问题考虑进去,不知道大家对这一块有没有什么好的思路推荐。
先用我手头这个上了系统的项目举个例子:
平台是KEA128 ARM M0+内核的芯片,
按照M0内核的功耗有三种 RUN WIAT STOP
我OS启动会创建一个空闲任务,空闲任务默认进入WAIT
开一个超时定时器 留有一个给任务的API可以重设定时器时间
当定时器时间到 设计空闲任务进入就直接进入STOP 并且开启RTC定时唤醒系统
问题吧 就在这 RTC唤醒后重置定时器时间并且设置空闲进入WAIT 我只是期望唤醒后只执行一些唤醒事件检查任务 但是吧 起初设计系统没有考虑电源管理框架和任务调度的问题 当唤醒后 自然就所有任务都跑起来了
不知道大家有没有这方面经验 比如在睡眠模式下冻结部分任务?

相关帖子

leihen0525|  楼主 | 2018-8-22 10:51 | 显示全部楼层
按照汽车上 KL15 IGN作为唤醒和睡眠的信号 我将这个信号设计为 主动睡眠
而我想 要OS具备一个合适的自动睡眠策略 可以根据任务的需求 来动态的降低功耗
已经困扰快一个星期了 不知道 有没有对操作系统 电源管理特别有见解的人 讨论一下这个问题

使用特权

评论回复
airwill| | 2018-8-27 07:00 | 显示全部楼层
你首先得理清楚,  那些需要休眠, 什么条件休眠.
本身休眠的问题不算是 RTOS 内核要管理解决的问题.

什么 RTOS, M0 应该跑不了太复杂的 OS.

使用特权

评论回复
caijie001| | 2018-8-27 13:39 | 显示全部楼层
用os就别要低功耗吧,,,,os是为了快速响应跟线程管理的。低功耗那些裸机就好了呗

使用特权

评论回复
leihen0525|  楼主 | 2018-8-28 14:26 | 显示全部楼层
airwill 发表于 2018-8-27 07:00
你首先得理清楚,  那些需要休眠, 什么条件休眠.
本身休眠的问题不算是 RTOS 内核要管理解决的问题.

我可能是受到Windows系统的影响
不过好在理清楚一些问题
OS还是要跑起来的
我设计的初衷是想让OS做更多的事情 task可以减少设计复杂度

使用特权

评论回复
leihen0525|  楼主 | 2018-8-28 14:29 | 显示全部楼层
caijie001 发表于 2018-8-27 13:39
用os就别要低功耗吧,,,,os是为了快速响应跟线程管理的。低功耗那些裸机就好了呗 ...

低功耗吧 在车上 点火开了 一般就不考虑功耗 至少目前汽车电子 是这样的
只有点火关了 功耗要求还是很高的 毕竟长时间蓄电池会亏电
毕竟现在单片机很强 嵌入式跑OS很正常 当然嵌入式功耗电源还是很重要的 不是么

使用特权

评论回复
leihen0525|  楼主 | 2018-8-28 14:39 | 显示全部楼层
void Power_Idle_Task(void* pdata)
{
        UART_Init();
        Uart_SendChar(0xEF);
        Power_Init();


        Timer_Init();//定时器初始化

        //System_Debug_Init();

        Services_Init();//服务组件

        Application_Init();//应用程序


        while(1)
        {
                //喂狗
                API_User_WDOG_Refresh();

                switch (Power.Power_Status)
                {
                        //1.设置进入Stop时间为1S
                        //2.设置当前进入模式为wait模式
                        case Power_Status_Init:
                        {
                                Power_RTC_SET_Time_User(1000,false);
                                API_User_SOC_Enter_Wait_Mode();

                                Power.Power_Status=Power_Status_Runing;
                        }break;

                        //1.设置当前在wait模式下运行时间为20MS
                        //2.设置当前进入模式为wait模式
                        //3.开启任务调度系统
                        case Power_Status_Enter_Wait:
                        {
                                Power_RTC_SET_Time_User(20,false);

                                API_User_SOC_Enter_Wait_Mode();
                                API_User_OS_Resume();

                                Power.Power_Status=Power_Status_Runing;

                        }// @suppress("No break at end of case")

                        //进入低功耗模式
                        case Power_Status_Runing:
                        {
                                asm("wfi");

                        }break;

                        //1.关闭任务调度系统
                        //2.设置当前进入低功耗模式
                        //3.设置唤醒stop模式时间为1S
                        case Power_Status_Enter_Stop:
                        {
                                API_User_OS_Suspend();
                                API_User_SOC_Enter_Stop_Mode();
                                Power_RTC_SET_Time_User(1000,false);

                                Power.Power_Status=Power_Status_Stoping;
                        }// @suppress("No break at end of case")

                        //进入低功耗模式
                        case Power_Status_Stoping:
                        {
                                asm("wfi");
                        }// @suppress("No break at end of case")

                        //1.检查当前唤醒信号是否有效
                        //2.如果唤醒信号有效则进入wait模式
                        case Power_Status_Check_WakeUp_Signal:
                        {
                                Function_Groups_Run(&Power.FGN,Null,Power_Check_WakUp);
                        }break;

                        default:
                        {

                        }break;
                }


        }

}
static void Services_Sleep_Task(void *pdata)
{

        Services_Input_Link_Event_Flag_Group();


        while(1)
        {
                switch (Services_Sleep.Status)
                {
                        case Services_Sleep_Status_Init:
                        {
                                Function_Groups_Init(&Services_Sleep.Operation_Function);
                                Services_Sleep.Status=Services_Sleep_Status_Enter_WakeUp;
                                API_User_Wait_Enter_Stop_Times(1000,true);
                                API_User_Sleep(50);
                        }break;

                        case Services_Sleep_Status_Runing:
                        {

                                Event_Return_Type ER=Services_Input_Wait_Status(SI_IGN_IN,IO_OFF,100);
                                if(ER==Event_Return_OK)
                                {
                                        API_User_Wait_Enter_Stop_Times(1000,true);

                                        API_User_Sleep(500);

                                        if(Services_Input_GET_Status(SI_IGN_IN)==IO_OFF)
                                        {
                                                Services_Sleep.Status=Services_Sleep_Status_Enter_Sleep;
                                                API_User_Wait_Enter_Stop_Times(1000,true);
                                        }
                                        else
                                        {
                                                ;
                                        }
                                }
                                else if(ER==Event_Return_Time_Out)
                                {
                                        API_User_Wait_Enter_Stop_Times(1000,true);
                                }
                                else
                                {
                                        API_User_Sleep(100);
                                }
                        }break;
                        case Services_Sleep_Status_DeepSleep:
                        {
                                if(Services_Input_Wait_Status(SI_IGN_IN,IO_ON,-1)==Event_Return_OK)
                                {
                                        Services_Sleep.Status=Services_Sleep_Status_Enter_WakeUp;
                                }
                        }break;

                        case Services_Sleep_Status_Enter_WakeUp:
                        {
                                API_User_Wait_Enter_Stop_Times(1000,true);

                                Function_Groups_Run(&Services_Sleep.Operation_Function,(void *)Services_Sleep_Operation_Enter_WakeUp,Null);
                                //API_User_Timer_WakeUp();
                                Services_Sleep.Status=Services_Sleep_Status_Runing;


                        }break;
                        case Services_Sleep_Status_Enter_Sleep:
                        {
                                Function_Groups_Run(&Services_Sleep.Operation_Function,(void *)Services_Sleep_Operation_Enter_Sleep,Null);
                                //API_User_Timer_Sleep();
                                Services_Sleep.Status=Services_Sleep_Status_DeepSleep;
                        }break;

                        default:
                        {
                                API_User_Sleep(100);
                        }break;
                }

        }
}

既然没有朋友有实质性结果 我就把思路贴出来吧 上面两个任务 第一个是系统空闲任务 优先级最低 属于内核任务 第二个是服务类任务 因为我的内核设计是微内核架构 第二个服务是检查IGN主动睡眠 第一个是 OS自动根据任务需求睡眠 唤醒 运行等需求 整体在睡眠下功耗做到了0.5MA 低于客户要求的1MA 有需要的小伙伴们可以了解一下

使用特权

评论回复
caijie001| | 2018-8-28 18:37 | 显示全部楼层
leihen0525 发表于 2018-8-28 14:29
低功耗吧 在车上 点火开了 一般就不考虑功耗 至少目前汽车电子 是这样的
只有点火关了 功耗要求还是很高 ...

你也可以这样理解,反正看情况需要吧,嵌入式这个东西就是可裁剪的,专向设备

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

55

帖子

3

粉丝