[En-Nut-Discussion] Patch hanging: Set Idle Heartbeat
Uwe Bonnes
bon at elektron.ikp.physik.tu-darmstadt.de
Thu May 27 00:49:48 CEST 2010
>>>>> "Harald" == Harald Kipp <harald.kipp at egnite.de> writes:
...
Harald> Btw. sbi/cbi works fine with memory mapped ports. The compiler
Harald> will take care to use the optimal assembly instructions.
Sorry if I sent the old patch again.
Looking at the patch some definition like
#define IDLE_HEARTBEAT_AVRPORT 0xabcf
#define IDLE_HEARTBEAT_PIN 1
should also allow to toggle some memory mapped device instead of the
GPIO. sbi/cbi will only work on GPIO.
Harald> P.S.: For those, who are wondering what's the background of the
Harald> heartbeat implementation: My company manufactures an Ethernut 2
Harald> based custom board, which contains an external hardware
Harald> watchdog. If a specific GPIO port is not toggled within a
Harald> certain time, this hardware will pull the reset line. While this
Harald> gives extra safety for the final application, it is almost
Harald> impossible to run "normal" Nut/OS applications. A quick solution
Harald> was to add GPIO toggling to the idle thread.
Another use is to look at the CPU load by looking at the pin with a scope or
toggling a LED.
--
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
Index: nut/arch/avr/os/nutinit.c
===================================================================
--- nut/arch/avr/os/nutinit.c (Revision 3006)
+++ nut/arch/avr/os/nutinit.c (Arbeitskopie)
@@ -312,9 +312,33 @@
#if defined(__GNUC__) && defined(__AVR_ENHANCED__)
uint8_t sleep_mode;
#endif
-#ifdef IDLE_HEARTBEAT_BIT
- uint8_t beat = 0;
+#if defined (IDLE_HEARTBEAT_PIN) && defined (IDLE_HEARTBEAT_AVRPORT)
+#if (IDLE_HEARTBEAT_AVRPORT == AVRPORTA)
+#define IDLE_HEARTBEAT_DDR DDRA
+#define IDLE_HEARTBEAT_PORT PORTA
+#elif (IDLE_HEARTBEAT_AVRPORT == AVRPORTB)
+#define IDLE_HEARTBEAT_DDR DDRB
+#define IDLE_HEARTBEAT_PORT PORTB
+#elif (IDLE_HEARTBEAT_AVRPORT == AVRPORTC)
+#define IDLE_HEARTBEAT_DDR DDRC
+#define IDLE_HEARTBEAT_PORT PORTC
+#elif (IDLE_HEARTBEAT_AVRPORT == AVRPORTD)
+#define IDLE_HEARTBEAT_DDR DDRD
+#define IDLE_HEARTBEAT_PORT PORTD
+#elif (IDLE_HEARTBEAT_AVRPORT == AVRPORTE)
+#define IDLE_HEARTBEAT_DDR DDRE
+#define IDLE_HEARTBEAT_PORT PORTE
+#elif (IDLE_HEARTBEAT_AVRPORT == AVRPORTF)
+#define IDLE_HEARTBEAT_DDR DDRF
+#define IDLE_HEARTBEAT_PORT PORTF
+#elif (IDLE_HEARTBEAT_AVRPORT == AVRPORTG)
+#define IDLE_HEARTBEAT_DDR DDRG
+#define IDLE_HEARTBEAT_PORT PORTG
#endif
+#endif
+#ifdef IDLE_HEARTBEAT_DDR
+ IDLE_HEARTBEAT_DDR |= _BV(IDLE_HEARTBEAT_PIN);
+#endif
#ifdef NUT_INIT_IDLE
NutIdleInit();
@@ -341,16 +365,6 @@
NutThreadYield();
NutThreadDestroy();
-#ifdef IDLE_HEARTBEAT_BIT
- if ((beat = !beat) == 0) {
- //UDR = '*';
- cbi(IDLE_HEARTBEAT_PORT, IDLE_HEARTBEAT_BIT);
- }
- else {
- sbi(IDLE_HEARTBEAT_PORT, IDLE_HEARTBEAT_BIT);
- }
- sbi(IDLE_HEARTBEAT_DDR, IDLE_HEARTBEAT_BIT);
-#endif
#if defined(__GNUC__) && defined(__AVR_ENHANCED__)
if (idle_sleep_mode != SLEEP_MODE_NONE) {
@@ -364,11 +378,17 @@
uint8_t bitkeeper = bit_is_set(XMCRB, XMBK);
cbi(XMCRB, XMBK); // disable buskeeper
#endif
+#ifdef IDLE_HEARTBEAT_PORT
+ IDLE_HEARTBEAT_PORT &= ~ _BV(IDLE_HEARTBEAT_PIN);
+#endif
/* Note: avr-libc has a sleep_mode() function, but it's broken for
AT90CAN128 with avr-libc version earlier than 1.2 */
AVR_SLEEP_CTRL_REG |= _BV(SE);
__asm__ __volatile__ ("sleep" "\n\t" :: );
AVR_SLEEP_CTRL_REG &= ~_BV(SE);
+#ifdef IDLE_HEARTBEAT_PORT
+ IDLE_HEARTBEAT_PORT |= _BV(IDLE_HEARTBEAT_PIN);
+#endif
#ifdef IDLE_THREAD_ADC_OFF
if (bitkeeper) {
sbi(XMCRB, XMBK); // re-enable buskeeper
More information about the En-Nut-Discussion
mailing list