`

『TinyOS』学习笔记 #11?

阅读更多

Lesson 11  TOSSIM 

Compiling TOSSIM

 

 make micaz sim

 

 

Running TOSSIM with Python

 

tos的模拟器是在python中运行

 

运行TOSSIM simulation 用到 runNextEvent function。it returns 0. This means that there was no next event to run. returns 1, there was an event to run.

 

 

Debugging Statements 

 

  • dbg: print a debugging statement preceded by the node ID.
  • dbg_clear: print a debugging statement which is not preceded by the node ID. This allows you to easily print out complex data types, such as packets, without interspersing node IDs through the output.
  • dbgerror: print an error statement preceded by the node ID
  • dbgerror_clear: print an error statement which is not preceded by the node ID  

 

TOSSIM's debugging output can be configured on a per-channel basis. So, for example, you can tell TOSSIM to send the "Boot" channel to standard output, but another channel, "RadioCountToLedsC", to a file. 这个channel名可以自己定义, dbg可以通过名字选择性的输出想要的信息。 比如t.addChannel("Boot", sys.stdout) 输出channel名为Boot的debug信息, 也就是执行到dbg("Boot", "Application booted.\n")这个就会输出,而dbg("my", "Application booted.\n")不会输出,因为没有加入my这个channel

 

By default, a channel has no destination and messages to it are discarded.

 

 

dbg("Boot", "Application booted.\n"); 

 

 

dbg() takes two or more parameters:

  • The first parameter ("Boot" in the above example) defines the output channel. An output channel is a string.
  • The second and subsequent parameters are the message to output and variable formatting. dbg() is identical to a sprintf statement in C++. 

debug and error functions 的唯一区别是 he string output at the beginning of a message. Debug statements print DEBUG (n), Error statements print ERROR (n).

 

If a statement has multiple channels and those channels share outputs, then TOSSIM only prints the message once. For example:

 

dbg("Boot,RadioCountToLedsC", "Application booted.\n");

 

if both the Boot channel and RadioCountToLedsC channel were connected to standard out, TOSSIM will only print one message. 

 

 

Configuring a Network

 

radio object

 

  • add(src, dest, gain): Add a link from src to dest with gain. When src transmits, dest will receive a packet attenuated by the gain value.
  • connected(src, dest): Return whether there is a link from src to dest.
  • gain(src, dest): Return the gain value of the link from src to dest.
  • threshold(): Return the CCA threshold.
  • setThreshold(val): Set the CCA threshold value in dBm. The default is -72dbM.

 

MAC object 

 

The default MAC object has a large number of functions, for controlling backoff behavior, packet preamble length, radio bandwidth, etc. All time values are specified in terms of radio symbols, and you can configure the number of symbols per second and bits per symbol. By default, the MAC object is configured to act like the standard TinyOS 2.0 CC2420 stack: it has 4 bits per symbol and 64k symbols per second, for 256kbps.

 

 

 

the radio connectivity data can be stored in a flat file, you can easily create topologies in files and then load the file using a Python script and store them into the radio object.

 

Create a file topo.txt that looks like this 

1  2 -54.0
2  1 -55.0
1  3 -60.0
3  1 -60.0
2  3 -64.0
3  2 -64.0

 

this file specifies each link in the graph as a line with three values, the source, the destination, and the gain.

 

This script will read the file and store the data in the radio object:

>>> f = open("topo.txt", "r")
>>> lines = f.readlines()
>>> for line in lines:
...   s = line.split()
...   if (len(s) > 0):
...     print " ", s[0], " ", s[1], " ", s[2];
...     r.add(int(s[0]), int(s[1]), float(s[2]))

 

这一章还介绍了 TOSSIM用于测试的完整的python脚本。

 

#! /usr/bin/python
from TOSSIM import *
import sys

t = Tossim([])
r = t.radio()
f = open("topo.txt", "r")

lines = f.readlines()
for line in lines:
  s = line.split()
  if (len(s) > 0):
    print " ", s[0], " ", s[1], " ", s[2];
    r.add(int(s[0]), int(s[1]), float(s[2]))

t.addChannel("RadioCountToLedsC", sys.stdout)
t.addChannel("Boot", sys.stdout)

noise = open("meyer-heavy.txt", "r")
lines = noise.readlines()
for line in lines:
  str = line.strip()
  if (str != ""):
    val = int(str)
    for i in range(1, 4):
      t.getNode(i).addNoiseTraceReading(val)

for i in range(1, 4):
  print "Creating noise model for ",i;
  t.getNode(i).createNoiseModel()

t.getNode(1).bootAtTime(100001);
t.getNode(2).bootAtTime(800008);
t.getNode(3).bootAtTime(1800009);

for i in range(0, 100):
  t.runNextEvent()
 

还有如何生成 network topology 和相关的信噪比。 详情请见原文

 

 

Variables 

 

TOSSIM allows you to inspect variables in a running TinyOS program. Currently, you can only inspect basic types. For example, you can't look at fields of structs, but you can look at state variables.

 

用来在python中来查阅tinyos程序(nesC程序)中的变量情况, 比如变量的值,类型等。可以利用这个功能来观察程序运行的状态等情况。

 

例子

from sys import *
from random import *
from TOSSIM import *
from tinyos.tossim.TossimApp import *   #引入库

n = NescApp()  #实例化
t = Tossim(n.variables.variables()) #获取变量列表并传入Tossim对象
r = t.radio()

f = open("topo.txt", "r")
lines = f.readlines()
for line in lines:
  s = line.split()
  if (len(s) > 0):
    if (s[0] == "gain"):
      r.add(int(s[1]), int(s[2]), float(s[3]))

noise = open("meyer-heavy.txt", "r")
lines = noise.readlines()
for line in lines:
  str = line.strip()
  if (str != ""):
    val = int(str)
    for i in range(0, 4):
      t.getNode(i).addNoiseTraceReading(val)

for i in range (0, 4):
  t.getNode(i).createNoiseModel()
  t.getNode(i).bootAtTime(i * 2351217 + 23542399)

m = t.getNode(0)
v = m.getVariable("RadioCountToLedsC.counter")  #得到要观察的变量
while (v.getData() < 10):   #getData() 取得观察变量的值
  t.runNextEvent()

print "Counter variable at node 0 reached 10."
 

 

【to be cont... 】

 

 

Injecting Packets

 

TOSSIM allows you to dynamically inject packets into a network. Packets can be scheduled to arrive at any time. If a packet is scheduled to arrive in the past, then it arrives immediately. Injected packets circumvent the radio stack: it is possible for a node to receive an injected packet while it is in the midst of receiving a packet from another node over its radio.

 

可以在Tossim模拟中加入包并发送。

 

 

RadioCountMsg.py defines a packet format, but this packet is contained in the data payload of another format. If a node is sending a RadioCountMsg over AM, then the RadioCountMsg structure is put into the AM payload, and might look something like this:

AM Header RadioCountMsg AM Footer

If it is sending it over a routing protocol. the packet is put in the routing payload, and might look something like this:

AM Header Routing Header RadioCountMsg AM Footer

If you want to send a RadioCountMsg to a node, then you need to decide how to deliver it. In the simple AM case, you place the RadioCountMsg structure in a basic AM packet. In the routing case, you put it in a routing packet, which you then put inside an AM packet. We'll only deal with the simple AM case here.

To get an AM packet which you can inject into TOSSIM, you call the newPacket function on a Tossim object. The returned object has the standard expected AM fields: destination, length, type, and data, as well as strength.

 

 

from RadioCountMsg import *  #include packet format

msg = RadioCountMsg()           #creates a RadioCountMsg
msg.set_counter(7);                #sets its counter to 7
pkt = t.newPacket();                #creates an AM packet
pkt.setData(msg.data)             #stores the RadioCountMsg in the AM packet
pkt.setType(msg.get_amType())     #set AM packet type
pkt.setDestination(0)                      #set AM packet destination

pkt.deliver(0, t.time() + 3)    #delivers pkt to node 0 at the current simulation time plus 3 ticks (e.g., 3ns).
 

 

 

 

 

【to be cont... 】

 

 

 

 

Using gdb

Since Driver is a C++ program, you can use gdb on it to step through your TinyOS code, inspect variables, set breakpoints, and do everything else you can normally do. Unfortunately, as gdb is designed for C and not nesC, the component model of nesC means that a single command can have multiple providers; referring to a specific command requires specifying the component, interface, and command.

 

$ gdb Driver
GNU gdb Red Hat Linux (6.0post-0.20040223.19rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) break *LedsP$Leds$led0Toggle
Breakpoint 1 at 0x804f184: file LedsP.nc, line 73.
 

 

观察程序中的变量

nesC translates component names to C names using $. $ is a legal but almost-never-used character in some versions of C, so nesC prohibits it and uses it internally. The leading * is necessary so dbg can parse the $s. With the above breakpoint set, gdb will break whenever a mote toggles led0.

Variables have similar names. For example, to inspect the packet of RadioCountToLedsC in the RadioCountToLeds application,

 

 (gdb) print RadioCountToLedsC$packet
 $1 = {{header = {{data = ""}, {data = ""}, {data = ""}, {data = ""}, {
         data = ""}}, data = {{data = ""} }, footer = {{
         data = ""}, {data = ""}}, metadata = {{data = ""}, {data = ""}, {
         data = ""}, {data = ""}, {data = ""}}} }
 

 

For those who know gdb very well, you'll recognize this as a print of an array, rather than a single variable: there are more than 1000 instances of the message_t struct. This is because TOSSIM simulates many motes; rather than there being a single RadioCountToLedsC$packet, there is one for every node. To print the packet of a specific node, you have to index into the array. This, for example, will print the variable for node 6:

 (gdb) print RadioCountToLedsC$packet[6]
 $2 = {header = {{data = ""}, {data = ""}, {data = ""}, {data = ""}, {
       data = ""}}, data = {{data = ""} }, footer = {{
       data = ""}, {data = ""}}, metadata = {{data = ""}, {data = ""}, {
       data = ""}, {data = ""}, {data = ""}}}
 

If you want to print out the variable for the node TOSSIM is currently simulating, you can do this:

(gdb) print RadioCountToLedsC$counter[sim_node()]
$4 = 0
 

设置 watchpoint

You can also set watchpoints (although, as to be expected, they are slow:

(gdb) watch CpmModelC$receiving[23]
Hardware watchpoint 2: CpmModelC$receiving[23]
 

This variable happens to be an internal variable in the packet-level network simulation, which keeps track of whether the radio thinks it is receiving a packet. So setting the above watchpoint will cause gdb to break whenever node 23 starts receiving a packet or returns to searching for packet preambles.

 

设置断点break point 

Generic components add another wrinkle. Since they use a code-copying approach, each instance of a generic has its own separate functions and variables (this is mostly due to the fact that you can pass types to them). Take, for example, AMQueueImplP, which is used in both the radio AM stack and the serial AM stack. If you use gdb on an application that uses both serial and radio communication and try to break on its Send.send, you'll see an error:

(gdb) break *AMQueueImplP$Send$send
No symbol "AMQueueImplP$Send$send" in current context.
 

nesC gives each generic a unique number. So if you have an application in which there is a single copy of AMQueueImplP, its name will actually be AMQueueImplP$0. For example, in RadioCountToLeds, this will work:

(gdb) break *AMQueueImplP$0$Send$send
Breakpoint 5 at 0x8051b29: file AMQueueImplP.nc, line 79.
 

If you have multiple instances of a generic in a program, there is unfortunately no easy way to figure out each one's name besides looking at the source code or stepping into them. E.g., if you application uses serial and radio communication, knowing which stack has AMQueueImpl$0 and which has AMQueueImplP$1 requires either stepping through their send operation or looking at their app.c files.

 

分享到:
评论
2 楼 kooyee 2009-08-06  
不好意思,好久没来了,请问你用的是那个版本的tinyos?
1 楼 lanni33 2009-04-14  
你好,我想问一下,你学习TOSSIM现在到什么程度了。教程上的例子你已经成功运行了。我有一些问题期待与你交流。
我在调试RadioCountToLeds应用程序时,怎么也触发不了SendDone事件。而且定时器也没有按照定的时间到时。你当时遇到这类问题了么?

相关推荐

    TinyOS学习笔记

    这篇文档是学习TinyOS过程中的笔记,是了解TinyOS的比较好的中文参考

    tinyos学习历程

    教你如何入手tinyos,以及学习nesc编程语言!

    tinyOS内核分析

    本文档从中间代码入手对 TinyOS 内核进行了简要分析,对于那些接触tinyOS 的人来说,这些是必须的,也是基础性的东西。

    tinyos.sh文件

    tinyos.sh文件,在linux环境下生成,cygwin环境下可用,tinyos.sh文件总出问题的可以下载,将绝对路径修改成自己的

    tinyos51 for 51 操作系统

    TinyOS51系统整合了RTX51—Tiny的优点,并在LQ51内核基础上增加了消息列队功能。1、在TinyOS51系统中_task_关键依然有效,0号任务依然是最高优先级的任务,1号任务次之,依次类推。2、。同时TinyOS51系统弥补了RTX51...

    uabantu下安装TinyOS需要的软件包

    2015/11/04 01:01 772 avr-tinyos-base_2.1-20080806_all.deb 2015/11/04 01:01 760 avr-tinyos_2.1-20080806_all.deb 2015/11/04 00:49 230,356 avrdude-tinyos_5.4-20080806_i386.deb 2015/11/04 00:49 1,065,420 ...

    tinyos中文手册

    TinyOS是UC Berkeley(加州大学伯克利分校)开发的开放源代码操作系统,专为嵌入式无线传感网络设计,操作系统基于构件(component-based)的架构使得快速的更新成为可能,而这又减小了受传感网络存储器限制的代码...

    TinyOS入门手册

    TinyOS入门手册 入门手册 TinyOS TinyOS入门手册

    tinyos tutorials学习小结

    在网上看到的前人学习tinyos tutorial的学习总结,跟大家分享一下

    Ubuntu安装TinyOS密码tinyos

    本PDF密码为tinyos,在资料中详细讲解了TinyOS2.0以上版本在Ubuntu上的安装与测试,更关键的是安装中遇到的问题都有详细的解决方式。

    tinyos-ubuntu16.04安装tinyos2.1.2.txt

    tinyos-ubuntu16.04安装tinyos2.1.2

    tinyos中文学习资料

    tinyos中文学习资料,包括很详细的代码解释。

    tinyos-release-tinyos-2_1_2.tar.gz

    根据tinyos官方网站上下载的tinyos2.1.2版本的发行包,其链接是:http://github.com/tinyos/tinyos-release/archive/tinyos-2_1_2.tar.gz

    基于ZigBee的TinyOS系统设计

    实现了用于TinyOS上的Zigbee协议

    TinyOS中文手册

    TinyOS+中文手册.pdf TinyOS+中文手册简体中文详细解说

    tinyos os embend

    tinyOS yuan ma

    TinyOS源码说明

    javadoc:为TinyOS自带Java工具(Listen、MIG、SerialForwarder等)的代码说明 micazdoc:micaz平台上所有组件和接口的说明文档 telosbdoc:telosb平台上所有组件和接口的说明文档

    论文研究-TinyOS任务调度的研究与改进 .pdf

    TinyOS任务调度的研究与改进,李明,丁恩杰,本文介绍了TinyOS任务调度机制,指出TinyOS调度策略的特点及不足。采用一种改进式NPEDF算法对TinyOS的调度器进行实时性改造,并详细描述�

    Small RTOS51 tiny os with sem&signal&Mbox Ver 2.0

    TinyOS51系统整合了RTX51—Tiny的优点,并在LQ51内核基础上增加了消息列队功能。1、在TinyOS51系统中_task_关键依然有效,0号任务依然是最高优先级的任务,1号任务次之,依次类推。2、。同时TinyOS51系统弥补了RTX51...

    tinyos中文学习指南

    分为7课,翻译过来的,可能有不准确的地方,是tinyos1.x

Global site tag (gtag.js) - Google Analytics