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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
设备为stm32L071,rtt是github上下载的最新版4.1.1。在调试pm功能时遇到问题:
3 \# @5 [) f/ s6 m1.可以进入STOP模式,tickless使用lptim,工作正常,软件定时器可以主动唤醒。6 g3 f% R: p$ u  t
2.当使用外部中断唤醒stop模式后,串口工作不正常,debug发现唤醒后竟然先执行了中断服务函数,然后切换到等待信号量的线程,直到idle后才会执行中的睡眠前的代码处,这时才执行恢复时钟函数。8 a9 U, ~. W. B; N5 F" w& h! \( T; D
pm睡眠前应该是禁用了全局中断的,只发生pending不执行ISR才对,为什么会有这种问题呢?5 @5 ]4 r( O) f, ~4 l

( c, \2 W7 h9 d# s. `! X2 cstatic void rx_thread_entry(void *param)
# m% p5 X/ j( I6 R{. o6 J3 m# ^1 q: Q
while(1)
4 R7 m1 X* g- w% t) J( r8 g8 [) j{- P: l1 @' o# N+ q+ K2 l) M
if (rt_sem_take(rx_sem, RT_WAITING_FOREVER) == RT_EOK). g$ v& w* o2 o; c% V) p
{* V+ U( }' o8 }9 S9 o1 T, q
rt_pm_sleep_request(PM_BOARD_ID, PM_SLEEP_MODE_NONE);
: N7 Y6 |. d. y. p( Ddo something //此时串口异常,LOG等功能输出乱码2 l1 E1 ^9 Y; Q; k( |% |
rt_thread_mdelay(5);  //执行到此处,才跳转到睡眠前位置,恢复时钟3 M+ x, _% n1 |8 T! L6 U: p
rt_thread_mdelay(5000);6 q  o) B/ \+ T) N' ]3 _5 ^% T' \4 ]2 t
rt_pm_sleep_release(PM_BOARD_ID, PM_SLEEP_MODE_NONE);
. p0 @( N9 ?( Y% h( f, [: o* l3 S}
* V  k) u. l8 [' d; g& ~}& x* }$ Q8 O. K" O. f
}7 ^8 u  C5 h3 r) h0 I& n+ U
void lora_rx_irq_callback(void *parameter)& n, [  w  _; J5 T) j
{; G0 v0 V! y" V3 b; s; N
rt_sem_release(rx_sem); //先执行此行,释放信号量; y- d) P/ F; m9 e/ t3 r  L1 n
}
7 Q% e, Y# J/ D7 q7 G4 v4 y$ Lpm适配代码如下:9 D& Q/ n! }0 y4 F# T
& Z( J0 X% P2 T! M3 U! ~5 F/ z
static void sleep(struct rt_pm *pm, uint8_t mode)
& U+ J) ~/ \! H7 r) a3 Y{$ I$ D( H" j0 q  X/ Z- t. A+ o
switch (mode): j; n( m# R# [, m& P  Z5 M
{7 H2 r* t: F, i! ~. d
case PM_SLEEP_MODE_NONE:
) W. f7 z9 z/ v4 S2 k/ dbreak;/ @/ A/ U% s, @0 o5 L
case PM_SLEEP_MODE_IDLE:  B! P8 x3 ]9 k; P( r
case PM_SLEEP_MODE_LIGHT:/ G# h1 B& D2 x! O0 ?
/* Enter SLEEP Mode, Main regulator is ON /. }( J4 c% C4 P  a
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);0 \7 |5 q, c5 }, j: r
break;
) S/ z# C7 U! @& l0 Icase PM_SLEEP_MODE_DEEP:
" ~3 {( w7 e6 X  a) M7 t6 A1 _/ Disable SysTick interrupt /
0 W( {( c+ j' H" |, ?, sCLEAR_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);: u, o5 G* O" A  x( B8 p; U. D
/ Enable the Ultra Low Power mode and the fast wake up /1 s0 `/ |8 K7 _  `7 ^0 j
SET_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);
" I1 Q$ K5 ~6 k/ Select HSI as system clock source after Wake Up from Stop mode /
8 r. c  k" e. X/ w; ]/ o//__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);2 X* C  S3 r+ j# s$ k
/ Enter STOP mode /
  o- E! E" \- N: `. LHAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
! Z% C/ q' O4 A: U6 ^/ Disable the Ultra Low Power mode and the fast wake up /
" a1 |2 A" ?  _4 f. K/ {CLEAR_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);3 u9 [7 N. g9 r' Y
/ Enable SysTick interrupt /1 z! @! f9 Z9 E: |
SET_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);+ I! F: o: A8 F* J" z0 h/ T6 ]
/ Re-configure the system clock /# V* g7 D# I; q; i2 Y% l
SystEMClock_ReConfig();* a' q# l5 l  z: p5 ~1 e$ ?2 W' R0 l
break;
  l) u+ U0 b4 H& D: o, l0 z/ qcase PM_SLEEP_MODE_STANDBY:" b2 Z" [& r8 J) T5 N; }8 N
case PM_SLEEP_MODE_SHUTDOWN:+ L8 W5 D" T: {. |' n- @
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);% j5 i$ E& \; B. J
/ Enter STANDBY mode */
( k/ k$ @7 j, k, R4 T2 d8 l7 DHAL_PWR_EnterSTANDBYMode();
+ F: A- p" p( ]. r+ R4 v9 G+ ybreak;
& n8 U: u. u/ v6 p- @9 ^0 Q: M, h7 K7 adefault:
  z/ {0 e; _8 j5 P4 R$ Q, zRT_ASSERT(0);) Y7 S. F0 y0 u; }' h( B
break;, L% O. x* W3 A# p$ A/ B$ }! x0 l3 h
}
9 X5 k7 T$ b( \* a9 Q0 ^4 G}1 L- K) P. d: C) r% ?6 J
# w$ p  _8 M5 X

