Wednesday, November 24, 2010
The corresponding variable in OTCL node class of protocols in NS2
$ns_ node-config -adhocRouting $opt(adhocRouting) \
-llType $opt(ll) \
-macType $opt(mac) \
-ifqType $opt(ifq) \
-ifqLen $opt(ifqlen) \
-antType $opt(ant) \
-propType $opt(prop) \
-phyType $opt(netif) \
-agentTrace OFF \
-routerTrace ON \
-macTrace ON\
-topoInstance $topo\
-energyModel $opt(energy)\
-txPower $opt(txpower)\
-rxPower $opt(rxpower)\
-initialEnergy $opt(initialenergy)\
-idlePower $opt(idlepower)\
-channel $chan_1_ \
-movementTrace OFF
Then, for each node, the instance of declared protocols is generated. Accrodingly, a corresponding variable in OTCL class Node is bound to the instance.
Sometimes, we need to setup the attribute of the protocol on each node individually. In this case, we should access the corresponding variable of the protocol. For example, we access routing protocol instance using
set rt [$node_($i) set ragent_]
then, we can use $rt to call the command designed for the routing protocol or set its C++ variables.
Following are some otcl variables in class Node
arptable_
nifs_ #number of interfaces
netif_
mac_
ifq_
ll_
imep_
For each of the last 5 variables, we totally have nifs_ elements. Thus, we should use index to specify which interface it is on. For example, we use the following command to access the mac protocol object on the first interface.
set mac [$node_($i) set mac_(0)]
Wednesday, November 10, 2010
[zz]vi 技巧
VIM TIPS
1. 词自动补全:
2. 行自动补全:
3. 文件名自动补全:
4. 搜索的正则表达式:
\ 取消后面所跟字符的特殊含义。比如 \[vim\] 匹配字符串“[vim]”
[] 匹配其中之一。比如 [vim] 匹配字母“v”、“i”或者“m”,[a-zA-Z] 匹配任意字母
[^] 匹配非其中之一。比如 [^vim] 匹配除字母“v”、“i”和“m”之外的所有字符
. 匹配任意字符
* 匹配前一字符大于等于零遍。比如 vi*m 匹配“vm”、“vim”、“viim”……
\+ 匹配前一字符大于等于一遍。比如 vi\+m 匹配“vim”、“viim”、“viiim”……
\? 匹配前一字符零遍或者一遍。比如 vi\?m 匹配“vm”或者“vim”
^ 匹配行首。例如 /^hello 查找出现在行首的单词 hello
$ 匹配行末。例如 /hello$ 查找出现在行末的单词 hello
\(\) 括住某段正规表达式
\数字 重复匹配前面某段括住的表达式。例如 \(hello\).*\1 匹配一个开始和末尾都是“hello”,中间是任意字符串的字符串
对于替换字符串,可以用“&”代表整个搜索字符串,或者用“\数字”代表搜索字符串中的某段括住的表达式。
5. 替换1,3s/pattern/replace/gc
1,3表示从第一行到第3行,可以用.,$表示当前行到文件末尾,可以用%表示当前行
s表示替换
pattern表示要替换的模式(可以是正则)
replace表示要使用的替换文本;
g表示全局,会在替换一个后替换下一个
c表示确认,再替换每一个时提示确认信息
6.替换中:可用v选中一个区域,使用’<和’>分别代表区域开始和结束
7.替换中,可用\zs和\ze分别表示匹配由此开始和匹配到此结束;\=表示后面是一个表达式,可以使用printf等方法,来根据匹配到的串计算值;
line()方法用来获取行号,如line(“.”)表示当前行,line(“‘<”)表示选中的第一行行号
submatch(0) == \0
|可用于分隔多条命令
g/str1/s//str2/ 表示对于匹配“str1”的所有串,执行后面的命令(g的作用,后面命令指s替换),s省略匹配串,表示使用前面g命令的匹配串,str2表示替换为str2
8. f@表示在该行向后调到第一个‘@’字符处,F@是向左跳转
9. [{向前跳转到第一个{ ]}是像后跳转到第一个}
10. v|c|d i|a { | [ | ” | ‘ 实现块级编辑
如在
{
aaaaaaaaaa
}
的aaa这行出按下vi{将选中aaa这一行,如果是va{则表示选中包含左右大括号和aaa那一行的三行
待补充。。。
read file in shell
s 1 3 0 1095738.816916 120
s 1 3 1 1095777.816447 120
s 1 3 2 1095839.816783 120
s 1 3 3 1095849.817093 120
s 1 3 4 1095889.817398 120
s 1 3 5 1095890.817669 120
s 1 3 6 1095894.817986 120
s 1 3 7 1095993.818285 120
s 1 3 8 1096094.818604 120
s 1 3 9 1096112.818891 120
s 1 3 10 1096138.819238 121
s 1 3 11 1096177.819493 121
s 1 3 12 1096185.819823 121
s 1 3 13 1096249.820129 121
s 1 3 14 1096296.820428 121
s 1 3 15 1096302.820737 121
r 1 3 0 1095793.176704 120
r 1 3 1 1095924.886250 120
r 1 3 2 1096002.680910 120
r 1 3 3 1096038.632938 120
r 1 3 4 1096074.528630 120
r 1 3 5 1096188.276739 120
r 1 3 6 1096248.133086 120
r 1 3 7 1096272.128736 120
r 1 3 8 1096319.986210 120
$ cat ./tmp.data | while read a b c d e f; do echo $a $b $c $d ; done
1 3 0
1 3 1
1 3 2
1 3 3
1 3 4
1 3 5
1 3 6
1 3 7
1 3 8
1 3 9
1 3 10
1 3 11
1 3 12
1 3 13
1 3 14
1 3 15
1 3 0
1 3 1
1 3 2
1 3 3
1 3 4
1 3 5
1 3 6
1 3 7
1 3 8
Friday, July 23, 2010
[zz]matlab求整数规划
最近碰到要求整数规划,在网上找到了一个非常好的matlab的工具箱—YALMIP,用他可以解决线性规划,非线性规划,整数规划,混合规划,强烈推荐把这个工具整合到matlab中去,这个工具是私人的,不过大家都可以免费下载使用。下载后,只要在matlab中添加路径就可以使用这工具箱。
正在吸引我的是,这个工具箱建立了一种新的数据类型,使所有规划问题都整合在一起。
举例如下:
已知非线性整数规划为:
Max z=x1^2+x2^2+3*x3^2+4*x4^2+2*x5^2-8*x1-2*x2-3*x3-x4-2*x5
s.t.
0<=xi<=99(i=1,2,...,5)
x1+x2+x3+x4+x5<=400
x1+2*x2+2*x3+x4+6*x5<=800
2*x1+x2+6*x3<=800
x3+x4+5*x5<=200
在matlab中输入 x=intvar(1,5);
f=[1 1 3 4 2]*(x'.^2)-[8 2 3 1 2]*x';F=set(0<=x<=99);
F=F+set([1 1 1 1 1]*x'<=400)+set([1 2 2 1 6]*x'<=800)+set(2*x(1)+x(2)+6*x(3)<=800);
F=F+set(x(3)+x(4)+5*x(5)<=200);solvesdp(F,-f)
double(f) 80199
double(x) 53 99 99 99 0
intvar(m,n):生成整数型变量;
sdpvar(m,n):生产变量;
solvesdp(F,f):求解最优解(最小值),其中F为约束条件(用set连接),f为目标函数
double:显示求解的答案
intvar,sdpvar,生成的变量可以像矩阵一样使用,如例题显示。
Tuesday, June 8, 2010
[zz]RT-N13U REPEATER SETUP PROCEDURE
---------------------------------
I had a problem setting up my RT-N13U in repeater mode (it took me a day). There is no documentation. So, I thought I would post a procedure here to help others.
PRIOR STEPS
----------
1. Before powering up the RT-N13U change the switch at the bottom of the device to the repeater position. If needed, see the reset option below.
2. Connect your computer to LAN port 1 on the RT-N13U
3. On your MAIN router, setup security first. Recommended settings are:
WPA2 with AES and a passphrase. I set mine to WPA2-Personal but your router might be different. (Note, even though a passphrase will work with symbols in regular mode, in repeater mode, the passphrase can not have symbols—this is what cost me a day trying to figure out)
4. Also set your MAIN router to run in G and N modes if desired. I set mine to Auto which does both.
SETTING UP RT-N13U
------------------
1. Keep your MAIN router turned on.
2. The PC/Laptop can not be receiving a signal. Shut off the wireless connection on your PC/Laptop now power it down.
3. Power up the RT-N13U and your computer and wait for them to connect.
4. Open a web browser (Internet Explorer) and go to http://192.168.1.220 and it should ask you for a user name and password, these are admin and admin
5. The ASUS Router Manager should open
6. At this point you should see the name of your MAIN router's ssid. If not, make sure you are in the Network Map Tab. Click on the top box (of a router with repeater mode). On the right, will be a box with Access Point Status. Click on the OK button next to AP Survey.
7. Select your MAIN router's ssid and click connect at the bottom of the page
8. In the network key (this is the MAIN router's passphrase), enter the passphrase and click connect
9. You should successfully establish the wireless connection
10. Note the new ip address for future reference to be able to connect to the setup page when not connected through a LAN cable (this is the address of the RT-N13U on your MAIN router)
11. Now, click the home button on your browser and get your home page. Connect to a site on the internet, if you can connect to the internet, your RT-N13U is working in repeater mode!!!
12. Now, power down and unplug the RT-N13U and place it wherever you need it to extend your network (make sure it is close enough to the MAIN router to receive a connection) plug it in
RESET/TROUBLESHOOTING
---------------------
If the RT-N13U fails to pick up a connect from the MAIN router, or you need to start from the beginning, you will need to reset the device:
1. Power off and set switch on the bottom of RT-N13U back to ap mode and power on, wait for 30 seconds. Power off.
2) Reset switch to repeater mode
3) Power on again and repeat the connection steps above
[zz]内核定时器 struct timer_list
定时器,有时也称为动态定时器或内核定时器,是管理内核时间的基础。内核经常要推后执行某些代码,比如下半部机制就是为了将工作推后执行。我们需要 一种工具,使工作能够在指定时间点上执行,正好在希望的时间点上,内核定时器正是这样一种工具。
定时器使用简单,只须执行一些初始化工作,设置一个超时时间,指定超时发生后执行的函数,然后激活定时器就可以了。
注意,定时器并不周期运行,它在超时后就自行销毁,这就是这种定时器被称为动态定时器的原因。动态定时器不断地创建和销毁,而且它的运行次数也不受 限制。
- 使用定时器
定时器由结构timer_list表示:
- 在
中 - struct timer_list {
- struct list_head entry; //定时器链表的入口
- unsigned long expires; //定时器超时时的节拍数
- void (*function)(unsigned long ); //定时器处理函数
- unsigned long data; //传给定时器处理函数的长整型参数
- struct tvec_t_base_s *base; //定时器内部值,用户不 要使用
- #ifdef CONFIG_TIMER_STATS
- void *start_site;
- char start_comm[16];
- int start_pid;
- #endif
- };
- 在
中 - struct tvec_t_base_s {
- spinlock_t lock;
- struct timer_list *running_timer;
- unsigned long timer_jiffies;
- tvec_root_t tv1;
- tvec_t tv2;
- tvec_t tv3;
- tvec_t tv4;
- tvec_t tv5;
- } ____cacheline_aligned_in_smp;
内核提供了一组与定时器相关的接口用来简化管理定时器的操作。所有这些接口都声明在
创建定时器首先要先定义它,然后通过一个辅助函数初始化定时器数据结构的内部值,初始化必须在使用其他定时器管理函数之前完成:
- struct timer_list my_timer;
- init_timer(&my_timer);// 初始化定时器
- my_timer.expires = jiffies + delay; //
- my_timer.data = 0; //
- my_timer.function = my_function; //
- add_timer(&my_timer); //最后,激活定时器
【补充】
也可以这样调用:
1、setup_timer(struct timer_list, function,data); //初始化timer并赋值func和data
2、mod_timer();修改并启动之。另外,定时值可以这样设 定:msecs_to_jiffies(50);
调用方式:
mod_timer(&mytimer, jiffies + msecs_to_jiffies(50) );
处理函数的原型:
void my_timer_function(unsigned long data);
data参数可以使你利用同一个处理函数注册多个定时器,只须通过该参数就能区别对待他们。如果你不需要这个参数,可以简单传递0或任何其他值给处 理函数。
当前节拍计数等于或大于指定的超时时,内核就开始执行定时器处理函数。因为内核有可能延误定时器的执行,所以不能用定时器来实现任何硬实时任务。
有时可能需要更改已经激活的定时器超时时间,内核通过mod_timer()来实现该功能。当定时器已经初始化,但未激活,mod_timer() 就激活它。一旦从该函数返回,定时器都被激活而且设置了新的定时值。
- int mod_timer( struct timer_list *timer, unsigned long expires)
- {
- BUG_ON(!timer->function);
- timer_stats_timer_set_start_info(timer);
- /*
- * This is a common optimization triggered by the
- * networking code - if the timer is re-modified
- * to be the same thing then just return:
- */
- if (timer->expires == expires && timer_pending(timer))
- return 1;
- return __mod_timer(timer, expires);
- }
如果要在定时器超时之前停止定时器,使用del_timer()函数:
- int del_timer( struct timer_list *timer)
- {
- tvec_base_t *base;
- unsigned long flags;
- int ret = 0;
- timer_stats_timer_clear_start_info(timer);
- if (timer_pending(timer)) {
- base = lock_timer_base(timer, &flags);
- if (timer_pending(timer)) {
- detach_timer(timer, 1);
- ret = 1;
- }
- spin_unlock_irqrestore(&base->lock, flags);
- }
- return ret;
- }
被激活或未被激活的定时器都可以使用该函数。注意,不要为已经超时的定时器调用该函数,因为它们会自动被删除。
删除定时器时要消息,可能存在潜在的竞争条件。多处理器机器上定时器中断可能已经在其他处理器上运行了,所以删除定时器时需要等待可能在其他处理器 上运行的定时器处理程序都退出,这是要使用del_timer_sync()函数执行删除工作:
- int del_timer_sync( struct timer_list *timer)
- {
- for (;;) {
- int ret = try_to_del_timer_sync(timer);
- if (ret >= 0)
- return ret;
- cpu_relax();
- }
- }
和del_timer()函数不同,del_timer_sync()函数不能在中断上下文中使用。
- 定时器竞争条件
定时器与当前执行代码是异步的,因此有可能存在潜在的竞争条件。
首先,绝不能用下列代码来代替mod_timer()函数:
- del_timer(my_timer);
- my_timer->expires = jiffies + new_delay;
- add_timer(my_timer);
其次,使用del_timer_sync()函数取代del_timer()函数。
最后,因为内核异步执行中断处理程序,所以应该重点保护定时器中断处理程序中的共享数据。
- 实现定时器
内核在时钟中断发生后执行定时器,定时器作为软中断在下半部上下文中执行。
具体来说,时钟中断处理程序会执行update_process_timers()函数,该函数随即调用run_local_timers()函 数:
run_timer_softirq()函数处理软中断TIMER_SOFTIRQ,从而在当前处理器上运行所有的超时定时器:
所有定时器都以链表形式存放在一起,为了提高搜索效率,内核将定时器按它们的超时时间划分为五组。当定时器超时时间接近时,定时器将随组一起下移。 采用分组定时器的方法可以在执行软中断的多数情况下,确保内核尽可能减少搜索超时定时器所带来的负担。
Tuesday, May 18, 2010
command for screen
teminal下命令:
screen 进入screen模式
screen -ls 查看有哪些screen (结果中含有窗口id)。
screen -r id 打开编号为id的screen窗口。
用screen新建的窗口下的命令:
Ctrl+a+c 在当前screen下建立新的窗口
exit 退出当前窗口,如果它是此screen的唯一窗口时,此screen也将完全退出。
Ctrl+a+d 暂时断开screen会话
Ctrl+a+w 显示所有窗口列表
Ctrl+a+n 切换到下一个窗口
Ctrl+a+p 切换到前一个窗口(与Ctrl+a+n相对)
screen -rd connect to an attached screen