Develop Matter new Device from scratch

[中文]

This section explains in detail the process of bk_matter creating a new Matter device type by creating a new On/Off Plug matter application based on bk_matter.

zap file configuration

The zap file is a configuration file of Matter. You can refer to the Matter protocol Device Library Specification to implement Configure the device type. For the use of zap tool, please refer to Matter Configuration Tool ZAP .

For an introduction to some basic concepts of Matter, please refer to Matter Introduction .

The zap tool will have multiple versions according to the development of matter, so the directory components/matter/connectedhomeip/zap contains two executable files:

  • zap: Used for visual editing of zap files. This tool is needed when modifying the configuration zap file.

  • zap-cli: Used to parse zap files and will be used during the compilation process.

The On/Off Plug device will include two endpoints.

Endpoint 0 device type is 0x0016 (Matter Root Node), which includes all basic clusters of Matter: basic information configuration (Basic Information cluster), wifi (Network Commissioning, WiFi Network Diagnostics), OTA (OTA Software Update Provider, OTA Software Update Requestor) etc. This part is basically the same for all types of devices. Therefore, it is more convenient to modify it directly on the basis of the examples/lighting-app/lighting-common/lighting-app.zap file. Only keep endpoint 0 and add new endpoints as needed.

The endpoint 1 device type is 0x010A (On/Off Plug-in Unit). For specific cluster configuration, you need to refer to the Device Library Specification document.

On/Off Plug-in Unit Cluster Requirements

ID

Cluster

Client/Server

Quality

Conformance

0x0003

Identify

Server

M

0x0004

Groups

Server

M

0x0005

Scenes

Server

P,M

0x0006

On/Off

Server

M

0x0008

Level Control

Server

O

Save the file as on-off-plug.zap, which will be used in the next section.

Create gn project

  1. First create a folder components/matter/connectedhomeip/examples/on-off-plug/beken to store the code and configuration of the new device.

mkdir -p components/matter/connectedhomeip/examples/on-off-plug/beken
  1. Create some soft links and introduce some required dependencies.

cd components/matter/connectedhomeip/examples/on-off-plug/beken
mkdir third_party
ln -s ../../build_overrides build_overrides
ln -s ../../../.. connectedhomeip
  1. Create file .gn, the configuration file of the gn project

 1# Copyright (c) 2022 Project CHIP Authors
 2#
 3# Licensed under the Apache License, Version 2.0 (the "License");
 4# you may not use this file except in compliance with the License.
 5# You may obtain a copy of the License at
 6#
 7# http://www.apache.org/licenses/LICENSE-2.0
 8#
 9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import("//build_overrides/build.gni")
16import("//build_overrides/chip.gni")
17
18# The location of the build configuration file.
19buildconfig = "${build_root}/config/BUILDCONFIG.gn"
20
21# CHIP uses angle bracket includes.
22check_system_includes = true
23
24default_args = {
25  target_cpu = "risc-v"
26  target_os = "freertos"
27
28  import("//args.gni")
29}
  1. Create the file args.gn with some default configuration for the project.

 1# Copyright (c) 2022 Project CHIP Authors
 2#
 3# Licensed under the Apache License, Version 2.0 (the "License");
 4# you may not use this file except in compliance with the License.
 5# You may obtain a copy of the License at
 6#
 7# http://www.apache.org/licenses/LICENSE-2.0
 8#
 9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15# Options from standalone-chip.mk that differ from configure defaults. These
16# options are used from examples/.
17
18import("//build_overrides/chip.gni")
19
20chip_device_platform = "beken"
21
22chip_project_config_include = ""
23chip_system_project_config_include = ""
24chip_ble_project_config_include = ""
25
26mbedtls_target = "${chip_root}/config/beken/mbedtls:mbedtls"
27lwip_platform = "external"
28
29chip_build_tests = false
30
31chip_inet_config_enable_tcp_endpoint = false
32chip_inet_config_enable_udp_endpoint = true
33
34chip_config_network_layer_ble = true
35chip_config_memory_management = "platform"
36chip_enable_additional_data_advertising = false
37chip_enable_rotating_device_id = true
38chip_enable_ota_requestor = false
39chip_inet_config_enable_ipv4 = true
40
41chip_detail_logging = false
42chip_automation_logging = false
43chip_use_transitional_device_instance_info_provider = false
44chip_use_transitional_commissionable_data_provider = false
45
46custom_toolchain = "${chip_root}/config/beken/toolchain:beken"