# u5 i# N# @  x- u0% F2 z5 A9 n$ j3 q4 x" T' w! ?
7 F5 O% i/ \: L! f

该用户从未签到

2#
发表于 2022-9-7 13:13 | 只看该作者
那说明禁用全局中断响应 没有效果; U+ ]1 R, |: u

该用户从未签到

3#
发表于 2022-9-7 14:19 | 只看该作者
rt_hw_interrupt_disable() 应该要实现 __disable_irq 的效果才对,可以查下相关的手册,ARM Cortex 相关的,不同的Cortex 核,可能不一样。- \$ N  @, V3 `$ t
  • TA的每日心情
    开心
    2023-6-2 15:15
  • 签到天数: 1 天

    [LV.1]初来乍到

    4#
    发表于 2022-9-7 14:36 | 只看该作者
    主要问题是中断唤醒后代码执行顺序问题。8 K3 h$ W) {  v" H
    看了您的PM设计思想和代码,我理解的预期唤醒后执行顺序是:6 |1 u2 j* _* }1 ^9 I& M
    1.外部中断Pending
    1 W- r% d" }; W& o! u2.MCU唤醒,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断. k. N- e1 l& b/ X9 H+ C/ h8 y+ i
    3.执行ISR,释放信号量,通知等待信号量的线程1 V' q6 i4 v, [. A' y
    4.执行线程代码, m$ l/ Z, R6 B' x+ J6 S' W

    0 u: @& L% P0 W0 ?0 N4 }& t9 m6 t2 ]但实际加断点debug测出的执行顺序为:
    1 @2 {. D, N: c1.外部中断Pending
    $ r% U& j) |+ s5 z5 [2.执行ISR,释放信号量,通知等待信号量的线程
    / k2 R+ z- v+ L4 W" q3.执行线程代码
    4 ?6 v. X# k- B& h5 @$ t7 \4.等待idle,如延时函数,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断
    1 w5 ^6 p& H; U% J
    . _* u* W0 t; i& I. j$ U+ f7 `这就导致唤醒后时钟不对,且第一个延时函数会因为tick补偿直接超时,不会产生延时效果(1s、2s、3s、5s都测过不生效),我尝试加两次延时解决了。

    该用户从未签到

    5#
    发表于 2022-9-7 14:59 | 只看该作者
    楼上说的很不错
    8 K: y1 x. B- Q2 i- g2 t
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-9-8 14:35 , Processed in 0.125000 second(s), 23 queries , Gzip On.

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

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

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