[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