- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个非常简单的程序让我很头疼。
一些背景:我正在 atmelstudio 6 中对 arduino Uno“Atmega328P”进行编程。我在 debugwire 模式下使用 JTAGICE mkII 进行编程和调试。我也用过this method使用 arduino 库使事情变得更容易。
我写了一个简单的程序来计算一个外部中断引脚上的转换。在我的例子中,我使用的是 INT0_vect。我指向的值,每次转换都会递增。
问题是在 ISR 中使用全局指针。您可能认为我忘记添加 volatile 关键字,但您错了。
ISR 为每次转换提供服务,但不会更改值。我不明白为什么,所以我单步执行程序,发现我的指针指向工作寄存器之一 R00。这应该没问题,但在服务 ISR 之前,R00 被插入堆栈 R00 递增并恢复先前的值。
我不知道为什么会这样。正如我所说,我正在使用“volatile uint8_t*
”,它应该是一个指向 volatile uint8_t 的指针。
代码如下:
#include "Arduino.h"
void setup();
void loop();
void update();
volatile uint8_t* Count;
void setup()
{
*Count = 0;
attachInterrupt(0,update, CHANGE); // makes ISR call update
}
void loop()
{
// delay(1000);
}
void update()
{
(*Count)++;
}
主循环调用一次设置然后重复循环。
attach interrupt 是一个宏,它设置中断然后有效地创建这个:
`ISR(INT0_vect){update();}`
一些附加信息:
最佳答案
由于 Count
指针是一个未显式初始化的全局变量,它被设置为 0x0
,这恰好是 Atmega328P 映射寄存器的地址 R00
到。
用 ISR()
宏标记的函数向编译器表明它是 C ISR 处理程序。为了让编译器安排 C 代码执行 ISR 而不会破坏 ISR 触发时可能正在运行的任何状态,它必须添加一些序言代码来保存一些 CPU 的寄存器状态(以及相应的尾声以恢复ISR 函数返回时的状态),这样被中断的执行路径就不会被破坏。因此,ISR()
指定导致编译器在堆栈上保存和恢复寄存器 R00
(和其他寄存器)。
这两种情况的结合就是为什么 R00
被保存在堆栈中,然后您的 ISR 递增它,然后 R00
从堆栈中恢复。
如果您不希望这种情况发生,您可以使用 ISR_NAKED
属性告诉编译器不要生成序言或结尾代码。但是,如果您的 ISR 句柄没有正确保存和恢复寄存器状态,那么在前台运行的任何东西都可能表现不佳。
因此,将 Count
设置为指向您为计数器分配的某个位置。或者,使 Count
成为一个简单的变量而不是指针,并直接在 ISR 中处理它。
可以在这里找到对 avr-gcc 的中断处理支持的一个很好的概述:http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
关于c++ - ISR 中使用的指针指向寄存器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21031428/
我有一段用于 PIC 设备的 C 代码,它按照预定义的模式驱动 4 个独立的继电器,每个继电器通过计数次数和发生频率来单独设置。这种模式会无限延续,但发现标准delay_ms 上的计时不够准确。我希望
我对这种宏尝试有疑问: #define ISR(x) #pragma isr=x 无法编译,因为它试图用不存在的参数替换 #pragma。有什么办法可以实现我想要做的事情吗?我想将 ISR(VEC1)
我现在使用的是嵌入式产品,即 PIC32 Microchip CPU。 我熟悉几个实时内核:AVIX , FreeRTOS , TNKernel ,并且在所有这些函数中,几乎所有函数都有 2 个版本:
我正在调试 arm-family cpu (Cortex M3) 上的固件。 调试器显示 CPU 寄存器,包括一个称为“xPSR”的寄存器,其中包含一个称为“ISR”的子字段。 CPU寄存器中的模式是
我有以下设置经纪人:3 - 全部启动并运行 min.insync.replicas=3。 我创建了一个topic,配置如下 bin\windows\kafka-topics --zookeeper 1
我有以下设置经纪人:3 - 全部启动并运行 min.insync.replicas=3。 我创建了一个topic,配置如下 bin\windows\kafka-topics --zookeeper 1
我有一个带有3个kafka节点和3个zk节点的kakfa集群。 生产者在AWS机器上尝试将数据推送到我的Intranet服务器上运行的kafka集群上。 使用以下命令从控制台创建主题(JOB_AWS_
在mspgcc中声明中断处理程序的首选方法是什么? 最佳答案 请澄清一下,因为这是Google的早期结果。 __attribute__((__interrupt__(TIMER0_A0_VECTOR)
在 ISR 内设置断点是否合法/可能?或者这是特定于硬件的? 最佳答案 是的,这是完全合法的,但是由于其他 ISR 没有及时触发,例如 USB,可能会出现一些小问题。 关于embedded - ISR
我正在使用 Hi-Tech-PICC v9.65PL1 进行 C 语言编程,对 PIC16F876 进行编程。 对于中断,我使用以下结构: void interrupt isr() { if
被零除错误未调用 ISR0。 我的内核主要从 boot.s 调用 void kernel_main() { gdt_install(); idt_install(); isrs_
我用8051的硬件中断0编写了一个简单的led闪烁代码。当按钮被按下时,它进入中断服务程序(ISR)。执行后它应该返回到主函数中,但它没有出现。这是我的c代码。任何积极的答复将不胜感激。 sbit L
在特定的 ISR 之后是否有任何(脏)方法来触发上下文切换到特定的进程? 在正常情况下,在 ISR 之后,被中断的进程会继续运行,我必须等待调度程序选择那个特定的进程。我想在 ISR 之后立即切换到具
我有一个非常简单的程序让我很头疼。 一些背景:我正在 atmelstudio 6 中对 arduino Uno“Atmega328P”进行编程。我在 debugwire 模式下使用 JTAGICE m
有没有一种方法可以从定时器 ISR 中操纵堆栈?所以我可以通过强制退出长时间运行的函数来丢弃堆栈的最高帧吗? (我知道在这种情况下会丢失堆分配的内存) 目标可能是 ARM CPU。 最好的问候 最佳答
我正在研究操作系统,我遇到了 ISR 和中断处理程序这两个术语。他们是同一个机制的两个词吗?如果不是,有什么区别? 最佳答案 中断处理程序和 ISR 没有区别。 Wiki说: In computer
是否可以使用类方法作为中断服务程序? 我有一个 ISR 编写并使用一个函数在 C 中工作: static void interrupt far ISR(...) {} 我尝试在 C++ 中创建
我正在尝试实现该功能 unsigned int (*poll) (struct file *filp, poll_table *wait); 在我的驱动程序中。我已经使用 将设备的文件描述符添加到等待
使用 RTOS(前 FreeRTOS)时,我们为每个线程提供单独的堆栈空间。那么ISR(中断服务程序)呢,它们在内存中是否有单独的堆栈?或者这是可配置的? 如果他们没有一个堆栈来存储 ISR 中声明的
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 6 年前。 Improve
我是一名优秀的程序员,十分优秀!