Skip to content

Commit

Permalink
riscv: telink: optimize startup time
Browse files Browse the repository at this point in the history
 - optimize startup time and the time less than 600ms .
 - adjust cluster info proc location to be in front of POST_KERNEL .

Signed-off-by: Fengtai Xie <[email protected]>
  • Loading branch information
fengtai-telink committed Dec 27, 2024
1 parent 283579c commit 09271bd
Show file tree
Hide file tree
Showing 7 changed files with 358 additions and 4 deletions.
4 changes: 4 additions & 0 deletions config/telink/chip-module/Kconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ config EXPOSE_CHIP_ID_VIA_BLE
bool "Get CHIP ID via ble"
default n

config STARTUP_OPTIMIZATE
bool "Control startup speed optimization"
default n

# Set multiplicator of Name Value Storage (NVS) as 1 to reach NVS sector size 4KB
# nvs_sector_size = flash_page_size * mult = 4KB * 1 = 4KB
config SETTINGS_NVS_SECTOR_SIZE_MULT
Expand Down
78 changes: 78 additions & 0 deletions examples/lighting-app/telink/src/ZclCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,47 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
using namespace chip;
using namespace chip::app::Clusters;

#if CONFIG_STARTUP_OPTIMIZATE
#include "AppTaskCommon.h"

static uint8_t latest_level = 0;
#define CLUTER_SOTRE_TIMEOUT 500
#define TRANSTION_TIMER_INIT_FLAG 0x55
#define TRANSTION_TIMER_DEINIT_FLAG 0x00

struct k_timer LevelChangeTimer;
static int timer_period = CLUTER_SOTRE_TIMEOUT;
static uint8_t init_timer = TRANSTION_TIMER_INIT_FLAG;

static void LevelTimeoutCallback(struct k_timer * timer)
{
if (!timer)
{
return;
}

cluster_startup_para cluster_para;
if (read_cluster_para(&cluster_para) != 0)
{
if (uart_init_flag)
{
printk("[LevelTimeoutCallback] Fail read startup cluster para\n");
}
}
if (cluster_para.level != latest_level)
{
cluster_para.level = latest_level;
if (store_cluster_para(&cluster_para) != 0)
{
if (uart_init_flag)
{
printk("[LevelTimeoutCallback] Fail store startup cluster para\n");
}
}
}
}
#endif // CONFIG_STARTUP_OPTIMIZATE

void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size,
uint8_t * value)
{
Expand All @@ -40,6 +81,43 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath &
ChipLogProgress(Zcl, "========MatterPostAttributeChangeCallback:clusterId=0x%x,AttributeId=0x%x,value=0x%x", clusterId,
attributeId, *value);

#if CONFIG_STARTUP_OPTIMIZATE
if (init_timer == TRANSTION_TIMER_INIT_FLAG)
{
k_timer_init(&LevelChangeTimer, &LevelTimeoutCallback, nullptr);
init_timer = TRANSTION_TIMER_DEINIT_FLAG;
}

if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id)
{
cluster_startup_para cluster_para;
if (read_cluster_para(&cluster_para) != 0)
{
if (uart_init_flag)
{
printk("[clusterId:OnOff] Fail read startup cluster para\n");
}
}
if (cluster_para.onoff != *value)
{
cluster_para.onoff = *value;
if (store_cluster_para(&cluster_para) != 0)
{
if (uart_init_flag)
{
printk("[clusterId:OnOff] Fail store startup cluster para\n");
}
}
}
}
else if (clusterId == LevelControl::Id && attributeId == LevelControl::Attributes::CurrentLevel::Id)
{
latest_level = *value;
k_timer_stop(&LevelChangeTimer);
k_timer_start(&LevelChangeTimer, K_MSEC(timer_period), K_NO_WAIT);
}
#endif // CONFIG_STARTUP_OPTIMIZATE

#else
static HsvColor_t hsv;
static XyColor_t xy;
Expand Down
22 changes: 22 additions & 0 deletions examples/platform/telink/common/include/AppTaskCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,28 @@ extern uint8_t para_lightness;
extern uint8_t sBoot_zb;
#endif

#if CONFIG_STARTUP_OPTIMIZATE
#define USER_CLUSTER_PARTITION user_cluster_partition
#define USER_CLUSTER_PARTITION_DEVICE FIXED_PARTITION_DEVICE(USER_CLUSTER_PARTITION)
#define USER_CLUSTER_PARTITION_OFFSET FIXED_PARTITION_OFFSET(USER_CLUSTER_PARTITION)
#define USER_CLUSTER_PARTITION_SIZE FIXED_PARTITION_SIZE(USER_CLUSTER_PARTITION)

typedef struct
{
uint8_t onoff;
uint8_t level;
uint8_t rfu[30];
} cluster_startup_para;

extern volatile bool uart_init_flag;

void set_debug_flag(bool flag);
volatile bool read_debug_flag(void);
void init_cluster_partition(void);
int store_cluster_para(cluster_startup_para * data);
int read_cluster_para(cluster_startup_para * data);
#endif // CONFIG_STARTUP_OPTIMIZATE

#include <cstdint>

using namespace ::chip;
Expand Down
140 changes: 140 additions & 0 deletions examples/platform/telink/common/src/AppTaskCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,141 @@ class AppCallbacks : public AppDelegate
AppCallbacks sCallbacks;
} // namespace

#if CONFIG_STARTUP_OPTIMIZATE
volatile bool uart_init_flag = false;
const struct device * cluster_para_dev = USER_CLUSTER_PARTITION_DEVICE;

