找回密码
 注册
关于网站域名变更的通知
查看: 218|回复: 4
打印 上一主题 下一主题

PM2.0外部中断唤醒后程序执行顺序异常为什么会发生这种情况呢

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-9-7 11:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
设备为stm32L071,rtt是github上下载的最新版4.1.1。在调试pm功能时遇到问题:
. e, j) L0 w( [$ M8 Z1.可以进入STOP模式,tickless使用lptim,工作正常,软件定时器可以主动唤醒。% n0 N, E7 o' _. z
2.当使用外部中断唤醒stop模式后,串口工作不正常,debug发现唤醒后竟然先执行了中断服务函数,然后切换到等待信号量的线程,直到idle后才会执行中的睡眠前的代码处,这时才执行恢复时钟函数。/ g0 K4 e# ]4 M! R/ @
pm睡眠前应该是禁用了全局中断的,只发生pending不执行ISR才对,为什么会有这种问题呢?
# `/ }5 U# }4 g; s: ?, w* R5 M9 A# |1 x% t8 e% R5 m
static void rx_thread_entry(void *param)
: B, Q5 R" j) G. g{8 p5 E( E# A+ B, a, U1 k* J. j
while(1)0 [7 Y/ B/ a" h/ f
{
. u9 T5 F2 i2 {' O# t& r3 zif (rt_sem_take(rx_sem, RT_WAITING_FOREVER) == RT_EOK)3 F5 h, o- Z0 Q
{3 U% ~4 D  Q( P
rt_pm_sleep_request(PM_BOARD_ID, PM_SLEEP_MODE_NONE);
+ Z0 H+ Q  c$ y9 P( q& O$ K- ~do something //此时串口异常,LOG等功能输出乱码1 i1 s" T* V! C3 C. {$ c6 L
rt_thread_mdelay(5);  //执行到此处,才跳转到睡眠前位置,恢复时钟  E; b! b+ n( _: R6 i$ C
rt_thread_mdelay(5000);# U+ e' U4 P8 B* V: P, U
rt_pm_sleep_release(PM_BOARD_ID, PM_SLEEP_MODE_NONE);, z; u5 K9 a* S1 U0 K" j
}0 d* b. y( A( |$ M
}
) b- ]9 j* H* b$ e. I}
" ~7 Q/ c8 z3 v  [8 \' b. ]& |/ Q/ ivoid lora_rx_irq_callback(void *parameter), f# S* r9 C5 Q3 h: J% i
{, m* b) x! o" h  }! u3 k7 }" Z
rt_sem_release(rx_sem); //先执行此行,释放信号量8 F  X$ V* f8 O; i7 w5 o7 P
}8 ~# q. j% _/ N1 E, N' ^  Y/ {
pm适配代码如下:
$ V; P/ b# c* p5 q6 y' E6 S
4 J: C8 N  a- ^3 {/ cstatic void sleep(struct rt_pm *pm, uint8_t mode)
5 h- h* C1 p( ^8 h; a{/ n" H+ Q5 n$ F( v4 K! f
switch (mode)4 }; j* J1 R& Z+ i$ I* {/ K. t" Q5 u$ x
{
6 s8 V: {2 ~. h, l9 C& xcase PM_SLEEP_MODE_NONE:
$ u( b7 D& h* H  ]; Qbreak;
: i  d% Z! i: w! h" A) Mcase PM_SLEEP_MODE_IDLE:6 u$ `4 Q, ]8 s# r* ]$ ?2 M
case PM_SLEEP_MODE_LIGHT:# a0 W9 Z5 f/ T4 P: b
/* Enter SLEEP Mode, Main regulator is ON /' ~2 @1 _4 u1 z7 W! V5 R
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
* \( x3 V. O* O# o  x9 D1 sbreak;
% K: i* C' T( h" {8 j# K- Wcase PM_SLEEP_MODE_DEEP:) {# S! I" u# k9 C! R/ i
/ Disable SysTick interrupt /, |% U2 b& X8 w+ F2 U/ A8 D/ S
CLEAR_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);
, F5 ?# ]4 ]/ e/ Enable the Ultra Low Power mode and the fast wake up /
  z- F+ V+ O) n9 F. g1 qSET_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);
% |5 K% ?' P% D) a8 {0 i6 ?) `/ Select HSI as system clock source after Wake Up from Stop mode /6 ~( x# w: V! F+ u( k$ j8 H, f
//__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
, M0 K; i- k. f4 Y% e! \% Z) Z) W+ _( q/ Enter STOP mode /$ k  m! |5 C! R. w
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
+ v2 P/ U) p5 @. n/ Disable the Ultra Low Power mode and the fast wake up /
: K0 v5 x, C+ K. r' K$ p) gCLEAR_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);
1 S# i  x# J/ H/ Enable SysTick interrupt /
! H/ F. Z7 H1 sSET_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);
$ e! q: U6 M, p. G0 B5 M; U" l" U/ Re-configure the system clock /
) U) S7 S3 y4 DSystEMClock_ReConfig();9 D7 C% g6 [3 s
break;
6 k) R/ `* ^4 {# Y6 N% lcase PM_SLEEP_MODE_STANDBY:' s' D) a* X/ \8 c
case PM_SLEEP_MODE_SHUTDOWN:" i' J( M1 w  |" [) k
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
& h$ z, i4 @2 z3 p: f" `! ^  F/ Enter STANDBY mode *// ~, w" K$ O3 c& ]
HAL_PWR_EnterSTANDBYMode();
. m# p4 b% `0 Y! w1 S. |# abreak;% D8 a- a3 ?9 d4 A
default:
6 Q$ m4 P* y5 K+ o: RRT_ASSERT(0);
( K) X( F0 T6 J2 Y! Lbreak;
2 G- a2 ^* I6 y% D, D}0 t, D9 V8 N1 U6 i  _9 r
}
, f. H- V8 V3 c5 A
5 N9 _! d# d$ _& h' I2 F5 m0 r- `$ z
0  q% d7 s- ^' r! U/ {% z* O! F* p
9 d1 V& C/ i$ t2 H

该用户从未签到

2#
发表于 2022-9-7 13:13 | 只看该作者
那说明禁用全局中断响应 没有效果
5 g! w! k- D8 _3 F; Q4 G

该用户从未签到

3#
发表于 2022-9-7 14:19 | 只看该作者
rt_hw_interrupt_disable() 应该要实现 __disable_irq 的效果才对,可以查下相关的手册,ARM Cortex 相关的,不同的Cortex 核,可能不一样。6 n  t2 `' ^8 O8 d) P$ P! G  b9 I7 ]# a
  • TA的每日心情
    开心
    2023-6-2 15:15
  • 签到天数: 1 天

    [LV.1]初来乍到

    4#
    发表于 2022-9-7 14:36 | 只看该作者
    主要问题是中断唤醒后代码执行顺序问题。% A/ T4 [+ a; V6 e8 S* [3 R
    看了您的PM设计思想和代码,我理解的预期唤醒后执行顺序是:
    + h. N+ N7 ]' B* f: I1.外部中断Pending
    7 I( Y+ C9 I8 j! F6 X8 @' O. O3 H7 O2.MCU唤醒,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断; X# q2 \  p5 ]  ^; w9 }
    3.执行ISR,释放信号量,通知等待信号量的线程$ G' Z( V$ E5 A9 C+ [
    4.执行线程代码
    : F+ e# e" T6 i3 c) L' p5 }6 m, i8 o6 Y) J' o9 }, W0 y
    但实际加断点debug测出的执行顺序为:6 M+ L0 @* @" Y2 u% x
    1.外部中断Pending2 ^! G+ u2 i8 ~# f
    2.执行ISR,释放信号量,通知等待信号量的线程
    # G4 N' t2 }* G7 w: U1 T: T5 I% n3.执行线程代码
    ' V$ w$ c2 o6 n. p, V) k  w4.等待idle,如延时函数,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断
    + R' M1 q, J) _7 N2 s
    1 i! v- T. i/ X' n" {* [这就导致唤醒后时钟不对,且第一个延时函数会因为tick补偿直接超时,不会产生延时效果(1s、2s、3s、5s都测过不生效),我尝试加两次延时解决了。

    该用户从未签到

    5#
    发表于 2022-9-7 14:59 | 只看该作者
    楼上说的很不错
    7 W0 s8 @" ?# D" k9 d7 T
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-8-19 21:19 , Processed in 0.109375 second(s), 23 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表