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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
设备为stm32L071,rtt是github上下载的最新版4.1.1。在调试pm功能时遇到问题:5 M) d# S5 ~/ |" B
1.可以进入STOP模式,tickless使用lptim,工作正常,软件定时器可以主动唤醒。
: F8 m, j# d3 i' }2.当使用外部中断唤醒stop模式后,串口工作不正常,debug发现唤醒后竟然先执行了中断服务函数,然后切换到等待信号量的线程,直到idle后才会执行中的睡眠前的代码处,这时才执行恢复时钟函数。
3 r3 q! [& N' |7 f7 O3 `pm睡眠前应该是禁用了全局中断的,只发生pending不执行ISR才对,为什么会有这种问题呢?: y( Z* \1 o; d. p$ P

, Z( X, I3 w$ w1 Kstatic void rx_thread_entry(void *param)
1 i0 B7 @( [5 Y! G{) m0 _6 q0 ?$ N* @# c' T$ a* i
while(1)3 i6 S+ X4 H; K# _/ [
{: D* r2 O1 n( t9 U5 W
if (rt_sem_take(rx_sem, RT_WAITING_FOREVER) == RT_EOK)9 i. U5 F  V- @- Z6 B5 ?  g
{
. Z6 V5 }& L$ F1 B* P9 qrt_pm_sleep_request(PM_BOARD_ID, PM_SLEEP_MODE_NONE);3 |% F% b' A& {' H0 E1 U: Q+ e
do something //此时串口异常,LOG等功能输出乱码
, G4 r' j8 E( j6 grt_thread_mdelay(5);  //执行到此处,才跳转到睡眠前位置,恢复时钟& ?; A9 H1 f+ ]3 X( ^, i5 F
rt_thread_mdelay(5000);
" J1 P  ~9 f& u& E4 c. @3 i* H( prt_pm_sleep_release(PM_BOARD_ID, PM_SLEEP_MODE_NONE);. p+ z' @' i: w) N( o0 `
}
0 F$ [% S6 I3 G6 ~% X5 `}
2 x3 V/ n( p6 i# |4 F  P8 }' p9 E}
& x; B6 U+ f7 V" s: x4 N, mvoid lora_rx_irq_callback(void *parameter)
# n. ?8 h& \( t( }& `7 k9 q" y$ R{
3 L. d5 y! y2 Frt_sem_release(rx_sem); //先执行此行,释放信号量2 |9 g2 |( f4 X$ S* [# K
}4 G$ r+ {- j- J4 H7 C
pm适配代码如下:  i% I" {$ w' v3 g
& ?. h* V7 w7 X; g
static void sleep(struct rt_pm *pm, uint8_t mode)
6 p+ T5 u& t6 ^, c{
! p; S8 h, R  [' ^4 N6 Rswitch (mode)
5 c0 Q) A! O) ?0 B' A2 k- V{$ ]9 r- V. `$ r) ^/ [2 R" H; v- a
case PM_SLEEP_MODE_NONE:
9 ~( k% y! _! k: F/ ~# _3 _8 [break;
9 k/ a0 q3 Z" c9 s2 C" L- L" Fcase PM_SLEEP_MODE_IDLE:
% F2 v5 V4 J! O* p' Mcase PM_SLEEP_MODE_LIGHT:# [+ |4 G3 Y$ Z9 @
/* Enter SLEEP Mode, Main regulator is ON /
6 t, b- ?! m8 S) ^' vHAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
& U1 g' I7 p' Z. r6 Ubreak;
$ @! [  m& T" `7 }2 A0 ~) Ecase PM_SLEEP_MODE_DEEP:
" U8 ^! \7 h% g' K3 d) f) m/ Disable SysTick interrupt /
/ l( g( P7 z4 lCLEAR_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);
' S, d/ M9 k: {2 c( R5 S  \/ Enable the Ultra Low Power mode and the fast wake up /+ ]: a9 ^" q7 |* n  E. x( I( b8 h
SET_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);
, l9 g/ S+ I- ]5 y' E! ~0 C/ Select HSI as system clock source after Wake Up from Stop mode /
, y) i9 y/ T  D0 C" _$ }//__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
, l- K  G* T; r% f, K/ Enter STOP mode /7 q6 e2 X; h2 j
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
7 b: y0 m2 A9 u/ Disable the Ultra Low Power mode and the fast wake up /
, p/ U8 y0 i! s" @6 z0 jCLEAR_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);
7 g" d2 T$ t6 j2 V0 D% |8 l/ Enable SysTick interrupt /
5 p" Z# ?% A- r6 c" c3 }SET_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);2 s# Q( A+ l. J( C. z, r2 u
/ Re-configure the system clock /
; a! `3 N3 z/ ^6 XSystEMClock_ReConfig();
, w/ }$ k' K6 X2 Hbreak;
, S8 R1 k; _' l  ]8 {case PM_SLEEP_MODE_STANDBY:* j# n$ y, H- y: {& H
case PM_SLEEP_MODE_SHUTDOWN:- h, X' r4 P9 g
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);2 Y: ]8 i9 a4 c  o
/ Enter STANDBY mode */
& P5 q% d2 x- Q1 s$ o# W- pHAL_PWR_EnterSTANDBYMode();  ]! o% X8 M! E) b% ~4 C
break;
. U) D1 q8 G7 @' x9 F7 t4 {7 y# Sdefault:* F8 U* N2 r4 u; z+ F
RT_ASSERT(0);
4 R4 m$ }0 v1 p) ]/ l2 h6 ubreak;' H% k4 O+ z) n; M4 q* n6 ~
}8 a: g5 H% k( @* `% n7 o
}
9 V# [+ U8 [. G* A2 H: a. _
; {4 }( t$ L/ G  M
, h6 ]1 D5 m( x% b; ?0
' Q  @" k& m( v  C% y' h# R0 ]2 F/ K
1 g! g* g# D  t# [9 Y7 B

该用户从未签到

2#
发表于 2022-9-7 13:13 | 只看该作者
那说明禁用全局中断响应 没有效果
' o0 ?+ `+ k  B: h5 j+ j4 b' g

该用户从未签到

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

    [LV.1]初来乍到

    4#
    发表于 2022-9-7 14:36 | 只看该作者
    主要问题是中断唤醒后代码执行顺序问题。5 i; d5 T# a4 J8 e7 M+ s
    看了您的PM设计思想和代码,我理解的预期唤醒后执行顺序是:
    % X) M# L' K( W- `1.外部中断Pending
    1 Y6 I" l0 p; q, a$ i6 u+ ~6 C2.MCU唤醒,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断
    1 S& x/ O1 |) v$ g; N3.执行ISR,释放信号量,通知等待信号量的线程. i/ a  g4 _, I$ m
    4.执行线程代码
    9 X- Z3 Q6 G; G5 f2 k* q1 b' s6 g+ W* e- F4 V/ J/ G5 [; h
    但实际加断点debug测出的执行顺序为:
    6 N% t7 L3 }+ x& k. \- W5 S1.外部中断Pending
    $ M- P( [- A5 [# x' S: X2.执行ISR,释放信号量,通知等待信号量的线程# }8 |' S% ]' }% O& r% {9 z
    3.执行线程代码
    ; H6 \7 D# x7 Z( z# {8 ~4.等待idle,如延时函数,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断7 q" W! y. s+ l% O& j
    / }/ }8 Q$ j, e
    这就导致唤醒后时钟不对,且第一个延时函数会因为tick补偿直接超时,不会产生延时效果(1s、2s、3s、5s都测过不生效),我尝试加两次延时解决了。

    该用户从未签到

    5#
    发表于 2022-9-7 14:59 | 只看该作者
    楼上说的很不错! I. I2 ]$ E6 @: e- K& f" V
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-24 10:56 , Processed in 0.140625 second(s), 23 queries , Gzip On.

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

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

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