uint32_t cluster_para_addr = USER_CLUSTER_PARTITION_OFFSET;
#define CLUSTER_PARA_LEN (sizeof(cluster_startup_para))
#define USER_CLUSTER_PARTITION_END (USER_CLUSTER_PARTITION_OFFSET + USER_CLUSTER_PARTITION_SIZE)

void set_debug_flag(bool flag)
{
uart_init_flag = flag;
}

volatile bool read_debug_flag(void)
{
return uart_init_flag;
}

void clear_cluster_para(void)
{
flash_erase(cluster_para_dev, USER_CLUSTER_PARTITION_OFFSET, USER_CLUSTER_PARTITION_SIZE);
cluster_para_addr = USER_CLUSTER_PARTITION_OFFSET;
}

void init_cluster_partition(void)
{
uint32_t i, cur_addr;
cluster_startup_para t_cmp;
cluster_startup_para t_cmp_back;
memset((void *) (&t_cmp_back), 0xff, CLUSTER_PARA_LEN);

for (i = 0;; i++)
{
cur_addr = USER_CLUSTER_PARTITION_OFFSET + i * CLUSTER_PARA_LEN;
if (cur_addr >= USER_CLUSTER_PARTITION_END)
{
clear_cluster_para();
if (uart_init_flag)
{
printk("Cluster partition is full, clear it and redirect address:0x%x\n", cluster_para_addr);
}
break;
}

flash_read(cluster_para_dev, cur_addr, &t_cmp, CLUSTER_PARA_LEN);
if (memcmp(&t_cmp, &t_cmp_back, CLUSTER_PARA_LEN) == 0) // read t_cmp is 0xff
{
cluster_para_addr = cur_addr;
if (uart_init_flag)
{
printk("Init cluster partition:0x%x\n", cluster_para_addr);
}
return;
}
}
}

int store_cluster_para(cluster_startup_para * data)
{
if (data == NULL)
{
if (uart_init_flag)
{
printk("[ERROR] The data that needs to be stored is NULL\n");
}
return -1;
}
if (cluster_para_addr >= (USER_CLUSTER_PARTITION_END - CLUSTER_PARA_LEN))
{
clear_cluster_para();
}

flash_write(cluster_para_dev, cluster_para_addr, data, CLUSTER_PARA_LEN);
cluster_para_addr += CLUSTER_PARA_LEN;
return 0;
}

int read_cluster_para(cluster_startup_para * data)
{
if (data == NULL)
{
if (uart_init_flag)
{
printk("[ERROR] The data to be read is NULL\n");
}
return -1;
}
if (cluster_para_addr >= USER_CLUSTER_PARTITION_END)
{
clear_cluster_para();
if (uart_init_flag)
{
printk("[ERROR] The read address exceeds partition, clear it and redirect address:0x%x\n", cluster_para_addr);
}
return -1;
}
if ((cluster_para_addr - CLUSTER_PARA_LEN) < USER_CLUSTER_PARTITION_OFFSET)
{
if (uart_init_flag)
{
printk("[ERROR] The cluster parition all NULL\n");
}
return -1;
}

cluster_startup_para t_cmp;
cluster_startup_para t_cmp_back;
memset((void *) (&t_cmp_back), 0xff, CLUSTER_PARA_LEN);

flash_read(cluster_para_dev, (cluster_para_addr - CLUSTER_PARA_LEN), &t_cmp, CLUSTER_PARA_LEN);
if (memcmp(&t_cmp, &t_cmp_back, CLUSTER_PARA_LEN) == 0) // read t_cmp is 0xff, error
{
clear_cluster_para();
if (uart_init_flag)
{
printk("[ERROR] The previous data was not successfully written\n");
}
return -1;
}
memcpy(data, &t_cmp, CLUSTER_PARA_LEN);
return 0;
}
#endif // CONFIG_STARTUP_OPTIMIZATE

#if CONFIG_DUAL_MODE_SWTICH
void FactoryResetExtHandler(void)
{
// Erase the user parameters partition to reset mode settings
flash_erase(flash_para_dev, USER_PARTITION_OFFSET, USER_PARTITION_SIZE);
// Need to erase zb nvs part in factory mode
flash_erase(zb_para_dev, ZB_NVS_START_ADR, ZB_NVS_SEC_SIZE);
#if CONFIG_STARTUP_OPTIMIZATE
// Need to erase cluster para parition
flash_erase(cluster_para_dev, USER_CLUSTER_PARTITION_OFFSET, USER_CLUSTER_PARTITION_SIZE);
#endif // CONFIG_STARTUP_OPTIMIZATE
}
#endif

Expand Down Expand Up @@ -940,6 +1068,18 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /*
sBoot_zb = 0;
flash_erase(flash_para_dev, USER_PARTITION_OFFSET, USER_PARTITION_SIZE);
flash_write(flash_para_dev, USER_PARTITION_OFFSET, &val, 1);
#if CONFIG_STARTUP_OPTIMIZATE
cluster_startup_para cluster_para;
cluster_para.onoff = light_para.onoff;
cluster_para.level = light_para.level;
if (store_cluster_para(&cluster_para) != 0)
{
if (uart_init_flag)
{
printk("[Commissioning] Fail store startup cluster para\n");
}
}
#endif // CONFIG_STARTUP_OPTIMIZATE
printk("Commissioning complete, set Matter commissionined flag");
}
break;
Expand Down
Loading

0 comments on commit 09271bd

Please sign in to comment.