This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] RTOS/TM4C1294NCPDT:只有从 networkIPAddrHook 启动任务时、getaddrinfo 才起作用

Guru**** 2334960 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/601702/rtos-tm4c1294ncpdt-getaddrinfo-works-only-if-the-task-is-started-from-networkipaddrhook

器件型号:TM4C1294NCPDT

工具/软件:TI-RTOS

我正在尝试使 DNS 正常工作、但这似乎不是很容易。 函数 DNSGetHostByName 总是无法解析 IP 地址、因此我必须使用 getaddrinfo。 唯一的问题是、只有当我从 networkIPAddrHook 动态创建任务时、它才起作用。 如果我静态创建一个任务(意味着将其添加到.cfg 文件中)、它将无法获取地址。 所有代码和输出的下方。

TI-RTOS:2.16.1.14

XDCTools:3.32.0.06

NDK:2.25.00.09

.cfg

/*========================= NDK 配置=================== //
var NDK= xdc.loadPackage ('ti.ndk.config');
var Global= xdc.useModule('ti.ndk.config.Global');
var IP= xdc.useModule('ti.ndk.config.Ip');
var UDP= xdc.useModule('ti.ndk.config.Udp');
var TCP= xdc.useModule('ti.ndk.config.Tcp');
var DNS= xdc.useModule('ti.ndk.config.Dns');

Global. ipv6 = false;
Global. stackLibType = Global. min;
Global.networkOpenHook ="&TcpHooks_vNetOpenHook";
Global.networkIPAddrHook ="&TcpHooks_vAddrIPHooks";

(这无法解析 IP 地址)
var task11Params = new Task.Params ();
task11Params.instance.name ="hDnsTest";
task11Params.priority = 1;
Program.global.hDnsTest = Task.create ("&testTaskFxn"、task11Params);

//自动调用 fdOpen/CloseSession for our 套接字任务*/
Global.autoOpenCloseFD = true;

Global. pktNumFrameBufs=10;
Global. memRawPageCount = 6;
Global. ndkThreadStackSize = 1536;
Global. lowTaskStackSize = 1024;
Global.normTaskStackSize = 1024;
Global. highTaskStackSize = 1024;
//Global. stackBeginHook ="&TcpHooks_vReadIPAddress";

tcp.transmitBufSize = 1024;
tcp.receiveBufSize = 1024;

Ip.autoIp = true; 

tcphooks.c

解析 IP 地址以测试

#define HOSTNAME 的任务 "www.google.de
"静态字符条[iNet_ADDRSTRLEN];

void testTaskFxn (UArg0、UArgarg1)
{
struct addrinfo * server_data = NULL;
INT 结果;

Task_sleep (5000);

while (1)
{
System_printf ("!!!!!!!!!!! \n"、结果);

结果= getaddrinfo (HOSTNAME、"0"、NULL、&server_data);

system_printf ("getaddrinfo 结果:%d\n"、结果);

if (结果=0 && server_data!= NULL)
{
struct sockaddr addr =*(server_data->ai_addr);
iNet_ntop (AF_iNet、&(struct sockaddr_in *)&addr)->sin_addr、strip、iNet_ADDRSTRLEN);
System_printf ("已解析的地址:%s\n"、条图);

freedrinfo (server_data);
SERVER_DATA =空;
}

Task_sleep (5000);
}
} 
networkIPAddrHook:

void TcpHooks_vIPAddrHook (IPN ipaddr、uint IfIdx、uint fAdd)
{
IPN IPTmp;
CI_IPNet NA;
句柄 hCfg;
int RC = 0;
字符 IPString[16];

hCfg = CfgGetDefault();

/*初始化 IP 地址块。 *
bzero (不适用、sizeof (CI_IPNet));

如果(fADD)
{
system_printf ("networkIPAddrHook:添加了网络\n");
}
其他
{
system_printf ("networkIPAddrHook:网络已移除\n");
}

IPTmp = ntohl (ipaddr);
System_printf ("networkIPAddrHook:\tif-%d:%d.%d.%d.%d\n"、IfIdx、
(uint8)(IPTmp>>24)&0xFF、(uint8)(IPTmp>16)&0xFF、
(uint8)(iptmp>>8)&0xFF、(uint8) iptmp&0xFF);

/*仅当存在 IP 地址信息时,才打印该 IP 地址信息。 *
IF (CfgGetImmadi调解(hCfg、CFGTAG _IPNet、1、1、sizeof (NA)、 (uint8 *)&nA)=sizeof (nA)
{
//是的,设备已配置,我们获得了 IP 地址/掩码*/
NtIPN2Str (na.ipaddr、IPString);
System_printf ("IP 地址:%s\n"、IPString);
NtIPN2Str (na.IPMask、IPString);
System_printf ("IP 子网掩码:%s\n"、IPString);
}
其他
{
System_printf ("IP 地址和子网掩码不可用\n");
}

RC = CfgGetImmadi调解(hCfg、CFGTAG _SYSINFO、CFGITEM_DHCP_DOMAINNAMESERVER、
1、4、(uint8 *)&iptmp);
如果(RC = 4)
{
IPTmp = ntohl (IPTmp);
System_printf ("networkIPAddrHook:\tif-%d:DNS =%d.%d.%d.%d\n"、IfIdx、
(uint8)(IPTmp>>24)&0xFF、(uint8)(IPTmp>16)&0xFF、
(uint8)(IPTmp>>8)&0xFF、(uint8) IPTmp&0xFF);
}
其他
{
system_printf ("networkIPAddrHook:DNS IP 获取失败!!!\n");
}

//如果任务未在.cfg 文件中定义,则会创建此任务
Task_Params taskParams;
ERROR_Block EB;
静态 bool init = false;
静态 Task_handle 任务处理;

/*添加 IP 地址时创建 HTTP 任务*/

if (fADD &&!init)
{
init = true;
ERROR_INIT (&EB);

Task_Params_init (&taskParams);
taskParams.STACKSIZE = 4096;
taskParams.priority = 1;
taskHandle = Task_create ((Task_FuncPtr) testTaskFxn、&taskParams、&EB);
if (taskHandle == NULL){
System_printf ("创建任务失败\n");
}
其他
{
system_printf ("已在 prioirty 1\r\n"创建任务);
}
}

结果:

在 ipaddhook 中创建任务时:

!!!!!!!!!!!
,getaddrinfo 结果:0
解析地址:216.58.213.195

在.cfg 中创建任务时

!!!!!!!!!!!
,00005.005 getaddrinfo:错误:无法解析主机名“www.google.de”

,getaddrinfo 结果:-2

!!!!!!!!!!!
,00010.005 getaddrinfo:错误:无法解析主机名“www.google.de”

,getaddrinfo 结果:-2

那么、问题是、为什么我只能 从从 ipaddrhook 动态创建的任务中成功调用 getaddrinfo? 为什么 DNSGetHostByName 根本不起作用?

JHi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Jhi、

    必须从线程内调用 NDK 套接字 API (您正在正确执行此操作)、但也必须在为该线程打开文件描述符会话后调用。  这是通过如下代码完成的:

    void myTaskThread()//静态创建的任务线程
    {
    fdOpenSession (TaskSelf ());//打开此线程的 NDK 文件描述符会话
    
    //在此处调用一些套接字 API,例如 sock()或 getaddrinfo()。
    
    fdCloseSession(TaskSelf();//关闭此线程的 NDK 文件描述符会话
    } 

    对于动态创建的任务线程、配置文件的以下设置会自动为您打开文件描述符设置:

    [引用 user="JHi ]/*为套接字任务自动调用 fdOpen/CloseSession */ Global.autoOpenCloseFD = true;

    此配置设置导致仅为动态创建的任务线程自动调用"fdOpenSession()"和"fdCloseSession()"。  这就是 getaddrinfo()为动态创建的任务线程工作的原因。

    对于静态创建的任务线程、您必须在代码中显式添加调用、如上面的示例所示。


    Steve

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的解释!

    JHi