Line 20 specifies the Matter compilation platform through chip_device_platform = "beken", and the source code under src/platform/beken will be used during compilation.

  1. Create BUILD.gn to set the project source code, etc.

 1# Copyright (c) 2020 Project CHIP Authors
 2#
 3# Licensed under the Apache License, Version 2.0 (the "License");
 4# you may not use this file except in compliance with the License.
 5# You may obtain a copy of the License at
 6#
 7# http://www.apache.org/licenses/LICENSE-2.0
 8#
 9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15import("//build_overrides/build.gni")
16import("//build_overrides/chip.gni")
17import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni")
18import("${chip_root}/src/app/chip_data_model.gni")
19import("${chip_root}/examples/on-off-plug/beken/args.gni")
20
21examples_plat_dir = "${chip_root}/examples/platform/beken"
22
23chip_data_model("on-off-plug") {
24  zap_file = "on-off-plug.zap"
25
26  is_server = true
27}
28
29static_library("MatterApp") {
30  public_deps = [
31    ":on-off-plug",
32    "${chip_root}/examples/providers:device_info_provider",
33    "${chip_root}/src/platform/logging:default",
34  ]
35
36  include_dirs = [
37    "${chip_root}/examples/on-off-plug/beken/main/include",
38    "${examples_plat_dir}",
39  ]
40
41  if (chip_enable_ota_requestor) {
42    sources = [
43      "${examples_plat_dir}/common/BekenAppServer.cpp",
44      "${examples_plat_dir}/common/CHIPDeviceManager.cpp",
45      "${examples_plat_dir}/common/CommonDeviceCallbacks.cpp",
46      "${examples_plat_dir}/ota/OTAHelper.cpp",
47      "main/DeviceCallbacks.cpp",
48      "main/DsoHack.cpp",
49      "main/chipinterface.cpp",
50      "main/Plug.cpp",
51    ]
52  } else {
53    sources = [
54      "${examples_plat_dir}/common/BekenAppServer.cpp",
55      "${examples_plat_dir}/common/CHIPDeviceManager.cpp",
56      "${examples_plat_dir}/common/CommonDeviceCallbacks.cpp",
57      "main/DeviceCallbacks.cpp",
58      "main/DsoHack.cpp",
59      "main/chipinterface.cpp",
60      "main/Plug.cpp",
61    ]
62  }
63
64  output_name = "libMatterApp"
65  output_dir = "${root_out_dir}/lib"
66  complete_static_lib = true
67}
68
69group("default") {
70  deps = [ ":MatterApp" ]
71}
72
73config("config") {
74  include_dirs = [ "include" ]
75}

Lines 40-49 mainly include the application layer code of this Matter device.

Lines 22-27 pass in the zap configuration file through the function chip_data_model . Therefore, you need to copy the zap file on-off-plug.zap created in the previous section to the modified directory. In addition, it needs to be executed in the directory components/matter/connectedhomeip .

./scripts/tools/zap/generate.py examples/on-off-plug/beken/on-off-plug.zap

This will generate the on-off-plug.matter file.

During the compilation process, the required cluster will be selected and added to the source code based on these two files, and some code will be generated. For the principle of this part, you can refer to the Matter document code_generation.

Implement code

  1. Realize the basic operations of the plug device, mainly realizing the initialization of the Plug device and some other operations

