This commit is contained in:
2026-05-11 11:02:40 +00:00
parent 0a19965657
commit 3d00f10b77

View File

@@ -14,15 +14,16 @@
#include "sys.h"
#include "utils.h"
static const uint8_t lcd_contrast = 210;
static const uint16_t refresh_interval_ms = 500;
static const char netif[] = "enp7s0";
static const char cpu_pcidev[] = "0000:00:18.3";
static const char gpu_pcidev[] = "0000:0a:00.0";
static const char netif[] = "enp7s0";
static const char cpu_pcidev[] = "0000:00:18.3";
static const char gpu_pcidev[] = "0000:0a:00.0";
struct control_t {
atomic_bool g_running;
pthread_mutex_t sensors_mtx;
pthread_cond_t sensors_ready;
atomic_bool g_running; // if using c11, you need atomic_store() and atomic_load();
} control;
struct sensors_t {
@@ -43,28 +44,31 @@ static void *sensors_thread(void *arg) {
struct timespec next;
clock_gettime(CLOCK_REALTIME, &next);
// set up paths for the sensors
/* set up paths for the sensors */
strcpy(sensors->home.mountpoint, "/home/drath");
strcpy(sensors->net.device, netif);
cpu_detect(&sensors->cpu, cpu_pcidev);
gpu_detect(&sensors->gpu, gpu_pcidev);
sys_detect(&sensors->sys, "nct6775.656");
/* main sensor loop */
applog(LOG_START, "reached sensors main loop");
while (control.g_running) { // NOLINT
pthread_mutex_lock(&control.sensors_mtx);
sys_get_load_avg(sensors->loadavg);
sys_get_time(&sensors->td);
sys_get_ram(&sensors->ram);
sys_get_disk(&sensors->home);
sys_get_network(&sensors->net);
sys_update_sensors(&sensors->sys);
{
sys_get_time(&sensors->td);
sys_get_load_avg(sensors->loadavg);
sys_get_ram(&sensors->ram);
sys_get_disk(&sensors->home);
sys_get_network(&sensors->net);
sys_update_sensors(&sensors->sys);
cpu_update(&sensors->cpu);
gpu_update(&sensors->gpu);
}
cpu_update(&sensors->cpu);
gpu_update(&sensors->gpu);
pthread_mutex_unlock(&control.sensors_mtx);
pthread_cond_signal(&control.sensors_ready);
pthread_mutex_unlock(&control.sensors_mtx);
timespec_add_ms(&next, refresh_interval_ms);
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next, NULL);
@@ -78,68 +82,69 @@ static void *display_thread(void *arg) {
applog(LOG_START, "display thread started");
struct sensors_t *sensors = arg;
/* lcd setup */
struct lcd_t lcd = {
.port = "/dev/serial/by-id/usb-Raspberry_Pi_Pico_E6616407E37AA12F-if00",
.baud = 0010002, // from termios-baud.h, B115200
};
lcd_init(&lcd);
// basic lcd setup
lcd_set_backlight(&lcd, true);
lcd_set_contrast(&lcd, 206);
lcd_set_contrast(&lcd, lcd_contrast);
lcd_write_buf(&lcd, 1, 9, "Waiting for sensors..."); // need to center this still
lcd_flush_buf(&lcd);
lcd_clear_buf(&lcd);
/* setup custom chars */
lcd_set_custom_char(&lcd, 0, &(lcd_glyph_t){16, 6, 9, 8, 8, 9, 6, 0}); // celcius
lcd_set_custom_char(&lcd, 1, &(lcd_glyph_t){0, 0, 4, 10, 10, 17, 31, 0}); // delta
lcd_set_custom_char(&lcd, 2, &(lcd_glyph_t){0, 0, 8, 21, 21, 2, 0, 0}); // home (tilde)
lcd_set_custom_char(&lcd, 3, &(lcd_glyph_t){4, 14, 21, 4, 4, 4, 0}); // up arrow
lcd_set_custom_char(&lcd, 4, &(lcd_glyph_t){4, 4, 4, 21, 14, 4, 0}); // down arrow
lcd_write_buf(&lcd, 1, 9, "Waiting for sensors..."); // need to center this still
lcd_flush_buf(&lcd);
lcd_clear_buf(&lcd);
/* main display loop */
applog(LOG_START, "reached display main loop");
while (control.g_running) { // NOLINT its updated globally bud
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
timespec_add_ms(&ts, (uint16_t)(refresh_interval_ms * 1.25));
pthread_mutex_lock(&control.sensors_mtx); // lock sensor struct
pthread_cond_timedwait(&control.sensors_ready, &control.sensors_mtx, &ts); // wait until data ready
// prepare some tricky sensors
const uint16_t avg_fan_speed = (sensors->sys.fan_speed[0] + sensors->sys.fan_speed[1]) / 2;
{
// prepare some tricky sensors
const uint16_t avg_fan_speed = (sensors->sys.fan_speed[0] + sensors->sys.fan_speed[1]) / 2;
char gpudelta[5];
const uint8_t delta = sensors->gpu.temp_hotspot - sensors->gpu.temp_edge;
snprintf(gpudelta, sizeof(gpudelta), "%c%d", 1, delta);
const uint8_t gpu_pos = delta > 10 ? 3 : 2;
char gpudelta[5];
const uint8_t delta = sensors->gpu.temp_hotspot - sensors->gpu.temp_edge;
snprintf(gpudelta, sizeof(gpudelta), "%c%d", 1, delta);
const uint8_t gpu_pos = delta > 10 ? 3 : 2;
char gpuclock[16];
snprintf(gpuclock, sizeof(gpuclock), "%d/%dMHz", sensors->gpu.clock_core, sensors->gpu.clock_mem);
char gpuclock[16];
snprintf(gpuclock, sizeof(gpuclock), "%d/%dMHz", sensors->gpu.clock_core, sensors->gpu.clock_mem);
lcd_writef(&lcd, 0, 0, "%s %s%c", sensors->td.date, sensors->td.time, lcd_bar(&lcd, 5, sensors->gpu.usage_core / 100.0));
lcd_writef(&lcd, 26, 0, "%s %s %s", P_NUM(sensors->loadavg[0]), P_NUM(sensors->loadavg[1]), P_NUM(sensors->loadavg[2]));
lcd_writef(&lcd, 0, 0, "%s %s%c", sensors->td.date, sensors->td.time, lcd_bar(&lcd, 5, sensors->gpu.usage_core / 100.0));
lcd_writef(&lcd, 26, 0, "%s %s %s", P_NUM(sensors->loadavg[0]), P_NUM(sensors->loadavg[1]), P_NUM(sensors->loadavg[2]));
lcd_writef(&lcd, 0, 1, "%d/%d%c", sensors->cpu.tctl, sensors->cpu.tccd1, 0);
lcd_writef(&lcd, 7, 1, "%s", P_BYTES(sensors->ram.used, 0));
lcd_writef(&lcd, 18, 1, "%3d%c", sensors->sys.t_sensor, 0);
lcd_writef(&lcd, 28, 1, "%4s%c", gpudelta, 0);
lcd_writef(&lcd, 25 - gpu_pos, 1, "%6s", P_BYTES(sensors->gpu.vram_used, 1));
lcd_writef(&lcd, 34, 1, "%d/%d%c", sensors->gpu.temp_edge, sensors->gpu.temp_hotspot, 0);
lcd_writef(&lcd, 0, 1, "%d/%d%c", sensors->cpu.tctl, sensors->cpu.tccd1, 0);
lcd_writef(&lcd, 7, 1, "%s", P_BYTES(sensors->ram.used, 0));
lcd_writef(&lcd, 18, 1, "%3d%c", sensors->sys.t_sensor, 0);
lcd_writef(&lcd, 28, 1, "%4s%c", gpudelta, 0);
lcd_writef(&lcd, 25 - gpu_pos, 1, "%6s", P_BYTES(sensors->gpu.vram_used, 1));
lcd_writef(&lcd, 34, 1, "%d/%d%c", sensors->gpu.temp_edge, sensors->gpu.temp_hotspot, 0);
lcd_writef(&lcd, 0, 2, "%.0fW", sensors->cpu.ptotal);
lcd_writef(&lcd, 5, 2, "%dR", avg_fan_speed);
lcd_writef(&lcd, 12, 2, "%c%s %c%s", 3, P_BYTES(sensors->net.upload, 1), 4, P_BYTES(sensors->net.download, 1));
lcd_writef(&lcd, 26, 2, "%4dR", sensors->gpu.fan_speed);
lcd_writef(&lcd, 32, 2, "%3d/%3dW", sensors->gpu.power_avg, sensors->gpu.power_cap);
lcd_writef(&lcd, 0, 2, "%.0fW", sensors->cpu.ptotal);
lcd_writef(&lcd, 5, 2, "%dR", avg_fan_speed);
lcd_writef(&lcd, 12, 2, "%c%s %c%s", 3, P_BYTES(sensors->net.upload, 1), 4, P_BYTES(sensors->net.download, 1));
lcd_writef(&lcd, 26, 2, "%4dR", sensors->gpu.fan_speed);
lcd_writef(&lcd, 32, 2, "%3d/%3dW", sensors->gpu.power_avg, sensors->gpu.power_cap);
lcd_writef(&lcd, 0, 3, "%dMHz", sensors->cpu.avg_freq);
lcd_writef(&lcd, 14, 3, "%c%s", 2, P_BYTES(sensors->home.usage.free, 1));
lcd_writef(&lcd, 21, 3, "%12s", gpuclock);
lcd_writef(&lcd, 34, 3, "%.3fV", sensors->gpu.vcore);
lcd_writef(&lcd, 0, 3, "%dMHz", sensors->cpu.avg_freq);
lcd_writef(&lcd, 14, 3, "%c%s", 2, P_BYTES(sensors->home.usage.free, 1));
lcd_writef(&lcd, 21, 3, "%12s", gpuclock);
lcd_writef(&lcd, 34, 3, "%.3fV", sensors->gpu.vcore);
}
pthread_mutex_unlock(&control.sensors_mtx); // unlock sensor struct
lcd_flush_buf(&lcd);
lcd_clear_buf(&lcd);
}
@@ -155,6 +160,14 @@ int main(void) {
control.g_running = true;
applog(LOG_START, "linuxSmartie started");
applog(LOG_DBG, "Compiled on %s %s with %s", __DATE__, __TIME__, C_STD);
struct sensors_t *sensors = malloc(sizeof(*sensors)); // no actual point in mallocing and it is ever so sligtly slower to access heap vs stack, but its cool
if (sensors == NULL) {
applog(LOG_ERR, "can't allocate mem for the sensor struct. You don't got %lu bytes bro?", sizeof(struct sensors_t));
free(sensors);
return -1;
}
applog(LOG_INF, "sensor struct allocated, size is %lu bytes", sizeof(struct sensors_t));
/* signal setup */
sigset_t sigset;
@@ -170,33 +183,24 @@ int main(void) {
pthread_mutex_init(&control.sensors_mtx, NULL);
pthread_cond_init(&control.sensors_ready, NULL);
/* allocate mem for the main struct */
struct sensors_t *sensors = malloc(sizeof(struct sensors_t));
if (sensors == NULL) {
applog(LOG_ERR, "cant allocate mem for the sensor struct");
free(sensors);
return -1;
}
applog(LOG_INF, "sensor struct allocated, size is %lu bytes", sizeof(struct sensors_t));
/* thread setup */
pthread_t display_pthread;
pthread_t sensors_pthread;
pthread_t display_pthread;
/* actually start the threads */
pthread_create(&display_pthread, NULL, display_thread, sensors);
pthread_create(&sensors_pthread, NULL, sensors_thread, sensors);
pthread_create(&display_pthread, NULL, display_thread, sensors);
const ssize_t ret = read(sfd, &info, sizeof(info)); // halts on this until SIGTERM
/* halts here until signal to stop */
const ssize_t ret = read(sfd, &info, sizeof(info));
(void)ret;
/* cleanup on exit signal */
/* cleanup on exit */
applog(LOG_WRN, "got stop signal, shutting down...");
close(sfd);
control.g_running = false;
pthread_join(display_pthread, NULL);
pthread_join(sensors_pthread, NULL);
pthread_join(display_pthread, NULL);
free(sensors);
return 0;
}