添加智能灯固件代码

This commit is contained in:
kerwincui
2021-07-13 17:14:51 +08:00
parent 332f74dd17
commit ecc0b91b8b
2568 changed files with 229441 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
/******************************************************************************
* 作者kerwincui
* 时间2021-06-08
* 邮箱164770707@qq.com
* 源码地址https://gitee.com/kerwincui/wumei-smart
* author: kerwincui
* create: 2021-06-08
* email164770707@qq.com
* source:https://github.com/kerwincui/wumei-smart
******************************************************************************/
#include "statistic_free_rtos.h"
static char task_names[NUM_OF_SPIN_TASKS][configMAX_TASK_NAME_LEN];
static SemaphoreHandle_t sync_spin_task;
static SemaphoreHandle_t sync_stats_task;
/**
* @brief 函数打印给定时间内任务的CPU使用情况
*
*
* @param xTicksToWait 统计测量周期
*
* @return
* - ESP_OK 成功
* - ESP_ERR_NO_MEM 内存不足,无法分配内部数组
* - ESP_ERR_INVALID_SIZE uxTaskGetSystemState的数组大小不足尝试增加ARRAY_SIZE_OFFSET
* - ESP_ERR_INVALID_STATE 延迟时间太短
*/
static esp_err_t print_real_time_stats(TickType_t xTicksToWait)
{
TaskStatus_t *start_array = NULL, *end_array = NULL;
UBaseType_t start_array_size, end_array_size;
uint32_t start_run_time, end_run_time;
esp_err_t ret;
//分配数组存储当前的任务状态
start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
start_array = malloc(sizeof(TaskStatus_t) * start_array_size);
if (start_array == NULL) {
ret = ESP_ERR_NO_MEM;
goto exit;
}
//获取当前任务状态
start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time);
if (start_array_size == 0) {
ret = ESP_ERR_INVALID_SIZE;
goto exit;
}
vTaskDelay(xTicksToWait);
//分配数组以存储延迟后的任务状态
end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET;
end_array = malloc(sizeof(TaskStatus_t) * end_array_size);
if (end_array == NULL) {
ret = ESP_ERR_NO_MEM;
goto exit;
}
//获取延迟后任务状态
end_array_size = uxTaskGetSystemState(end_array, end_array_size, &end_run_time);
if (end_array_size == 0) {
ret = ESP_ERR_INVALID_SIZE;
goto exit;
}
//以运行时统计时钟周期为单位,计算合计已用时间
uint32_t total_elapsed_time = (end_run_time - start_run_time);
if (total_elapsed_time == 0) {
ret = ESP_ERR_INVALID_STATE;
goto exit;
}
printf("| Task | Run Time | Percentage\n");
//将开始数组和结束数组的每一个任务进行匹配
for (int i = 0; i < start_array_size; i++) {
int k = -1;
for (int j = 0; j < end_array_size; j++) {
if (start_array[i].xHandle == end_array[j].xHandle) {
k = j;
//通过覆盖他们的句柄来标记已匹配的任务
start_array[i].xHandle = NULL;
end_array[j].xHandle = NULL;
break;
}
}
//检查是否找到匹配的任务
if (k >= 0) {
uint32_t task_elapsed_time = end_array[k].ulRunTimeCounter - start_array[i].ulRunTimeCounter;
uint32_t percentage_time = (task_elapsed_time * 100UL) / (total_elapsed_time * portNUM_PROCESSORS);
printf("| %s | %d | %d%%\n", start_array[i].pcTaskName, task_elapsed_time, percentage_time);
}
}
//打印不匹配的任务
for (int i = 0; i < start_array_size; i++) {
if (start_array[i].xHandle != NULL) {
printf("| %s | Deleted\n", start_array[i].pcTaskName);
}
}
for (int i = 0; i < end_array_size; i++) {
if (end_array[i].xHandle != NULL) {
printf("| %s | Created\n", end_array[i].pcTaskName);
}
}
ret = ESP_OK;
exit: //公共返回路径
free(start_array);
free(end_array);
return ret;
}
static void spin_task(void *arg)
{
xSemaphoreTake(sync_spin_task, portMAX_DELAY);
while (1) {
//消耗CPU周期
for (int i = 0; i < SPIN_ITER; i++) {
__asm__ __volatile__("NOP");
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
static void stats_task(void *arg)
{
xSemaphoreTake(sync_stats_task, portMAX_DELAY);
//开始所有旋转任务
for (int i = 0; i < NUM_OF_SPIN_TASKS; i++) {
xSemaphoreGive(sync_spin_task);
}
//定期打印实时统计信息
while (1) {
printf("\n\nGetting real time stats over %d ticks\n", STATS_TICKS);
if (print_real_time_stats(STATS_TICKS) == ESP_OK) {
printf("Real time stats obtained\n");
} else {
printf("Error getting real time stats\n");
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void free_rtos_start(void)
{
//允许其他核心完成初始化
vTaskDelay(pdMS_TO_TICKS(100));
//创建信号量以进行同步
sync_spin_task = xSemaphoreCreateCounting(NUM_OF_SPIN_TASKS, 0);
sync_stats_task = xSemaphoreCreateBinary();
//创建旋转任务
for (int i = 0; i < NUM_OF_SPIN_TASKS; i++) {
snprintf(task_names[i], configMAX_TASK_NAME_LEN, "spin%d", i);
xTaskCreatePinnedToCore(spin_task, task_names[i], 1024, NULL, SPIN_TASK_PRIO, NULL, tskNO_AFFINITY);
}
//创建并启动统计任务
xTaskCreatePinnedToCore(stats_task, "stats", 4096, NULL, STATS_TASK_PRIO, NULL, tskNO_AFFINITY);
xSemaphoreGive(sync_stats_task);
}