1

我正在使用这个模块层次结构:

Node: {udpApp[0]<->udp<->networkLayer->wlan[0]} and wlan[0]: {CNPCBeacon<->mac<->radio}

使用 udpApp 的一些 ini 参数作为: 我在 udpApp 的 ini 文件中给出了一些初始参数:

**.host*.numUdpApps = 2
**.host*.udpApp[0].typename = "UDPBasicApp" 
**.host*.udpApp[0].destAddresses = "gw1"
**.host*.udpApp[0].startTime = 1.32s
**.host*.udpApp[0].stopTime = 1.48s

但在运行时,我想通过 CNPCBeacon 模块更改 udpAPP[0] 的 startTime 和 stopTime 。

因此,我将 CNPCBeacon.cc 更改为:-

cModule* parentmod = getParentModule();
cModule* grantParentmod = parentmod->getParentModule();
cModule* udpmod = grantParentmod->getSubmodule("udpApp",0);
double varHoldingStartTime = udpmod->par("startTime").doubleValue();
double varGoldingStopTime = udpmod->par("stopTime").doubleValue();
varHoldingStartTime = SIMTIME_DBL(4.2);
varGoldingStopTime = SIMTIME_DBL(4.5);
udpmod->par("startTime").setDoubleValue(varHoldingStartTime);
udpmod->par("stopTime").setDoubleValue(varGoldingStopTime);
EV<<"New start and stop time is "<<udpmod->par("startTime").str()<<"\t"<<udpmod->par("stopTime").str()<<endl;`

其中成功更改了参数。但是它不会udpApp[0]再次启动模块。所以我尝试使用这个模块的动态转换:

UDPBasicApp* udpBasicMod = dynamic_cast<UDPBasicApp*>(udpmod);
sendTimer = new cMessage("sendTimer");
scheduleAt(iniSchduleTime, sendTimer);

并导致以下错误:-

模块 (CNPCBeacon) BSoneNode.gw1.wlan[0].CNPCBeacon (id=23) 在事件 #1496 中出错,t=4:在上下文中调用模块 (UDPBasicApp)BSoneNode.gw1.udpApp[0] 的 scheduleAt()模块 (CNPCBeacon)BSoneNode.gw1.wlan[0].CNPCBeacon:从后一个模块调用的方法缺少 Enter_Method() 或 Enter_Method_Silent()?

还有其他方法可以通过其他子模块实例化模块吗?

感谢您的帮助。

4

2 回答 2

1

通过另一个模块(请求模块)重新初始化一个模块(目标模块)的解决方案是在目标模块中创建handleParamterChange()函数。handleParameterChange() 用于在 tun 时重新读取更改的参数。但是,它不会启动 scheduleAt() 事件来重新初始化目标模块的事件。所以我只是在这个函数中添加了 scheduleAt() 事件:

void UDPBasicApp:: handleParameterChange(const char* parname) 
{
    if(parname) 
    {
          if((strcmp(parname, "startTime")==0) && 
             (startTime !=  par("startTime").doubleValue()) 
                    startTime = par("startTime").doubleValue();
           if(strcmp(parname,"stopTime")==0)&& 
             (stopTime !=  par("stopTime").doubleValue())
           { 
                stopTime = par("stopTime").doubleValue(); 
                selfMsg->setKind(START); 
                scheduleAt((simtime_t)(startTime), selfMsg);
           }
}

这里注意selfMsg是在INET框架中UdpBasciApp.cc的初始化函数中定义的。

于 2015-06-13T16:48:09.527 回答
0

我对您的模块和子模块之间的层次结构和关系有点迷失,但是我认为如果您想动态创建(或重新创建)一个模块,您可以使用 OMNeT++ 建议的内置方法:https:/ /omnetpp.org/doc/omnetpp/manual/usman.html#sec186

一旦您(重新)定义了参数值,也许您可​​以直接使用单线:

cModuleType *moduleType = cModuleType::get("foo.nodes.WirelessNode");
cModule *mod = moduleType->createScheduleInit("node", this);

另一方面,您的错误消息抱怨:Enter_Method()和/或Enter_Method_Silent()

X::get()如果您尝试从另一个模块中调用模块(示例)的函数,则应使用这些宏:

Y::doSmthWithXsGet()
{
    x->get();
}

为了使这个工作Enter_Method()(或Enter_Method_Silent())必须写在开头X::get()

X::get()
{
    Enter_Method();
    /* rest of the code */
}

您可以阅读OMNeT++ 用户手册的Direct Method Calls部分来了解这意味着什么。


奇怪的是,你得到了这个scheduleAt()方法的错误,这是一个属于基本 OMNeT++ 类的方法cSimpleModule。这意味着,为了在您的类中使用此方法,您必须从cSimpleModule您的类定义中继承。

也许只是做类似的事情:

class MyCurrentClass: public cSimpleModule
{
    /* further class definition */
};

...可以解决你的问题。

于 2015-06-09T12:01:40.807 回答