- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
您好,我想知道让 ARM Cortex M0+ 进入深度 sleep 的正确方法是什么。特别是我正在使用 CMSIS-RTOS RTX。
我的 IRQ 处理方式是 ISR 只是设置 OS Signal 并清除 IRQ。例如。:
void ISR_A(){
osSignalSet(ID_Task_Handling_IRQ_A, IRQ_A_SIGNAL_CODE);
DisableIRQ_A();
}
void os_idle_demon(void) {
...
timeToSleep = os_suspend(); // get from OS how long I can sleep and also stop OS scheduling
LPTMR_Init(timeToSleep,...) // set wakeup timer
POWER_EnterLLS(void) // enter deep sleep. Set registers and calls WFI instruction
// after wakup compute actual slpetTime
os_resume(sleptTime); // enable OS scheduling
}
os_suspend()
之间时和
__wfi()
指令然后 IRQ 被清除但任务不能被调度(因为
os_suspend()
)。当 CPU 进入 WFI 时,它会进入休眠状态,因此应处理来自 ISR 的信号的 OS 线程永远不会执行。但是 CPU 也不会被(pad)IRQ 唤醒,因为它已经被处理了。
if( ! OS_Signal_Is_rised) {
// only do it atomically because what if IRQ would come here?
wfi;
}
最佳答案
所以我有时间对芯片 MKL17Z256VFT4 中的 ARM M0+ 做一些测试。使用 CMSIS-RTOS RTX (v 4.75)。
它是这样工作的:
void os_idle_demon(void) { // task with lowest priority - scheduled by
//system when there is no action to do
for (;;) {
timeToSleep = os_suspend(); // stop OS from switching tasks and get maximum allowed sleep time
__disable_irq();
LPTMR_Init(timeToSleep...); // set Low Power sleep timer
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;//set DeepSleep
GPIO(pin=0,val=1); // signalize on GPIO pad that CPU is (almost) in sleep
__enable_irq();
__wfi(); // go to DeepSleep
GPIO(pin=0,val=0); // signalize on GPIO pad that CPU just wakeup
sleptTime = LPTMR_GetCounterValue(); // get sleepTime after wakeup
os_resume(sleptTime); // set system to schedule tasks and give os info about sleep time
}
NVIC_SetPendingIRQ(PORTCD_IRQn);
用于执行 IRQ。我观察到逻辑分析仪正在运行哪个任务,观察 GPIO 引脚。
os_suspend()
之前触发ISR 被调用,我在 ISR 系统信令中使用
osSignalSet(ID_Thread1, SIGNAL_X)
.由于每个线程的优先级都高于
os_idle_demon
线程
ID_Thread1
正在等待
event = osSignalWait(ANY_SIGNAL, osWaitForever);
切换到(通过 RTOS)并处理信号。在该线程再次开始等待任何信号和
os_idle_demon
之后任务已安排,ARM 进入休眠状态。
os_suspend()
之间和
__disable_irq()
.我发现在
__disable_irq()
之前调用 IRQ 时ARM 处理 IRQ 的速度不够快,实际上
__disable_irq()
首先执行。所以 IRQ 等到
__enable_irq()
叫做。所以一切都进入另一个案例。
__enable_irq()
之前.在启用 IRQ 之后和 CPU 执行 DeepsSleep (
__wfi();
) 之前,将执行 ISR。信号已设置。但是系统不能切换线程(我们称之为
os_suspend()
)。但显然 WFI 以某种方式神奇地(我仍在研究规范为什么)没有执行。没有进入深度 sleep ,代码继续
os_resume()
.然后操作系统切换任务和信号被正确处理。
__enable_irq();
// do not put anything here
__wfi();
__enable_irq()
之后立即执行。 . ISR 设置 OS 信号,但信号任务未安排(因为我们之前调用了
os_suspend()
)。然后
__wfi()
进入深度 sleep .然后系统永远休眠或直到 LPTMR。但这是错误的,因为有信号应该尽快处理,但没有!
__enable_irq();
之间添加任何指令和
__wfi();
.此外,您不得在其间添加任何指令:
os_suspend();
和
__disable_irq();
.这至少对 MKL17Z256VFT4 有效。不知道其他芯片。但是您可以通过使用函数
NVIC_SetPendingIRQ()
强制执行 IRQ 标志来测试自己。
CPSID
ARM 从 WFI 中唤醒。所以也许更安全的顺序是
__wfi(); // go to DeepSleep
// optionally enable peripherals that might been disabled
__enable_irq();
__enable_irq();
最迟在您调用
os_resume(sleptTime);
之前否则在我的芯片上我会得到 HardFault。
__WFE();
指示以确保没有比赛条件。 WFE 是等待事件。它将 CPU 置于与 WFI 相同的 sleep 模式。但它也会检查“事件寄存器”。该寄存器在每个 ISR(最后)上设置。如果在 WFE 之前有 IRQ,那么 WFE 将不会进入休眠状态。您可以通过调用指令
__SEV();
来选择设置“事件寄存器”。 .无法从 SW 访问“事件寄存器”。如果你想确保清除它,你可以打电话
__SEV(); // set event register if it was not set
__WFE(); // clear event register and don't goto sleep because we set event register just before
关于arm - CMSIS-RTOS Keil RTX - 进入 ARM 深度 sleep 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35875753/
CMSIS文件和外设驱动文件中写的是什么类型的代码。我怎样才能区分它们?任何例子都会更有帮助。谢谢你。 最佳答案 “CMSIS”是 Cortex Microcontroller Software In
这个问题已经有答案了: Storing third-party libraries in source control (17 个回答) Arguments for and against inclu
我正在尝试在 STM32F407 微 Controller 上实现 60kHz 带通滤波器,但遇到了一些问题。我在 MATLABs fdatool 的帮助下生成了过滤器,然后也在 MATLAB 中对其
最近我一直在检查 CMSIS DSP 复杂数学函数库,我看到了一些我无法完全理解的东西,因此我是关于 SO 的第一篇文章。 我无法理解的是 he11 复杂的点积函数如何产生正确的结果?该功能可在此处找
我下载了 CMSIS 版本 3,但在使用时遇到了一些问题。主要问题在startup_device.s。我不知道如何正确完成该文件,也找不到任何好的文档。有人尝试过使用这个cmsis版本吗?如何进行?正
我正在将产品移植到基于 CMSIS 的 RTOS,该产品需要获取 32 位整数形式的线程 ID。然而,CMSIS 线程 id 类型 (osThreadId) 是完全不透明的,类型定义为 struct
我想使用 CMSIS 中的 DSP 功能。我正在使用 STM32CubeIDE,我的目标板是 ST32F411RE Discovery。将 CMSIS DSP 与 Keil uVision 一起使用非
我正在使用 CMSIS API在我的 ARM Cortex-M CPU 的 C 程序中。 CMSIS 将 NVIC_DisableIRQ 函数定义为 __STATIC_INLINE void __NV
我正在使用 STM32F103C8T6 并希望使用 CMSIS,which is essentially just register definitions and no code ,让我的生活更轻松
我正在尝试制作一个使用各种功能的 C 程序,然后通过连接到 LPCXpresso 1769 的 DIP 开关,它必须选择要执行的功能(例如 00 二进制计数器 01 旋转 LED 等)。现在,我已经做
我已经从 8 位裸机寄存器转向,并且必须学习一些新的 C Kungfu 才能理解 CMSIS 核心方法。 我这里有一段来自 ARM Cortex M 供应商的外设访问层的代码片段。他们创建了这个 SN
FreeRTOS 和 CMSIS-RTOS 有什么区别?谁能解释这两个 RTOS 的相似之处或不同之处? 最佳答案 我认为这里的混淆来源是存在 CMSIS-RTOS API( v1 和 v2 ),并且
在 gcc 的 CMSIS 定义中,您可以找到如下内容: static __INLINE void __DMB(void) { __ASM volatile ("dmb"); } 我的问题是:如果内存
我在 stm32f103rc 中尝试 DMA。我按照这个教程https://letanphuc.net/2014/06/how-to-use-stm32-dma/并使用 CMSIS CORE 编写了我
我编写了一个使用 CMSIS DSP 库中的 arm_cfft_f32 函数的代码。如何将 CMSIS DSP 库添加到我的项目的 Makefile 中? STM32CubeMX为STM32F407芯
我们在 STM32F407 板上的 CMSIS 和 FreeRTOS 中遇到互斥锁问题。 有两个线程可以通过 UART 访问硬件 radio 。我们正在使用互斥体来确保一次只有一个线程可以与 radi
我使用 MCB1700 评估板。Keil为开发者提供了RL-ARM库。但几个小时前我创建了 CMSIS Librariy。它还具有用于 USB、以太网等的 header 和 c 文件(带有示例)。“R
所以我在 STM32F427 微 Controller 上使用 CMSIS-RTOS 邮件队列机制和 Keil uVision 5.0.5 运行在 180MHz。并且不时地使用 osMailFree(
我正在尝试为我的 Cortex-M0 嵌入式处理器设置 CLion C 工作环境。我是 CLion 和 cmake 的新手,我已经为这个问题苦苦挣扎了好几天: 问题出现在 CMSIS 中包含的 cor
您好,我想知道让 ARM Cortex M0+ 进入深度 sleep 的正确方法是什么。特别是我正在使用 CMSIS-RTOS RTX。 我的 IRQ 处理方式是 ISR 只是设置 OS Signal
我是一名优秀的程序员,十分优秀!