Commit a5bae1f8 authored by Wenxi Xu's avatar Wenxi Xu
Browse files

添加了led显示cpu负载

parent 5bb8739e
Loading
Loading
Loading
Loading
+24 −21
Original line number Diff line number Diff line
@@ -28,35 +28,28 @@
	};

	aliases {
		// led0 = &led_0_blue;
		// led1 = &led_1_green;
		// led2 = &led_2_red;
		vofa = &usart6;
		led-red = &led_2_red;
		led-green = &led_1_green;
		led-blue = &led_0_blue;
		plot = &usart6;
		watchdog0 = &iwdg;
	};

	// pwmleds {
	// 	compatible = "pwm-leds";

	// 	led_0_blue: led_0_blue {
	// 		pwms = <&pwm5 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
	// 	};

	// 	led_1_green: led_1_green {
	// 		pwms = <&pwm5 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
	// 	};

	// 	led_2_red: led_2_red {
	// 		pwms = <&pwm5 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
	// 	};
	// };

	pwmleds: pwmleds {
		compatible = "pwm-leds";
		status = "okay";
		heater: heater {
			pwms = <&pwm10 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
		};
		led_0_blue: led_0_blue {
			pwms = <&pwm5 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
		};
		led_1_green: led_1_green {
			pwms = <&pwm5 2 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
		};
		led_2_red: led_2_red {
			pwms = <&pwm5 3 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
		};
	};

	imu_temp_pid: imu_temp_pid {
@@ -166,7 +159,7 @@
&usart6 {
	pinctrl-0 = <&usart6_tx_pg14 &usart6_rx_pg9>;
	pinctrl-names = "default";
	current-speed = <2500000>;
	current-speed = <921600>;
	status = "okay";
	data-bits = <8>;
	stop-bits = "1";
@@ -198,6 +191,16 @@ zephyr_udc0: &usbotg_fs {
	status = "okay";
};

&timers5 {
	status = "okay";
	st,prescaler = <10000>;
	pwm5: pwm {
		status = "okay";
		pinctrl-0 = <&tim5_ch1_ph10 &tim5_ch2_ph11 &tim5_ch3_ph12>;
		pinctrl-names = "default";
	};
};

&timers10 {
	status = "okay";
	st,prescaler = <10000>;
+5 −1
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ CONFIG_FPU=y

CONFIG_PWM=y

CONFIG_CAN=y

CONFIG_SENSOR=y
CONFIG_BMI08X=y
CONFIG_BMI08X_ACCEL_TRIGGER_OWN_THREAD=y
@@ -57,6 +59,7 @@ CONFIG_IMU_PWM_TEMP_CTRL=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_ZMS=y
CONFIG_ZMS_LOG_LEVEL_ERR=y

CONFIG_DMA_STM32=y # STM32 UART 驱动

@@ -80,4 +83,5 @@ CONFIG_ISR_STACK_SIZE=3200
CONFIG_MAIN_STACK_SIZE=3200
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=3200

CONFIG_SEGGER_SYSVIEW_RTT_BUFFER_SIZE=8192
 No newline at end of file
CONFIG_PLOTTER=y
CONFIG_PLOTTER_FREQ=300
 No newline at end of file
+156 −79
Original line number Diff line number Diff line
@@ -4,8 +4,10 @@
 * SPDX-License-Identifier: Apache-2.0
 */
#include "zephyr/toolchain.h"
#include <zephyr/drivers/led.h>
#include <zephyr/drivers/pwm.h>
#ifdef CONFIG_BOARD_DM_MC02
#include <zephyr/drivers/led_strip.h>
#endif
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/kernel.h>
@@ -14,6 +16,14 @@
#include <zephyr/debug/thread_analyzer.h>
#include "init.h"

LOG_MODULE_REGISTER(board_init, LOG_LEVEL_INF);

struct led_rgb {
	uint8_t r;
	uint8_t g;
	uint8_t b;
};

#ifdef CONFIG_BOARD_DM_MC02
#define XT30_1_NODE DT_NODELABEL(power1)
#define XT30_2_NODE DT_NODELABEL(power2)
@@ -68,99 +78,166 @@ void pwr_init(void)

#ifdef CONFIG_BOARD_ROBOMASTER_BOARD_C

// #define LED_BLUE  DT_ALIAS(led0)
// #define LED_GREEN DT_ALIAS(led1)
// #define LED_RED   DT_ALIAS(led2)
#define LED_BLUE  DT_ALIAS(led_blue)
#define LED_GREEN DT_ALIAS(led_green)
#define LED_RED   DT_ALIAS(led_red)

static const struct pwm_dt_spec pwm_led_r = PWM_DT_SPEC_GET(LED_RED);   // 红色LED
static const struct pwm_dt_spec pwm_led_g = PWM_DT_SPEC_GET(LED_GREEN); // 绿色LED
static const struct pwm_dt_spec pwm_led_b = PWM_DT_SPEC_GET(LED_BLUE);  // 蓝色LED

// 定义PWM周期 (单位:纳秒)
// 这里我们假设亮度值是 0-255,所以周期也设置为 255 个单位时间
// 你可以根据实际需求调整周期,例如 10000 (10kHz 对应 100us 周期,如果亮度是0-100)
// PWM_DT_SPEC_GET 会从设备树中获取周期,所以这里定义的 period 仅用于计算 pulse_width
// 通常,我们会让 period 与亮度的最大值相对应,以简化计算。
// 例如,如果亮度范围是 0-255,并且PWM硬件的计数器可以达到255或更高,
// 那么将PWM周期设置为能表示256个级别的值是合适的。
// pwm_set_cycles 使用的是纳秒,但 pwm_dt_spec 会处理转换。
// 我们这里假设亮度值 (0-255) 直接映射到脉冲宽度。
#define PWM_PERIOD_FOR_BRIGHTNESS (pwm_led_r.period) // 使用从设备树获取的周期

/**
 * @brief 设置RGB LED的亮度
 *
 * @param r 红色LED的亮度 (0-255, 0为灭, 255为最亮)
 * @param g 绿色LED的亮度 (0-255, 0为灭, 255为最亮)
 * @param b 蓝色LED的亮度 (0-255, 0为灭, 255为最亮)
 *
 * @return 0 如果成功, 负数错误码如果失败.
 */
int set_rgb_led_brightness(struct led_rgb *color)
{
	int ret;
	uint32_t pulse_r, pulse_g, pulse_b;

	// 将亮度值 (0-255) 映射到脉冲宽度 (单位:纳秒)
	// 假设PWM周期 (pwm_led_x.period) 对应最大亮度 (255)
	// pulse_width = (brightness / 255.0) * period_ns
	pulse_r = (uint32_t)(((float)color->r / 255.0f) * PWM_PERIOD_FOR_BRIGHTNESS);
	pulse_g = (uint32_t)(((float)color->g / 255.0f) * PWM_PERIOD_FOR_BRIGHTNESS);
	pulse_b = (uint32_t)(((float)color->b / 255.0f) * PWM_PERIOD_FOR_BRIGHTNESS);

	// 设置红色LED的PWM占空比
	ret = pwm_set_dt(&pwm_led_r, pwm_led_r.period, pulse_r);
	if (ret < 0) {
		LOG_ERR("Failed to set red LED PWM (%d)", ret);
		return ret;
	}

// const struct device *led_blue = DEVICE_DT_GET(LED_BLUE);
// const struct device *led_green = DEVICE_DT_GET(LED_GREEN);
// const struct device *led_red = DEVICE_DT_GET(LED_RED);
	// 设置绿色LED的PWM占空比
	ret = pwm_set_dt(&pwm_led_g, pwm_led_g.period, pulse_g);
	if (ret < 0) {
		LOG_ERR("Failed to set green LED PWM (%d)", ret);
		return ret;
	}

	// 设置蓝色LED的PWM占空比
	ret = pwm_set_dt(&pwm_led_b, pwm_led_b.period, pulse_b);
	if (ret < 0) {
		LOG_ERR("Failed to set blue LED PWM (%d)", ret);
		return ret;
	}

	LOG_DBG("RGB LED brightness set: R=%u, G=%u, B=%u (pulse width R:%u, G:%u, B:%u ns)",
		color->r, color->g, color->b, pulse_r, pulse_g, pulse_b);

	return 0;
}
#define PWR_INIT
#define LED_INIT
#define LED_INIT led_init();

#endif /* CONFIG_BOARD_ROBOMASTER_BOARD_C */

#define RGB(_r, _g, _b) ((struct led_rgb){.r = (_r), .g = (_g), .b = (_b)})

// static inline void led_set_rgb(struct led_rgb *color)
// {
// #ifdef CONFIG_BOARD_DM_MC02
// 	led_strip_update_rgb(strip, color, 1);
// 	// struct spi_config config;
// 	// const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(spi6));

// 	// config.frequency = 9000000;
// 	// config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8);
// 	// config.slave = 0;

// 	// uint8_t buff[] = {0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0xF8, 0xF8, 0xF8, 0xF8,
// 	// 		  0xF8, 0xF8, 0xF8, 0xF8, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0};
// 	// int len = 24 * sizeof(buff[0]);

// 	// struct spi_buf tx_buf = {.buf = buff, .len = len};
// 	// struct spi_buf_set tx_bufs = {.buffers = &tx_buf, .count = 1};

// 	// int ret = spi_write(dev, &config, &tx_bufs);
// #endif /* CONFIG_BOARD_DM_MC02 */

// #ifdef CONFIG_BOARD_ROBOMASTER_BOARD_A
// 	// led_set_brightness(led_green, 1, color->g);
// 	// led_set_brightness(led_red, 1, color->r);
// #endif /* CONFIG_BOARD_ROBOMASTER_BOARD_A */

// #ifdef CONFIG_BOARD_ROBOMASTER_BOARD_C
// 	// led_set_brightness(led_blue, 1, color->b);
// 	// led_set_brightness(led_green, 1, color->g);
// 	// led_set_brightness(led_red, 1, color->r);
// #endif /* CONFIG_BOARD_ROBOMASTER_BOARD_C */
// }
void led_set_rgb(struct led_rgb *color)
{
#ifdef CONFIG_BOARD_DM_MC02
	led_strip_update_rgb(strip, color, 1);

#endif /* CONFIG_BOARD_DM_MC02 */

#ifdef CONFIG_BOARD_ROBOMASTER_BOARD_A
	// led_set_brightness(led_green, 1, color->g);
	// led_set_brightness(led_red, 1, color->r);
#endif /* CONFIG_BOARD_ROBOMASTER_BOARD_A */

#ifdef CONFIG_BOARD_ROBOMASTER_BOARD_C

// void led_serivce_func(void *p1, void *p2, void *p3)
// {
// 	ARG_UNUSED(p1);
// 	ARG_UNUSED(p2);
// 	ARG_UNUSED(p3);

// 	struct k_thread_runtime_stats idle_stats_old, idle_stats_new;
// 	uint64_t idle_cycles_diff;
// 	uint64_t total_cycles_diff;
// 	struct led_rgb color;

// 	while (1) {
// 		// 获取统计数据
// 		k_thread_runtime_stats_all_get(&idle_stats_old);
// 		k_msleep(1000);
// 		k_thread_runtime_stats_all_get(&idle_stats_new);

// 		// 计算CPU使用率 (0-100)
// 		// idle_cycles_diff = idle_stats_new.idle_cycles - idle_stats_old.idle_cycles;
// 		// total_cycles_diff =
// 		// 	idle_stats_new.execution_cycles - idle_stats_old.execution_cycles;
// 		// float cpu_usage = 100.0f * (1.0f - ((float)idle_cycles_diff /
// 		// total_cycles_diff));

// 		// // 映射到RGB值 (红色表示高负载,绿色表示低负载)
// 		// uint8_t red = (uint8_t)((cpu_usage / 100.0f) * 0x0f);
// 		// uint8_t green = (uint8_t)((1.0f - cpu_usage / 100.0f) * 0x0f);

// 		// color = RGB(red, green, 0);
// 		// led_set_rgb(&color);

// 		// printk("CPU: %.1f%%, RGB: %02x%02x00\n", (double)cpu_usage, red, green);
#endif /* CONFIG_BOARD_ROBOMASTER_BOARD_C */
}

void led_serivce_func(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	struct k_thread_runtime_stats idle_stats_old, idle_stats_new;
	uint64_t idle_cycles_diff;
	uint64_t total_cycles_diff;
	struct led_rgb color;

	// uint8_t blue = 0u;
	// bool blue_decrease = false;

	while (1) {
		// 获取统计数据
		k_thread_runtime_stats_all_get(&idle_stats_old);
		k_msleep(50);
		k_thread_runtime_stats_all_get(&idle_stats_new);

		// 计算CPU使用率 (0-100)
		idle_cycles_diff = idle_stats_new.idle_cycles - idle_stats_old.idle_cycles;
		total_cycles_diff =
			idle_stats_new.execution_cycles - idle_stats_old.execution_cycles;
		float cpu_usage = 100.0f * (1.0f - ((float)idle_cycles_diff / total_cycles_diff));

		// // 映射到RGB值 (红色表示高负载,绿色表示低负载)
		uint8_t red = (uint8_t)((cpu_usage / 100.0f) * 0xff);
		uint8_t green = (uint8_t)((1.0f - cpu_usage / 100.0f) * 0xff);

		// if (blue_decrease) {
		// 	blue--;
		// 	if (blue == 0) {
		// 		blue_decrease = false;
		// 	}
		// } else {
		// 	blue++;
		// 	if (blue == 0xff) {
		// 		blue_decrease = true;
		// 	}
		// }

// static K_THREAD_STACK_DEFINE(led_serivce_stack, 1024); // 定义线程栈
// static struct k_thread led_service_thread;
		color = RGB(red, green, 0);
		set_rgb_led_brightness(&color);

		LOG_DBG("CPU: %.1f%%, RGB: %02x%02x%02x", (double)cpu_usage, red, green, 0);
	}
}

static K_THREAD_STACK_DEFINE(led_serivce_stack, 1024); // 定义线程栈
static struct k_thread led_service_thread;
void led_init(void)
{
	struct led_rgb color = RGB(0x4F, 0x4F, 0x4F);
	// led_set_rgb(&color);
	led_set_rgb(&color);
	k_sleep(K_MSEC(300));
	// k_thread_create(&led_service_thread, led_serivce_stack,
	// 		K_THREAD_STACK_SIZEOF(led_serivce_stack), led_serivce_func, NULL, NULL,
	// 		NULL, -1, 0, K_NO_WAIT);

#ifdef CONFIG_BOARD_ROBOMASTER_BOARD_C
	// 检查PWM设备是否就绪
	if (!device_is_ready(pwm_led_r.dev) || !device_is_ready(pwm_led_g.dev) ||
	    !device_is_ready(pwm_led_b.dev)) {
		LOG_ERR("One or more PWM LED devices are not ready");
	}

	set_rgb_led_brightness(&color);
#endif /* CONFIG_BOARD_ROBOMASTER_BOARD_C */

	k_thread_create(&led_service_thread, led_serivce_stack,
			K_THREAD_STACK_SIZEOF(led_serivce_stack), led_serivce_func, NULL, NULL,
			NULL, -1, 0, K_NO_WAIT);
}

void board_init(void)
@@ -168,5 +245,5 @@ void board_init(void)
	k_sleep(K_MSEC(550));
	PWR_INIT
	LED_INIT
	printk("Board init done.\n");
	LOG_INF("Board init done.");
}
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@

struct led_rgb;

static inline void led_set_rgb(struct led_rgb *color);
void led_set_rgb(struct led_rgb *color);
void led_serivce_func(void *p1, void *p2, void *p3);
void board_init(void);