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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
设备为stm32L071,rtt是github上下载的最新版4.1.1。在调试pm功能时遇到问题:' z6 |8 Q# s* j1 i1 c
1.可以进入STOP模式,tickless使用lptim,工作正常,软件定时器可以主动唤醒。
( T2 o$ f8 ?3 h4 C# n$ i$ f2.当使用外部中断唤醒stop模式后,串口工作不正常,debug发现唤醒后竟然先执行了中断服务函数,然后切换到等待信号量的线程,直到idle后才会执行中的睡眠前的代码处,这时才执行恢复时钟函数。
, B+ t  s$ ]. |, f# c; }4 Ipm睡眠前应该是禁用了全局中断的,只发生pending不执行ISR才对,为什么会有这种问题呢?
$ a# [7 y9 `, }' i# x4 ^8 J- u6 b" a- r* h
static void rx_thread_entry(void *param)
9 p/ i4 h  |9 F* Y$ V4 E{
1 V. g( O3 V6 u6 X1 r9 swhile(1)
9 j2 z  X1 i# l% B) K{1 F; M+ ~1 ~  Z; d, \
if (rt_sem_take(rx_sem, RT_WAITING_FOREVER) == RT_EOK). x  F1 [- g5 X9 j. A
{
8 D$ `* j: a8 M9 H8 qrt_pm_sleep_request(PM_BOARD_ID, PM_SLEEP_MODE_NONE);
6 }& f8 e- y) k; W6 Q$ Fdo something //此时串口异常,LOG等功能输出乱码0 }7 l' D$ Y( x- ]* D( u, ]  |
rt_thread_mdelay(5);  //执行到此处,才跳转到睡眠前位置,恢复时钟
3 X# y8 r# L0 s8 Z* Nrt_thread_mdelay(5000);
5 l; x+ z, l7 R; I+ Crt_pm_sleep_release(PM_BOARD_ID, PM_SLEEP_MODE_NONE);
) v: e" }) j' E- K& m0 v$ |}0 t0 P  a* h, _- U! N" J
}- U9 X# b7 H2 t* H$ x
}
. d4 R2 ~* B* y& K0 k# vvoid lora_rx_irq_callback(void *parameter)
( l  t$ a7 [; n( m* U+ p{
8 R' C- t- i- b3 m4 x1 v6 f7 Nrt_sem_release(rx_sem); //先执行此行,释放信号量; L) ?/ d& {6 s3 \9 |' g; A
}
. n' @2 e  |1 `& Kpm适配代码如下:7 B# l$ ^( s( U- ]+ X  j
; k8 a# X7 ]' x/ n! V( J2 D4 }" R
static void sleep(struct rt_pm *pm, uint8_t mode)  ^. W9 H- Q" X$ y
{! k  p) b* y! T2 K$ P6 `6 h
switch (mode); G2 T3 V$ o0 f' ?, E
{
0 V  i/ l% X! m6 mcase PM_SLEEP_MODE_NONE:
# r  P# T6 l7 z; ~# ^% ]7 Tbreak;
6 Y" m) V! i! a- i. B% {1 zcase PM_SLEEP_MODE_IDLE:3 P7 h9 u+ {; S+ t" v
case PM_SLEEP_MODE_LIGHT:
" I+ D# K3 d) q( t4 L/* Enter SLEEP Mode, Main regulator is ON /( U" c  q+ N0 J$ |
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);1 N0 b6 Y! ], s& i% g( E; b
break;/ }6 E: u# x( f& e2 C8 G# }) Z
case PM_SLEEP_MODE_DEEP:' c# ^/ Q3 E- E
/ Disable SysTick interrupt /
' C( r. a# r% c* ^) {7 y7 X7 iCLEAR_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);
; f% A6 @+ j* i# ?$ |* ~/ Enable the Ultra Low Power mode and the fast wake up /3 L; C% X0 r: c3 {( ^, m% Y
SET_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);- Z  r9 e9 c: U$ X2 v
/ Select HSI as system clock source after Wake Up from Stop mode /
: t3 v8 r/ z6 L. B//__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);- c+ h4 Y9 D+ v! b* v. h" m
/ Enter STOP mode /
$ _6 R+ e! V) d/ VHAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
( v# E% `6 F/ B$ ?/ Disable the Ultra Low Power mode and the fast wake up /% O! g* x+ }9 X7 C9 |
CLEAR_BIT(PWR->CR, PWR_CR_ULP | PWR_CR_FWU);
# G4 `- e4 p' [4 j& m) g/ Enable SysTick interrupt /5 ~0 a( f/ z& W% v+ h
SET_BIT(SysTick->CTRL, (rt_uint32_t)SysTick_CTRL_TICKINT_Msk);
9 W( p7 @& |# l7 j" p/ Re-configure the system clock /
0 m: D: X% `* G' wSystEMClock_ReConfig();/ x- u' j5 [5 r( U
break;
0 ~1 b% h( n+ ~  P5 N5 \8 icase PM_SLEEP_MODE_STANDBY:7 o. Q4 j! d/ j5 w! s& q3 }3 n( r/ u
case PM_SLEEP_MODE_SHUTDOWN:7 Q# {: I& F/ c! O3 Y1 \0 V2 \
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);$ e% Z) u  ^4 ~0 w3 Q/ e
/ Enter STANDBY mode */
# ?! Y- D+ i2 y. s& w9 mHAL_PWR_EnterSTANDBYMode();
, C/ p3 x. l# j5 l* E  Gbreak;! R9 f. h( i( ~0 h% V% X
default:7 c4 N7 _* ]2 J8 i  ?
RT_ASSERT(0);
  a2 o& g6 b! z5 jbreak;( h6 F1 h# y2 e! C: h  x! a
}4 \# o/ X& g; G" y" k, l& I
}& F" k! s& Y8 t  |9 o1 Y: v, h
: D" |" ~( V: z  }" q4 S, s

6 M' [0 L* V9 J5 N2 z0. f/ G# W* X; R) P
5 `( `) O+ C, Z" L6 d9 `

该用户从未签到

2#
发表于 2022-9-7 13:13 | 只看该作者
那说明禁用全局中断响应 没有效果
9 d! Y; l& {/ J& v$ }& b

该用户从未签到

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

    [LV.1]初来乍到

    4#
    发表于 2022-9-7 14:36 | 只看该作者
    主要问题是中断唤醒后代码执行顺序问题。
    8 j, A; _/ n1 ]/ c7 w$ o7 O* i看了您的PM设计思想和代码,我理解的预期唤醒后执行顺序是:2 F1 v; k* g6 a& d% i
    1.外部中断Pending/ L3 t$ a! u  d
    2.MCU唤醒,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断; [% g& i6 Y" m
    3.执行ISR,释放信号量,通知等待信号量的线程$ {7 r4 f: O. R) S  Y* S1 I2 ~
    4.执行线程代码
    3 q* @7 p+ `6 ^( `/ U7 k* W! L/ [
    但实际加断点debug测出的执行顺序为:, C, H7 c) R9 g7 n
    1.外部中断Pending1 c" `" d. {- e! r
    2.执行ISR,释放信号量,通知等待信号量的线程) F( q5 ~! ?% f; q) m& z5 T
    3.执行线程代码
    ( t+ Z) B3 ?/ F9 j# l! y4.等待idle,如延时函数,按照睡眠前代码位置继续执行sleep函数中的HAL_PWR_EnterSTOPMode()后续代码,恢复时钟,补偿systick,开启全局中断
    * u. T6 O" n: H+ }; |( J9 Q# b
    8 ?/ ]7 N3 @, ]% i1 a: y# J: E这就导致唤醒后时钟不对,且第一个延时函数会因为tick补偿直接超时,不会产生延时效果(1s、2s、3s、5s都测过不生效),我尝试加两次延时解决了。

    该用户从未签到

    5#
    发表于 2022-9-7 14:59 | 只看该作者
    楼上说的很不错
    ; o" D; W" z% c
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-7-29 22:26 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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