1

我在我的 tcl 代码中使用了一个主脚本,我在其中打开了一个 udp 端口​​来读取它上面的数据。我已经使用 fileevent 进行了此操作,我正在使用“vwait”命令进入事件循环。但我不希望主脚本因此而被阻止。简而言之,我希望主脚本继续流动,等待 udp 数据事件应该在后台。如何实现这一点。请帮我。我为此浪费了很多时间,但一切都顺理成章。任何帮助都会非常显着。

这是我的主要脚本:

#!/usr/bin/env tclsh8.5

proc create_udp_payload { command data } {
    set payload     ""
    append payload $command
    append payload  [ format %08x [ expr $data ] ]
    return $payload
}

proc send_udp_packet { payload } {
    puts -nonewline $soc::s [binary format H* $payload]
    puts "\nTransmitting the UDP payload $payload"
    return 0
}

set DEST_IP_ADDR        10.10.20.241
set DEST_UDP_PORT       5558
set soc::s              [udp_open]
puts "Listening on udp port : [fconfigure $soc::s -myport]"
udp_conf $soc::s $DEST_IP_ADDR $DEST_UDP_PORT
fconfigure $soc::s -buffering none -translation binary
fileevent $soc::s readable [list ::udp_listen]

for { set j 0 } { $j < 10 } { incr j} {
    puts "Sending read request to read register $j"
    set command "00"
    append command  [format %02x $j]
    send_udp_packet [create_udp_payload $command  0x0000]
    after 1000
    flush $soc::s
}

wait forever #to enter into the event loop

for { set j 2 } { $j < 12 } { incr j} {
    puts "Sending  write request to write register $j"
    set command "80"
    append command [format %02x $j]
    send_udp_packet [create_udp_payload $command [expr {0x0000 | $j }] ]
    after 2000
    flush $soc::s
}

实际上,我想从硬件中一个一个地读取 10 个寄存器,为此我使用了一个 for 循环,但我不知道如何为此进入事件循环。因为它阻塞了主脚本。同样在那之后我想一个一个地写相同硬件的10个寄存器。任何人都可以修改此代码以相应地工作。在此先感谢您........

4

1 回答 1

0

after idle我认为使用“技巧”可以轻松解决您的问题。这个想法是设置你的“通道可读”事件处理程序,然后为“事件循环空闲”条件安排数据发送代码的执行,然后进入事件循环:

像这样:

# 1. Create and configure the UDP endpoint:
set udp [udp_open ...]
...
# 2. Install "chan readable" callback handlers for that endpoint:
fileevent $udp readable ...
...
# 3. Schedule the one-off callback to send your data:
after idle [list post_data $udp]
# 4. Enter the event loop:
vwait ::done

一旦vwait被调用,事件循环机制就会查看是否有任何未决事件(应该没有),一旦未决事件队列耗尽或为空,所有使用安装的处理程序都会after idle被调用,并且您的数据会被发送出去.

请注意,此方法也适用于其他类似情况,例如,没有什么可以阻止您从after idle事件循环调用的其他处理程序安装此类处理程序。这使您永远不会离开事件循环(就像 GUI 程序和网络服务器通常那样)。

于 2013-01-28T16:48:19.553 回答