pm_sample.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-12-15 liuhy first implementation.
  9. */
  10. /*
  11. * 程序清单:这是一个 pm睡眠唤醒的使用例程
  12. * 例程导出了 pm_sample 命令到控制终端
  13. * 命令调用格式:pm_sample
  14. * 命令解释:进入不同的睡眠模式,然后用按键唤醒
  15. * 程序功能:通过串口输出字符串,告知进入睡眠和唤醒睡眠的情况。
  16. */
  17. #include <rtthread.h>
  18. #include <rtdevice.h>
  19. #define PM_NAME "pm" /* 设备名称 */
  20. #define WAKE_UP_PIN 18 /* 唤醒源 */
  21. #define SLEEP_TIMES 12 /* 进入睡眠次数,轮流进入不同的睡眠模式,包括无睡眠模式 */
  22. struct pm_callback_t
  23. {
  24. volatile int in_fun_times; /*进入函数的次数*/
  25. volatile char flag; /*标志*/
  26. volatile int mode; /*需要打印的模式*/
  27. };
  28. volatile struct pm_callback_t g_pm_data;
  29. /*进入睡眠前,睡眠唤醒后,都会进入。*/
  30. /*函数打印睡眠相关的信息*/
  31. void sleep_in_out_callback(rt_uint8_t event, rt_uint8_t mode, void *data)
  32. {
  33. /*没有标志,不处理*/
  34. if(!(g_pm_data.flag))
  35. {
  36. return;
  37. }
  38. /*标志不正常,清空标志*/
  39. if((g_pm_data.flag) > 2)
  40. {
  41. (g_pm_data.flag) = 0;
  42. return;
  43. }
  44. /*模式不匹配*/
  45. if(g_pm_data.mode != mode )
  46. {
  47. return;
  48. }
  49. /*进入的事件*/
  50. switch(event)
  51. {
  52. /*进入睡眠前*/
  53. case RT_PM_ENTER_SLEEP: g_pm_data.flag = 1;
  54. rt_kprintf("\n\r##%d : ENTER ",g_pm_data.in_fun_times);
  55. g_pm_data.in_fun_times++; /*进入睡眠次数+1*/
  56. break;
  57. /*睡眠唤醒后*/
  58. case RT_PM_EXIT_SLEEP: g_pm_data.flag = 0; /*睡眠唤醒后*/
  59. rt_kprintf("\n\rEXIT\n\r");
  60. rt_pm_release(mode); /*释放休眠模式*/
  61. return;
  62. default: break;
  63. };
  64. /*当前的睡眠模式*/
  65. switch(mode)
  66. {
  67. case PM_SLEEP_MODE_NONE: rt_kprintf("PM_SLEEP_MODE_NONE\n\r");
  68. break;
  69. case PM_SLEEP_MODE_IDLE: rt_kprintf("PM_SLEEP_MODE_IDLE\n\r");
  70. break;
  71. case PM_SLEEP_MODE_LIGHT: rt_kprintf("PM_SLEEP_MODE_LIGHT\n\r");
  72. break;
  73. case PM_SLEEP_MODE_DEEP: rt_kprintf("PM_SLEEP_MODE_DEEP\n\r");
  74. break;
  75. case PM_SLEEP_MODE_STANDBY: rt_kprintf("PM_SLEEP_MODE_STANDBY\n\r");
  76. break;
  77. case PM_SLEEP_MODE_SHUTDOWN: rt_kprintf("PM_SLEEP_MODE_SHUTDOWN\n\r");
  78. break;
  79. case PM_SLEEP_MODE_MAX: rt_kprintf("PM_SLEEP_MODE_MAX\n\r");
  80. break;
  81. default: break;
  82. }
  83. }
  84. /* pm测试函数 */
  85. static void pm_test(void *parameter)
  86. {
  87. int in_mode[7],i = 0;
  88. g_pm_data.in_fun_times = 0;
  89. g_pm_data.flag = 0;
  90. in_mode[0] = PM_SLEEP_MODE_NONE;
  91. in_mode[1] = PM_SLEEP_MODE_IDLE;
  92. in_mode[2] = PM_SLEEP_MODE_LIGHT;
  93. in_mode[3] = PM_SLEEP_MODE_DEEP;
  94. in_mode[4] = PM_SLEEP_MODE_STANDBY;
  95. in_mode[5] = PM_SLEEP_MODE_SHUTDOWN;
  96. in_mode[6] = PM_SLEEP_MODE_MAX;
  97. /*设置回调函数和私有数据*/
  98. rt_pm_notify_set(sleep_in_out_callback,RT_NULL);
  99. while(i < SLEEP_TIMES)
  100. {
  101. g_pm_data.mode = in_mode[i%6];
  102. /*无休眠模式,不赋予标志*/
  103. if(g_pm_data.mode != PM_SLEEP_MODE_NONE)
  104. {
  105. g_pm_data.flag = 2;
  106. }
  107. /*请求选择的休眠模式*/
  108. rt_pm_request(in_mode[i%6]);
  109. rt_thread_mdelay(500);
  110. /*无休眠模式,不需要额外的等待*/
  111. while(( g_pm_data.flag != 0 )&&(g_pm_data.mode != PM_SLEEP_MODE_NONE))
  112. {
  113. rt_thread_mdelay(500);
  114. }
  115. /*释放选择的休眠模式*/
  116. rt_pm_release(in_mode[i%6]);
  117. i++;
  118. }
  119. /*清除回调函数和私有数据*/
  120. rt_pm_notify_set(RT_NULL,RT_NULL);
  121. rt_kprintf("thread pm_test close\n\r");
  122. }
  123. /*按键唤醒的回调函数*/
  124. void wake_by_pin(void *args)
  125. {
  126. }
  127. static int pm_sample(int argc, char *argv[])
  128. {
  129. rt_thread_t thread;
  130. /* 按键引脚为输入模式 */
  131. rt_pin_mode(WAKE_UP_PIN, PIN_MODE_INPUT_PULLUP);
  132. /* 绑定中断,下降沿模式,回调函数名为wake_by_pin */
  133. rt_pin_attach_irq(WAKE_UP_PIN, PIN_IRQ_MODE_RISING, wake_by_pin, RT_NULL);
  134. /* 使能中断 */
  135. rt_pin_irq_enable(WAKE_UP_PIN, PIN_IRQ_ENABLE);
  136. thread = rt_thread_create("pm_test", pm_test, RT_NULL, 1024, 25, 10);
  137. if (thread != RT_NULL)
  138. {
  139. rt_thread_startup(thread);
  140. }
  141. else
  142. {
  143. rt_kprintf("create pm_test thread failed!\n\r");
  144. }
  145. return RT_EOK;
  146. }
  147. /* 导出到 msh 命令列表中 */
  148. MSH_CMD_EXPORT(pm_sample, pm sample);