|
View:
New views
5 Messages
—
Rating Filter:
Alert me
|
|
|
wdt_enable may fail to enable the watchdog on ATmega1281Hi,
It seems the wdt_enable macro from "avr/wdt.h" may fail to enable the watchdog at least on ATmega1281 devices and possibly on all devices that keep the WDTCSR register in the extended I/O space. The macro looks like this in my version: #define wdt_enable(value) \ __asm__ __volatile__ ( \ "in __tmp_reg__,__SREG__" "\n\t" \ "cli" "\n\t" \ "wdr" "\n\t" \ "sts %0,%1" "\n\t" \ "out __SREG__,__tmp_reg__" "\n\t" \ "sts %0,%2" \ : /* no outputs */ \ : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \ "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \ "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \ _BV(WDE) | (value & 0x07)) ) \ : "r0" \ ) This macro seems to depend on the fact that at least one more instruction will be executed after global interrupts are enabled before an actual interrupt can happen. But this fact seems only to be true for instructions using only one instruction word (16 bits). Instructions such as sts that use two words (32 bits) are not guaranteed to be executed before an interrupt may fire. I have learned this the hard way after trying to optimize interrupt latency in my application for ATmega1281. It does not seem to be documented by Atmel. Could possibly other macros/functions in avr-libc be affected by this? Best regards, Danjel McGougan _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@... http://lists.nongnu.org/mailman/listinfo/avr-libc-dev |
|
|
RE: wdt_enable may fail to enable the watchdog onATmega1281> -----Original Message----- > From: > avr-libc-dev-bounces+eric.weddington=atmel.com@... > [mailto:avr-libc-dev-bounces+eric.weddington=atmel.com@nongnu. > org] On Behalf Of Danjel McGougan > Sent: Friday, August 28, 2009 3:03 AM > To: avr-libc-dev@... > Subject: [avr-libc-dev] wdt_enable may fail to enable the > watchdog onATmega1281 > > This macro seems to depend on the fact that at least one more > instruction will be executed after global interrupts are enabled > before an actual interrupt can happen. But this fact seems only to be > true for instructions using only one instruction word (16 bits). > Instructions such as sts that use two words (32 bits) are not > guaranteed to be executed before an interrupt may fire. I have learned > this the hard way after trying to optimize interrupt latency in my > application for ATmega1281. It does not seem to be documented by > Atmel. Have you tested this on the ATmega1281? Have you tested this on any other ATmega device? _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@... http://lists.nongnu.org/mailman/listinfo/avr-libc-dev |
|
|
Re: wdt_enable may fail to enable the watchdog onATmega1281As Weddington, Eric wrote:
> > Instructions such as sts that use two words (32 bits) are not > > guaranteed to be executed before an interrupt may fire. > Have you tested this on the ATmega1281? This behaviour would surprise me a bit, given that the datasheet chapter about interrupt latency explicitly mentions the increased latency when the interrupt arrives while a multiword instruction is currently being executed. I'd be interested in setting up a test setup that experimentally verifies this behaviour, as the assumption the next instruction will still be executed without being interrupted is quite crucial to the toolchain. -- cheers, J"org .-.-. --... ...-- -.. . DL8DTL http://www.sax.de/~joerg/ NIC: JW11-RIPE Never trust an operating system you don't have sources for. ;-) _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@... http://lists.nongnu.org/mailman/listinfo/avr-libc-dev |
|
|
RE: wdt_enable may fail to enable the watchdogonATmega1281> -----Original Message----- > From: > avr-libc-dev-bounces+eric.weddington=atmel.com@... > [mailto:avr-libc-dev-bounces+eric.weddington=atmel.com@nongnu. > org] On Behalf Of Joerg Wunsch > Sent: Monday, August 31, 2009 12:13 PM > To: avr-libc-dev@... > Subject: Re: [avr-libc-dev] wdt_enable may fail to enable the > watchdogonATmega1281 > > As Weddington, Eric wrote: > > > > Instructions such as sts that use two words (32 bits) are not > > > guaranteed to be executed before an interrupt may fire. > > > Have you tested this on the ATmega1281? > > This behaviour would surprise me a bit, given that the datasheet > chapter about interrupt latency explicitly mentions the increased > latency when the interrupt arrives while a multiword instruction is > currently being executed. > > I'd be interested in setting up a test setup that experimentally > verifies this behaviour, as the assumption the next instruction will > still be executed without being interrupted is quite crucial to the > toolchain. Exactly. I'm interested to hear what the OP has to say about this. _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@... http://lists.nongnu.org/mailman/listinfo/avr-libc-dev |
|
|
Re: wdt_enable may fail to enable the watchdog onATmega1281Weddington, Eric wrote:
>> This macro seems to depend on the fact that at least one more >> instruction will be executed after global interrupts are enabled >> before an actual interrupt can happen. But this fact seems only to be >> true for instructions using only one instruction word (16 bits). >> Instructions such as sts that use two words (32 bits) are not >> guaranteed to be executed before an interrupt may fire. I have learned >> this the hard way after trying to optimize interrupt latency in my >> application for ATmega1281. It does not seem to be documented by >> Atmel. > > Have you tested this on the ATmega1281? Have you tested this on any other ATmega device? Hi, I tried to reproduce this using simpler code since posting and I can not trigger it again. It seems the construct that confused me was this little piece in my application: This is the start of the USART0_RX_vect interrupt routine: push r29 ; save r29 in r29, _SFR_IO_ADDR(SREG) push r29 ; save SREG lds r29, _SFR_MEM_ADDR(UCSR0B) andi r29, ~_BV(RXCIE0) sts _SFR_MEM_ADDR(UCSR0B), r29 ; clear RXCIE0 in UCSR0B sei Here I disable the RXC-interrupt and then enable global interrupts to allow nested interrupts in my application. If I move sei one instruction up (to reduce interrupt latency) the code does not work anymore: push r29 ; save r29 in r29, _SFR_IO_ADDR(SREG) push r29 ; save SREG lds r29, _SFR_MEM_ADDR(UCSR0B) andi r29, ~_BV(RXCIE0) sei sts _SFR_MEM_ADDR(UCSR0B), r29 ; clear RXCIE0 in UCSR0B ---> RXC interrupt fires here It seems the CPU schedules an RXC interrupt when sei is executed and it doesn't matter that we then clear the RXCIE0 bit in the next instruction (which should always be executed). The RXC interrupt fires before the next instruction anyway. So to conclude I don't think there is a problem in avr-libc. I was too quick to post. BR, Danjel McGougan _______________________________________________ AVR-libc-dev mailing list AVR-libc-dev@... http://lists.nongnu.org/mailman/listinfo/avr-libc-dev |
| Free embeddable forum powered by Nabble | Forum Help |