Plug.cpp
 1#define KEY_GPIO        GPIO_24
 2#define CONTROL_GPIO    GPIO_26
 3#define LED_GPIO        GPIO_9
 4
 5void Plug::Init()
 6{
 7    ChipLogDetail(DeviceLayer,"Plug Init");
 8    gpio_config_t cfg;
 9	gpio_int_type_t int_type = GPIO_INT_TYPE_MAX;
10
11    bk_gpio_disable_input(CONTROL_GPIO);
12    bk_gpio_enable_output(CONTROL_GPIO);
13
14    bk_gpio_disable_input(LED_GPIO);
15    bk_gpio_enable_output(LED_GPIO);
16
17    cfg.io_mode =GPIO_INPUT_ENABLE;
18	int_type = GPIO_INT_TYPE_FALLING_EDGE;
19	cfg.pull_mode = GPIO_PULL_UP_EN;
20	bk_gpio_set_config(KEY_GPIO, &cfg);
21	bk_gpio_register_isr(KEY_GPIO ,key_callback);
22    bk_gpio_enable_interrupt(KEY_GPIO);
23
24    bk_gpio_set_output_high(CONTROL_GPIO);
25    bk_gpio_set_output_high(LED_GPIO);
26    isOn = false;
27    mFlashingFreq = 0;
28    initOver = false;
29}
30
31void Plug::StartUpInit()
32{
33    ChipLogDetail(DeviceLayer,"Plug StartUpInit");
34    if (Server::GetInstance().GetFabricTable().FabricCount() == 0)
35    {
36        LedStartFlashing(false);
37    }
38    initOver = true;
39}
40
41void Plug::SetOnOff(bool on)
42{
43    ChipLogDetail(DeviceLayer,"Plug SetOnOff");
44    if(!initOver || mFlashingFreq != 0 || on == isOn)
45    {
46        return;
47    }
  1. Implement the callback of Matter. After the Matter protocol receives changes to the relevant properties of the control end, it will call the corresponding callback.

DeviceCallbacks.cpp
 1void AppDeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId,
 2                                                     uint8_t type, uint16_t size, uint8_t * value)
 3{
 4    switch (clusterId)
 5    {
 6    case Clusters::OnOff::Id:
 7        OnOnOffPostAttributeChangeCallback(endpointId, attributeId, value);
 8        break;
 9    default:
10        ChipLogProgress(Zcl, "Unknown cluster ID: " ChipLogFormatMEI, ChipLogValueMEI(clusterId));
11        break;
12    }
13}
14void AppDeviceCallbacks::OnOnOffPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
15{
16    VerifyOrExit(attributeId == Clusters::OnOff::Attributes::OnOff::Id,
17                 ChipLogError(DeviceLayer, "[%s] Unhandled Attribute ID: '0x%04lx", TAG, attributeId));
18    VerifyOrExit(endpointId == 1 || endpointId == 2,
19                 ChipLogError(DeviceLayer, "[%s] Unexpected EndPoint ID: `0x%02x'", TAG, endpointId));
20    PlugMgr().SetOnOff(*value);
21
22exit:
23    return;
24}
  1. Start the Matter process, initialize and start the Matter CHIP process

chipinterface.cpp
 1static AppDeviceCallbacks EchoCallbacks;
 2static void InitServer(intptr_t context)
 3{
 4    chip::BekenAppServer::Init();
 5    gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
 6    chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider);
 7#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR    
 8    OTAHelpers::Instance().InitOTARequestor();
 9#endif    
10    PlugMgr().StartUpInit();
11}
12
13{
14    ChipLogProgress(DeviceLayer, "on-off-plug!");
15    chip::Inet::UDPEndPointImplLwIP::SetQueueFilter((chip::Inet::EndpointQueueFilter *)&filter);
16
17    CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance();
18    err                           = deviceMgr.Init(&EchoCallbacks); // start the CHIP task
19    if (err != CHIP_NO_ERROR)
20    {
21        ChipLogError(DeviceLayer, "DeviceManagerInit() - ERROR!\r\n");
22    }
23    else
24    {
25        ChipLogProgress(DeviceLayer, "DeviceManagerInit() - OK\r\n");
26        vTaskDelay(pdMS_TO_TICKS(50)); // Just server the application event handler
27    ChipLogProgress(SoftwareUpdate, "Exited");

Build

Modify the configuration CONFIG_MATTER_EXAMPLE="on-off-plug" in the corresponding configuration file projects/matter/config/bk7258/config

You can compile the new matter application

make bk7258 PROJECT=matter