Your First Topology detection
What you will learn:
Since the beginning of this training, you discovered how to create services, deal with messages, or control them using Pyluos. But you never created embedded application service using other services yet. It is time for you to go to the next stage and learn how to use your new superpowers!
Part 1: The topology of your system
1. Introduction
In the previous training, we created a LED and a button services to control them using Pyluos.
We will reuse those services and create our first fully embedded application able to detect the topology of our system and use the available services in it.
2. Our first embedded app, a switcher service
We will create a simple application able to find a led
and button
services, to turn on or off the LED depending on the button's state.
First, clone or download the training repository.
In PlatformIO IDE, open the folder corresponding to your board in Training/1_First_Service/Work_base from the repository you just cloned or downloaded, and connect the board to your computer with a USB cable.
Because you previously learned how to make a service's skeleton, we already prepared it for you in this tutorial.
Open the lib/switcher/switcher.c file on PlatformIO. This will be your base work.
This switcher application is specific to this tutorial, so there is no default Luos type available for it. This means that you will need to create a custom one. Let's call it SWITCHER_APP
.
void Switcher_Init(void)
{
revision_t revision = {1, 0, 0};
Luos_CreateService(Switcher_MsgHandler, SWITCHER_APP, "Switcher", revision);
}
Now we need to add this type after the Luos default ones. To do that, Luos engine provides a constant defining the beginning of the custom type list. To start your custom type list, you can add:
enum // Custom type list
{
SWITCHER_APP = LUOS_LAST_TYPE
};
3. Your first detection
To be able to use other services, we need to list them, define their position, and their purpose. To do that, Luos engine allows you to make a topology detection. The detection has to be done at least once by one of the services in the network, so that Luos engine knows how to route the different messages to their destinations. Without a detection, you can't exchange any information between services.
In the previous tutorials, the gate application was making the detection for you. Now it is time to emancipate from the gate and make the detection by yourself.
More details about detections and topology are on the related Luos documentation page.
To make a detection, Luos engine needs to know which service is requesting it. So we will need to pass the switcher service to the detection function.
To do that, you need to create a service_t
pointer, so that Luos engine allows you to link it to the actual created service, at the service creation:
/*******************************************************************************
* Variables
******************************************************************************/
// the new line to copy and paste
service_t *switcher_app; // This will be our switcher service
void Switcher_Init(void)
{
revision_t revision = {1, 0, 0};
// the new line to copy and paste
switcher_app = Luos_CreateService(Switcher_MsgHandler, SWITCHER_APP, "Switcher", revision);
}
Now we can make the detection using Luos_Detect()
:
void Switcher_Init(void)
{
revision_t revision = {1, 0, 0};
switcher_app = Luos_CreateService(Switcher_MsgHandler, SWITCHER_APP, "Switcher", revision);
// the new line to copy and paste
Luos_Detect(switcher_app);
}
After using this API, Luos engine will assign a unique ID to each service in the system and create a routing table containing all the services' information present in the network: ID, Alias, and topology. This routing table created by the service starting the detection is shared to the others. More details about the routing table can be found on the dedicated Luos documentation page.
If you check your main files, you will see a switcher package and a led package. All those packages create only one service. The service performing the detection always has the ID 1 because this service will be the “root” of your system. So in our case, the switcher app will receive ID 1. Then, the other services will get the next ID following the creation order, so the led service will receive ID 2.
Now, let's try to turn on the LED!
4. Turn on the LED on with your app
At the end of a detection, every service will receive an END_DETECTION message. To simply turn on the LED after the detection, we will use this END_DETECTION message to send an order to the LED.
void Switcher_MsgHandler(service_t *service, msg_t *msg)
{
// the new block to copy and paste
if (msg->header.cmd == END_DETECTION)
{
msg_t pub_msg;
pub_msg.header.cmd = IO_STATE;
pub_msg.header.target_mode = ID;
pub_msg.header.target = 2;
pub_msg.header.size = 1;
pub_msg.data[0] = 1;
Luos_SendMsg(switcher_app, &pub_msg);
}
}
Compile and upload the project to the board.
The led service was detected by the switcher application. At the end of the detection, a message was sent to the led service to turn on the LED.