⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 watchdog.tcl

📁 eCos操作系统源码
💻 TCL
📖 第 1 页 / 共 2 页
字号:
                    .watchdog raise $watchdog::right_pupil $watchdog::right_eye                } else {                    set watchdog::eyes "both"                    .watchdog raise $watchdog::left_eye    $watchdog::background                    .watchdog raise $watchdog::left_pupil  $watchdog::left_eye                    .watchdog raise $watchdog::right_eye   $watchdog::background                    .watchdog raise $watchdog::right_pupil $watchdog::right_eye                }            } else {                if { 0 == [expr int(8 * rand())] } {                    set watchdog::eyes "none"                    .watchdog lower $watchdog::left_eye    $watchdog::background                    .watchdog lower $watchdog::right_eye   $watchdog::background                    .watchdog lower $watchdog::left_pupil  $watchdog::background                    .watchdog lower $watchdog::right_pupil $watchdog::background                    # There is no point in moving the pupils if both eyes are shut                    return                }            }            set watchdog::pupils [expr int(9 * rand())]            set new_pupil_x [lindex [lindex $watchdog::pupil_positions $watchdog::pupils] 0]            set new_pupil_y [lindex [lindex $watchdog::pupil_positions $watchdog::pupils] 1]            if { ("left" == $watchdog::eyes) || ("both" == $watchdog::eyes) } {                .watchdog coords $watchdog::left_pupil              \                    [expr $watchdog::left_eye_x + $new_pupil_x]     \                    [expr $watchdog::left_eye_y + $new_pupil_y]     \                    [expr $watchdog::left_eye_x + $new_pupil_x + 2] \                    [expr $watchdog::left_eye_y + $new_pupil_y + 2]            }            if { ("right" == $watchdog::eyes) || ("both" == $watchdog::eyes) } {                .watchdog coords $watchdog::right_pupil              \                    [expr $watchdog::right_eye_x + $new_pupil_x]     \                    [expr $watchdog::right_eye_y + $new_pupil_y]     \                    [expr $watchdog::right_eye_x + $new_pupil_x + 2] \                    [expr $watchdog::right_eye_y + $new_pupil_y + 2]            }        }        # Cancel the gui display when the eCos application has exited.        # The watchdog is allowed to go back to sleep. If the application        # exited because of the watchdog then of course the alarm picture        # should remain visible, otherwise it would be just a flash.        proc gui_cancel { } {            .watchdog lower $watchdog::left_eye    $watchdog::background            .watchdog lower $watchdog::right_eye   $watchdog::background            .watchdog lower $watchdog::left_pupil  $watchdog::background            .watchdog lower $watchdog::right_pupil $watchdog::background            if { ! $watchdog::alarm_triggered } {                .watchdog raise $watchdog::asleep      $watchdog::background            }        }                # Raise the alarm. This involves hiding the eyes and raising        # the alarm picture. If sound is enabled, the sound player        # should be invoked        proc gui_alarm { } {            .watchdog lower $watchdog::asleep      $watchdog::background            .watchdog lower $watchdog::left_eye    $watchdog::background            .watchdog lower $watchdog::right_eye   $watchdog::background            .watchdog lower $watchdog::left_pupil  $watchdog::background            .watchdog lower $watchdog::right_pupil $watchdog::background            .watchdog raise $watchdog::alarm       $watchdog::background            if { "" != $watchdog::sound_file } {                # Catch errors on the actual exec, e.g. if the sound player is                # invalid, but play the sound in the background. If there are                # problems actually playing the sound then the user should                # still see a message on stderr. Blocking the entire auxiliary                # for a few seconds is not acceptable.                if { [catch { eval exec -- $watchdog::sound_player $watchdog::sound_file & } message] } {                    synth::report_warning "Watchdog device, failed to play alarm sound file\n    $message\n"                }            }        }	set _watchdog_help [file join $synth::device_src_dir "doc" "devs-watchdog-synth.html"]	if { ![file readable $_watchdog_help] } {	    synth::report_warning "Failed to locate synthetic watchdog documentation $_watchdog_help\n\			          \    Help->Watchdog target menu option disabled.\n"	    set _watchdog_help ""	}	if { "" == $_watchdog_help } {	    .menubar.help add command -label "Watchdog" -state disabled	} else {	    .menubar.help add command -label "Watchdog" -command [list synth::handle_help "file://$_watchdog_help"]	}    }    # Now for the real work. By default the watchdog is asleep. The eCos    # application can activate it with a start message, which results    # in an "after" timer. That runs once a second to check whether or not    # the watchdog should trigger, and also updates the GUI.    #    # The target-side code should perform a watchdog reset at least once    # a second, which involves another message to this script and the    # setting of the reset_received flag.    #    # The update handler gets information about the eCos application using    # /proc/<pid>/stat (see man 5 proc). The "state" field is important:    # a state of T indicates that the application is stopped, probably    # inside gdb, so cannot reset the watchdog. The other important field    # is utime, the total number of jiffies (0.01 seconds) executed in    # user space. The code maintains an open file handle to the /proc file.    variable reset_received     0    variable after_id           ""    variable proc_stat          ""    variable last_jiffies       0        set _filename "/proc/[set watchdog::ecos_pid]/stat"    if { [catch { open $_filename "r" } proc_stat ] } {        synth::report_error "Watchdog device, failed to open $_filename\n    $proc_stat\n"        set watchdog::init_ok 0    }    unset _filename    proc update { } {        set watchdog::after_id [after $watchdog::resolution watchdog::update]        if { $synth::flag_gui } {            watchdog::gui_update        }        seek $watchdog::proc_stat 0 "start"        set line [gets $watchdog::proc_stat]        scan $line "%*d %*s %s %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu %lu" state jiffies	# In theory it is possible to examine the state field (the third argument).	# If set to T then that indicates the eCos application is traced or	# stopped, probably inside gdb, and it would make sense to act as if	# the application had sent a reset. Unfortunately the state also appears	# to be set to T if the application is blocked in a system call while	# being debugged - including the idle select(), making the test useless.	# FIXME: figure out how to distinguish between being blocked inside gdb	# and being in a system call.	#if { "T" == $state } {	#    set watchdog::reset_received 1	#    return	#}	        # If there has been a recent reset the eCos application can continue to run for a bit longer.        if { $watchdog::reset_received } {            set watchdog::last_jiffies $jiffies            set watchdog::reset_received 0            return        }        # We have not received a reset. If the watchdog is using wallclock time then        # that is serious. If the watchdog is using elapsed cpu time then the eCos        # application may not actually have consumed a whole second of cpu time yet.        if { $watchdog::use_wallclock || (($jiffies - $watchdog::last_jiffies) > ($watchdog::resolution / 10)) } {            set watchdog::alarm_triggered 1            # Report the situation via the main text window            synth::report "Watchdog device: the eCos application has not sent a recent reset\n    Raising SIGPWR signal.\n"            # Then kill off the eCos application            exec kill -PWR $watchdog::ecos_pid            # There is no point in another run of the timer            after cancel $watchdog::after_id            # And if the GUI is running, raise the alarm visually            if { $synth::flag_gui } {                watchdog::gui_alarm            }        }    }    # When the eCos application has exited, cancel the timer and    # clean-up the GUI. Also get rid of the open file since the    # /proc/<pid>/stat file is no longer meaningful    proc exit_hook { arg_list } {        if { "" != $watchdog::after_id } {            after cancel $watchdog::after_id        }        if { $synth::flag_gui } {            watchdog::gui_cancel        }        close $watchdog::proc_stat    }    synth::hook_add "ecos_exit" watchdog::exit_hook        proc handle_request { id reqcode arg1 arg2 reqdata reqlen reply_len } {        if { 0x01 == $reqcode } {            # A "start" request. If the watchdog has already started,            # this request is a no-op. Otherwise a timer is enabled.            # This is made to run almost immediately, so that the            # GUI gets a quick update. Setting the reset_received flag            # ensures that the watchdog will not trigger immediately            set watchdog::reset_received 1            if { "" == $watchdog::after_id } {                set watchdog::after_id [after 1 watchdog::update]            }            if { $synth::flag_gui } {                .watchdog lower $watchdog::asleep $watchdog::background            }        } elseif { 0x02 == $reqcode } {            # A "reset" request. Just set a flag, the update handler            # will detect this next time it runs.            set watchdog::reset_received 1        }    }        proc instantiate { id name data } {        return watchdog::handle_request    }}if { $watchdog::init_ok } {    return watchdog::instantiate} else {    synth::report "Watchdog cannot be instantiated, initialization failed.\n"    return ""}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -