I've started a Thread project, which I intend to modify so that I control the LEDs of a node 2 over the air, pressing the switches in node 1.
I'm currently using the "frdmkw41z_wireless_examples_thread_router_eligible_device_freertos" example, and managed to add external LEDs and control them through the demo provided.
Nevertheless, I would like to use external switches to control more LEDs, since my evaluation kit (PAN4620) only has 2 working switches (SW2 and SW3; SW1 is reset).
Thus, how can I manage the link between gKBD_EventPBn_c (n: number of event) and the GPIO input (SW pressed).
Also, the use of APP_AppModeHandleKeyboard in router_eligible_device_app.c does not seem clear to me, can't figure out where it is invoked.
Finally, looking forward, I would like to control the input of the GPIO through a recurrent function, leaving the switch case from APP_AppModeHandleKeyboard behind. Therefore, where is the main loop of the app to append this function and ensure the demo keeps working.
Thanks in advance,
The different thread demos works with a operative system and there are both tasks and events, in this case the API for the keyboard will be triggered with a button/switch event, you can use the same switch case for your needs in this case.
I would recommend you to check the Kinetis Thread Stack Application Developer's Guide, I believe this will be helpful for you as well as this other post : https://community.nxp.com/docs/DOC-333784 .
So much to learn! Here are two questions based on the resources provided:
1. From the Kinetis Thread Stack Application Developer's Guide - Chapter 5 Reading IP Address Configuration, THR_GetIP6Addr function is used in router_eligible_device_app.c (line 351) to, quote, "set application CoAP destination to all nodes on connected network".
How can I set this destination address, for example, in node 1's gCoapDestAddress to be the Ip6Addr from node 2? So that when pressing the switches in node 1, the CoAP command is sent only to node 2 and activate his LEDs.
In other words, where is the Ip6Addr of node 2 defined, to set the gCoapDestAddress of node 1 to this address directly in firmware; how is this coded?
I understand this can be done through terminal with ifconfig, but I would like to do this by the board itself.
Note: Developer's Guide - 22.214.171.124 The IEEE EUI64 address says the EUI64 is meant only to commissioning purposes.
2. My intention is to create a task that reads constantly the inputs of node 1, and send this information to node 2, to activate LEDs. From your post Kinetis W: [Thread] CoAP basics and hands on, I could create a resource that do this. However, how may I call this task in the APP_Handler "which runs on the default application task, as called in the main_task loop" [3.7 Application task message queue and event handlers], to achieve my intentions; I'm I on the right path?
1. Maybe you can try to add the address from the routing table when the device is connected, have you tried that ?
2. Have you considered using a timer to set an event an read the resource?
1. I've found the IP6_GetRoute function, which "Returns the pointer to the entry corresponding to the give index in routing table". So, in router_eligible_device.c, I declared as public global variables:
/* Index and Pointer to Routing Table */
uint32_t index = 1; // second entry of table
ip6RoutingTblEntry_t *pTblEntry = NULL;
Then, in Stack_to_APP_Handler, in the switch case gThrEv_GeneralInd_Connected_c: triggered by a connection of the device, I defined the following:
// /* Set application CoAP destination to all nodes on connected network */
// THR_GetIP6Addr(mThrInstanceId, gAllThreadNodes_c, &gCoapDestAddress, NULL);
/* Set application CoAP destination to the second node on connected network */
pTblEntry = IP6_GetRoute(index);
gCoapDestAddress = pTblEntry->dstPrefix;
However, after successfully connecting, the nodes do not send the CoAP commands (whether the index is 0 or 1).
2. I've used the Periodic Interrupt Timer (Pit), so your proposal seems like a good approach; any further recommendations?
Sorry , I did not get the approached you are following in the step one, you can get the address from the table and use it to send the message in the callback by using a timer.
You can try using this https://community.nxp.com/docs/DOC-345405 post as a base on adding a task in the wireless connectivity scheduler.
Hope this helps
I apologize, what I'm trying is to take the frdmkw41z_wireless_examples_thread_router_eligible_device_freertos example as it comes, just imported from the SDK, and modify only the gCoapDestAddress global variable assignment in router_eligible_device.c so that it sends commands to one specific node. Since in function Stack_to_APP_Handler, it is set to ALL nodes.
It seems as easy as changing the line 322:
THR_GetIP6Addr(mThrInstanceId, gAllThreadNodes_c, &gCoapDestAddress, NULL);
to the desired CoAP destination address (ipAddr_t). However, I've tried using:
gCoapDestAddress = IP6_GetRoute(0)->dstPrefix;
gCoapDestAddress = IP_IF_GetAddrByIf6(gIpIfSlp0_c, 0, FALSE)->ip6Addr;
and neither have worked.
That does not seem to be the correct approach, when you start the demo, you need to create a network and once you have the network the node will join and be given an address in the network.
if you want to send it in a creating node, you can check the post I already sent you . In the callback for the resource you can find there how they add the address before sending the CoAP message,.
FLib_MemCpy(&pMySession->remoteAddr,&gCoapDestAddress,sizeof(ipAddr_t)); COAP_SendMsg(pMySession, pMySessionPayload, pMyPayloadSize);
Hope this helps,
Yes thank you, I see how the FLib_MemCpy passes the address from gCoapDestAddress to the pMySession->remoteAddr.
Nevertheless, since gCoapAddress is set to gAllThreadNodes_c in line 322 as mentioned in my previous reply, I was trying to change that direction there.
Because of your observation, now I've been trying to modify the FLib_MemCpy function, so that the pSrc pointer parameter points to a specific node's address. Since I didn't found documentation for IP address tables, this was my last attempt:
/* Buffer IP address by index */ iIpIdx = 0; FLib_MemCpy(&pSession->remoteAddrStorage.ss_addr, &IP_IF_GetAddrByIf6(gIpIfSlp0_c, iIpIdx, FALSE)->ip6Addr, sizeof(ipAddr_t));
FLib_MemCpy(&pSession->remoteAddrStorage.ss_addr, &IP6_GetRoute(iIpIdx)->dstPrefix, sizeof(ipAddr_t));
But neither work as wished.
Please check the Kinetis Thread Stack Application Developer’s Guide, there you can find information of the CoAP usage as well as a brief description on how to use sockets.
<installation path >\SDK_2.2.1_FRDM-KW41Z\docs\wireless\Thread
You will find more information as well of the Thread demos.