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.
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
First create a folder
components/matter/connectedhomeip/examples/on-off-plug/bekento store the code and configuration of the new device.
mkdir -p components/matter/connectedhomeip/examples/on-off-plug/beken
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
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}
Create the file
args.gnwith 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.
Create
BUILD.gnto 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
Realize the basic operations of the plug device, mainly realizing the initialization of the Plug device and some other operations
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 }
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.
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}
Start the Matter process, initialize and start the Matter CHIP process
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