formatting shit
This commit is contained in:
@@ -24,7 +24,7 @@ struct cpu_sensors_t {
|
||||
char hwmon[128];
|
||||
};
|
||||
|
||||
void cpu_detect(struct cpu_sensors_t* t, const char* pci_dev);
|
||||
void cpu_detect(struct cpu_sensors_t *t, const char *pci_dev);
|
||||
void cpu_update(struct cpu_sensors_t *c);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#ifndef GPU_H
|
||||
#define GPU_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct gpu_sensors_t {
|
||||
uint64_t vram_used;
|
||||
@@ -36,7 +36,7 @@ struct gpu_sensors_t {
|
||||
char hwmon[128];
|
||||
};
|
||||
|
||||
void gpu_detect(struct gpu_sensors_t* t, const char* pci);
|
||||
void gpu_update(struct gpu_sensors_t* g);
|
||||
void gpu_detect(struct gpu_sensors_t *t, const char *pci);
|
||||
void gpu_update(struct gpu_sensors_t *g);
|
||||
|
||||
#endif
|
||||
@@ -16,19 +16,19 @@ struct lcd_t {
|
||||
|
||||
typedef uint8_t lcd_glyph_t[8];
|
||||
|
||||
void lcd_close(struct lcd_t* lcd);
|
||||
void lcd_clear(struct lcd_t* lcd);
|
||||
void lcd_set_contrast(struct lcd_t* lcd, uint8_t contrast);
|
||||
void lcd_set_backlight(struct lcd_t* lcd, bool enabled);
|
||||
void lcd_set_cursor(struct lcd_t* lcd, uint8_t row, uint8_t col);
|
||||
void lcd_set_custom_char(struct lcd_t* lcd, uint8_t index, const lcd_glyph_t* glyph);
|
||||
void lcd_write_str(struct lcd_t* lcd, const char* str, uint8_t len);
|
||||
void lcd_write_str_pos(struct lcd_t* lcd, const char* str, uint8_t len, uint8_t posX, uint8_t posY);
|
||||
void lcd_write_buf(struct lcd_t* lcd, uint8_t row, uint8_t col, const char* str);
|
||||
void lcd_writef(struct lcd_t *lcd, uint8_t x, uint8_t y, const char *fmt, ...) __attribute__((format(printf, 4, 5)));
|
||||
void lcd_clear_buf(struct lcd_t* lcd);
|
||||
void lcd_flush_buf(struct lcd_t* lcd);
|
||||
char lcd_bar(struct lcd_t* lcd, uint8_t char_id, double value);
|
||||
int lcd_init(struct lcd_t* lcd);
|
||||
void lcd_close(struct lcd_t *lcd);
|
||||
void lcd_clear(struct lcd_t *lcd);
|
||||
void lcd_set_contrast(struct lcd_t *lcd, uint8_t contrast);
|
||||
void lcd_set_backlight(struct lcd_t *lcd, bool enabled);
|
||||
void lcd_set_cursor(struct lcd_t *lcd, uint8_t row, uint8_t col);
|
||||
void lcd_set_custom_char(struct lcd_t *lcd, uint8_t index, const lcd_glyph_t *glyph);
|
||||
void lcd_write_str(struct lcd_t *lcd, const char *str, uint8_t len);
|
||||
void lcd_write_str_pos(struct lcd_t *lcd, const char *str, uint8_t len, uint8_t posX, uint8_t posY);
|
||||
void lcd_write_buf(struct lcd_t *lcd, uint8_t row, uint8_t col, const char *str);
|
||||
void lcd_writef(struct lcd_t *lcd, uint8_t x, uint8_t y, const char *fmt, ...) __attribute__((format(printf, 4, 5)));
|
||||
void lcd_clear_buf(struct lcd_t *lcd);
|
||||
void lcd_flush_buf(struct lcd_t *lcd);
|
||||
char lcd_bar(struct lcd_t *lcd, uint8_t char_id, double value);
|
||||
int lcd_init(struct lcd_t *lcd);
|
||||
|
||||
#endif
|
||||
@@ -15,25 +15,25 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef enum {
|
||||
LOG_INF,
|
||||
LOG_WRN,
|
||||
LOG_ERR,
|
||||
LOG_DBG,
|
||||
LOG_START,
|
||||
LOG_INF,
|
||||
LOG_WRN,
|
||||
LOG_ERR,
|
||||
LOG_DBG,
|
||||
LOG_START,
|
||||
} log_level_t;
|
||||
|
||||
/* __PRETTY_FUNCTION__ is a GCC/Clang extension that gives the full
|
||||
s ignature: "voi*d foo(int x)" — same thing source_location gave you.
|
||||
Falls back to plain __func__ (C99) if somehow unavailable. */
|
||||
#define applog(level, fmt, ...) \
|
||||
log_write(level, __PRETTY_FUNCTION__, fmt, ##__VA_ARGS__)
|
||||
log_write(level, __PRETTY_FUNCTION__, fmt, ##__VA_ARGS__)
|
||||
|
||||
/* format attribute gives compile-time printf format checking —
|
||||
better than wha*t std::format gave you at runtime */
|
||||
void log_write(log_level_t level, const char *func, const char *fmt, ...)
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
|
||||
#else /* APPLOG_ENABLED not defined */
|
||||
#else /* APPLOG_ENABLED not defined */
|
||||
|
||||
#define applog(...) ((void)0)
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ struct network_t {
|
||||
};
|
||||
|
||||
struct syssensors_t {
|
||||
uint16_t fan_speed[2]; // left and right cpu fans
|
||||
int16_t t_sensor; // ntc temp sensor
|
||||
uint16_t fan_speed[2]; // left and right cpu fans
|
||||
int16_t t_sensor; // ntc temp sensor
|
||||
char hwmon[128];
|
||||
};
|
||||
|
||||
@@ -37,11 +37,11 @@ void sys_get_load_avg(double *load_avg);
|
||||
|
||||
void sys_get_ram(struct memory_t *ram);
|
||||
|
||||
void sys_get_disk(struct disk_t* disk);
|
||||
void sys_get_disk(struct disk_t *disk);
|
||||
|
||||
void sys_get_network(struct network_t* network);
|
||||
void sys_get_network(struct network_t *network);
|
||||
|
||||
void sys_detect(struct syssensors_t* s, const char* platform);
|
||||
void sys_update_sensors(struct syssensors_t* s);
|
||||
void sys_detect(struct syssensors_t *s, const char *platform);
|
||||
void sys_update_sensors(struct syssensors_t *s);
|
||||
|
||||
#endif //LINUXSMARTIE_SYS_H
|
||||
#endif // LINUXSMARTIE_SYS_H
|
||||
@@ -1,28 +1,48 @@
|
||||
#ifndef UTILS_H
|
||||
#define UTILS_H
|
||||
|
||||
#include <time.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
uint64_t timespec_diff_us(const struct timespec *a, const struct timespec *b);
|
||||
void timespec_add_ms(struct timespec *ts, uint16_t ms);
|
||||
char *pretty_bytes(uint64_t bytes, int8_t start_suffix, char *buf, size_t bufsz);
|
||||
char *pretty_num(double num, char *buf, size_t bufsz);
|
||||
|
||||
void fast_read_num_u64(const char* dir, const char* file, char* buf, uint64_t* result, uint32_t divider);
|
||||
void fast_read_num_u16(const char* dir, const char* file, char* buf, uint16_t* result, uint32_t divider);
|
||||
void fast_read_num_u8(const char* dir, const char* file, char* buf, uint8_t* result, uint32_t divider);
|
||||
void fast_read_num_i16(const char* dir, const char* file, char* buf, int16_t* result, uint32_t divider);
|
||||
void fast_read_num_f(const char* dir, const char* file, char* buf, float* result, uint32_t divider);
|
||||
|
||||
bool file_exists(const char *path);
|
||||
size_t read_file(const char* path, char* buffer, size_t n);
|
||||
|
||||
int get_hwmon_dir(char *path);
|
||||
#if __STDC_VERSION__ >= 202311L
|
||||
#define C_STD "C23"
|
||||
#elif __STDC_VERSION__ >= 201710L
|
||||
#define C_STD "C17"
|
||||
#elif __STDC_VERSION__ >= 201112L
|
||||
#define C_STD "C11"
|
||||
#elif __STDC_VERSION__ >= 199901L
|
||||
#define C_STD "C99"
|
||||
#else
|
||||
#define C_STD "C89"
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define P_BYTES(bytes, start) pretty_bytes((bytes), (start), (char[16]){0}, 16)
|
||||
#define P_NUM(num) pretty_num((num), (char[8]){0}, 8)
|
||||
|
||||
void timespec_add_ms(struct timespec *ts, uint16_t ms);
|
||||
|
||||
uint64_t timespec_diff_us(const struct timespec *a, const struct timespec *b);
|
||||
|
||||
char *pretty_num(double num, char *buf, size_t bufsz);
|
||||
|
||||
char *pretty_bytes(uint64_t bytes, int8_t start_suffix, char *buf, size_t bufsz);
|
||||
|
||||
bool file_exists(const char *path);
|
||||
|
||||
int get_hwmon_dir(char *path);
|
||||
|
||||
size_t read_file(const char *path, char *buffer, size_t n);
|
||||
|
||||
void fast_read_num_u64(const char *dir, const char *file, char *buf, uint64_t *result, uint32_t divider);
|
||||
|
||||
void fast_read_num_u16(const char *dir, const char *file, char *buf, uint16_t *result, uint32_t divider);
|
||||
|
||||
void fast_read_num_u8(const char *dir, const char *file, char *buf, uint8_t *result, uint32_t divider);
|
||||
|
||||
void fast_read_num_i16(const char *dir, const char *file, char *buf, int16_t *result, uint32_t divider);
|
||||
|
||||
void fast_read_num_f(const char *dir, const char *file, char *buf, float *result, uint32_t divider);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#include "cpu.h"
|
||||
#include "utils.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void cpu_detect(struct cpu_sensors_t *t, const char *pci_dev) {
|
||||
t->module = unknown;
|
||||
@@ -20,8 +20,8 @@ void cpu_detect(struct cpu_sensors_t *t, const char *pci_dev) {
|
||||
}
|
||||
|
||||
char buf[128];
|
||||
char *nt = stpncpy(buf, t->hwmon, sizeof(buf)); // nt is a pointer to the null terminator of the copied string
|
||||
stpcpy(nt, "/in1_input"); // write at the null terminator address
|
||||
char *nt = stpncpy(buf, t->hwmon, sizeof(buf)); // nt is a pointer to the null terminator of the copied string
|
||||
stpcpy(nt, "/in1_input"); // write at the null terminator address
|
||||
t->module = file_exists(buf) ? zenpower : k10temp; // idk if this is reliable, we're trying to avoid just reading the name
|
||||
applog(LOG_INF, "Detected %d cores, module enum #%d in path %s", t->num_cores, t->module, t->hwmon);
|
||||
}
|
||||
|
||||
74
src/gpu.c
74
src/gpu.c
@@ -1,14 +1,14 @@
|
||||
#include "gpu.h"
|
||||
|
||||
#include "gpu_metrics.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "gpu_metrics.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
||||
const char rel_metrics_path[] = "/../../gpu_metrics"; // gpu_metrics path relative to hwmon path
|
||||
const uint16_t max_metrics_length = 512; // length of the metrics buffer
|
||||
const uint16_t max_metrics_length = 512; // length of the metrics buffer
|
||||
|
||||
void gpu_detect(struct gpu_sensors_t *t, const char *pci) {
|
||||
snprintf(t->hwmon, sizeof(t->hwmon), "/sys/bus/pci/devices/%s/hwmon", pci);
|
||||
@@ -26,7 +26,7 @@ void gpu_detect(struct gpu_sensors_t *t, const char *pci) {
|
||||
char raw_metrics[max_metrics_length];
|
||||
if (!read_file(buf, raw_metrics, sizeof(raw_metrics)))
|
||||
return;
|
||||
const struct metrics_table_header* header = (struct metrics_table_header*)raw_metrics;
|
||||
const struct metrics_table_header *header = (struct metrics_table_header *)raw_metrics;
|
||||
applog(LOG_INF, "Found gpu_metrics_v%d_%d", header->format_revision, header->content_revision);
|
||||
t->has_gpu_metrics = true;
|
||||
}
|
||||
@@ -67,48 +67,48 @@ void update_from_metrics(struct gpu_sensors_t *g) {
|
||||
|
||||
switch (header->format_revision * 10 + header->content_revision) {
|
||||
|
||||
/* rx5700xt, rx7800xtx rx9070xt */
|
||||
case 13: {
|
||||
const struct gpu_metrics_v1_3* metrics = (struct gpu_metrics_v1_3*)raw_metrics;
|
||||
g->usage_core = metrics->average_gfx_activity;
|
||||
g->usage_umc = metrics->average_umc_activity;
|
||||
g->usage_media = metrics->average_mm_activity;
|
||||
/* rx5700xt, rx7800xtx rx9070xt */
|
||||
case 13: {
|
||||
const struct gpu_metrics_v1_3 *metrics = (struct gpu_metrics_v1_3 *)raw_metrics;
|
||||
g->usage_core = metrics->average_gfx_activity;
|
||||
g->usage_umc = metrics->average_umc_activity;
|
||||
g->usage_media = metrics->average_mm_activity;
|
||||
|
||||
g->temp_edge = metrics->temperature_edge;
|
||||
g->temp_hotspot = metrics->temperature_hotspot;
|
||||
g->temp_mem = metrics->temperature_mem;
|
||||
g->temp_edge = metrics->temperature_edge;
|
||||
g->temp_hotspot = metrics->temperature_hotspot;
|
||||
g->temp_mem = metrics->temperature_mem;
|
||||
|
||||
g->temp_vrm_gfx = metrics->temperature_vrgfx;
|
||||
g->temp_vrm_soc = metrics->temperature_vrsoc;
|
||||
g->temp_vrm_mem = metrics->temperature_vrmem;
|
||||
g->power_avg = metrics->average_socket_power;
|
||||
g->fan_speed = metrics->current_fan_speed;
|
||||
g->temp_vrm_gfx = metrics->temperature_vrgfx;
|
||||
g->temp_vrm_soc = metrics->temperature_vrsoc;
|
||||
g->temp_vrm_mem = metrics->temperature_vrmem;
|
||||
g->power_avg = metrics->average_socket_power;
|
||||
g->fan_speed = metrics->current_fan_speed;
|
||||
|
||||
g->clock_core = metrics->average_gfxclk_frequency;
|
||||
g->clock_mem = metrics->average_uclk_frequency; // mem controller clock, needs to be 2x on 5700xt for some reason
|
||||
g->clock_core = metrics->average_gfxclk_frequency;
|
||||
g->clock_mem = metrics->average_uclk_frequency; // mem controller clock, needs to be 2x on 5700xt for some reason
|
||||
|
||||
// hacks for rx7800xt
|
||||
// g->clock_core = metrics->average_vclk1_frequency; // why not gfxclock?
|
||||
// g->clock_mem = metrics->average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping
|
||||
break;
|
||||
}
|
||||
// hacks for rx7800xt
|
||||
// g->clock_core = metrics->average_vclk1_frequency; // why not gfxclock?
|
||||
// g->clock_mem = metrics->average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping
|
||||
break;
|
||||
}
|
||||
|
||||
/* ryzen 5 5600g */
|
||||
case 22: {
|
||||
const struct gpu_metrics_v2_2* metrics = (struct gpu_metrics_v2_2*)raw_metrics;
|
||||
g->temp_edge = metrics->temperature_gfx / 100;
|
||||
break;
|
||||
}
|
||||
/* ryzen 5 5600g */
|
||||
case 22: {
|
||||
const struct gpu_metrics_v2_2 *metrics = (struct gpu_metrics_v2_2 *)raw_metrics;
|
||||
g->temp_edge = metrics->temperature_gfx / 100;
|
||||
break;
|
||||
}
|
||||
|
||||
/* werid hardware i probably dont like, maybe fallback to reading from fs? */
|
||||
default: {
|
||||
applog(LOG_WRN, "Unsupported gpu_metrics_v%d_%d", header->format_revision, header->content_revision);
|
||||
break;
|
||||
}
|
||||
/* werid hardware i probably dont like, maybe fallback to reading from fs? */
|
||||
default: {
|
||||
applog(LOG_WRN, "Unsupported gpu_metrics_v%d_%d", header->format_revision, header->content_revision);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* reads values from system and updates the target gpu_sensors_t struct */
|
||||
/* reads values from system and updates the target gpu_sensors_t struct */
|
||||
void gpu_update(struct gpu_sensors_t *g) {
|
||||
const bool hwmon_valid = g->hwmon[0] != '\0';
|
||||
|
||||
|
||||
62
src/lcd.c
62
src/lcd.c
@@ -1,26 +1,26 @@
|
||||
#include "lcd.h"
|
||||
#include "log.h"
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "log.h"
|
||||
#include "lcd.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
int lcd_open(struct lcd_t* lcd, const bool reopen) {
|
||||
int lcd_open(struct lcd_t *lcd, const bool reopen) {
|
||||
applog(LOG_INF, "Opening serial port at %s", lcd->port);
|
||||
if (lcd->fd <= 0 || reopen)
|
||||
lcd->fd = open(lcd->port, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||
if (lcd->fd <= 0) {
|
||||
applog(LOG_ERR, "Error opening serial port %s", lcd->port); // err
|
||||
applog(LOG_ERR, "Error opening serial port %s", lcd->port); // err
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lcd_close(struct lcd_t* lcd) {
|
||||
void lcd_close(struct lcd_t *lcd) {
|
||||
if (lcd->fd >= 0) {
|
||||
close(lcd->fd);
|
||||
applog(LOG_INF, "LCD port closed");
|
||||
@@ -28,61 +28,62 @@ void lcd_close(struct lcd_t* lcd) {
|
||||
lcd->fd = -1;
|
||||
}
|
||||
|
||||
void lcd_write(struct lcd_t* lcd, const uint8_t* cmdbuf, const uint8_t len) {
|
||||
void lcd_write(struct lcd_t *lcd, const uint8_t *cmdbuf, const uint8_t len) {
|
||||
if (!write(lcd->fd, cmdbuf, len)) {
|
||||
applog(LOG_ERR, "failed to execute write(), lost access to port?");
|
||||
lcd_open(lcd, true);
|
||||
}
|
||||
}
|
||||
|
||||
void lcd_clear(struct lcd_t* lcd) {
|
||||
void lcd_clear(struct lcd_t *lcd) {
|
||||
const uint8_t cmdbuf[] = {254, 88};
|
||||
lcd_write(lcd, cmdbuf, sizeof(cmdbuf));
|
||||
}
|
||||
|
||||
void lcd_set_contrast(struct lcd_t* lcd, const uint8_t contrast) {
|
||||
void lcd_set_contrast(struct lcd_t *lcd, const uint8_t contrast) {
|
||||
applog(LOG_INF, "Set contrast to %d", contrast);
|
||||
const uint8_t cmdbuf[] = {254, 80, contrast};
|
||||
lcd_write(lcd, cmdbuf, sizeof(cmdbuf));
|
||||
}
|
||||
|
||||
void lcd_set_backlight(struct lcd_t* lcd, const bool enabled) {
|
||||
void lcd_set_backlight(struct lcd_t *lcd, const bool enabled) {
|
||||
applog(LOG_INF, "Set backlight to %s", enabled ? "true" : "false");
|
||||
const uint8_t cmdbuf[] = {254, (enabled ? 66 : 70), 255};
|
||||
lcd_write(lcd, cmdbuf, enabled ? 3 : 2);
|
||||
}
|
||||
|
||||
void lcd_set_cursor(struct lcd_t* lcd, const uint8_t row, const uint8_t col) {
|
||||
void lcd_set_cursor(struct lcd_t *lcd, const uint8_t row, const uint8_t col) {
|
||||
const uint8_t cmdbuf[] = {254, 71, (col + 1), (row + 1)};
|
||||
lcd_write(lcd, cmdbuf, sizeof(cmdbuf));
|
||||
}
|
||||
|
||||
/* reconsider so im not writing every time. prepend custom chars to the write buffer? */
|
||||
void lcd_set_custom_char(struct lcd_t* lcd, const uint8_t index, const lcd_glyph_t* glyph) {
|
||||
void lcd_set_custom_char(struct lcd_t *lcd, const uint8_t index, const lcd_glyph_t *glyph) {
|
||||
uint8_t cmdbuf[] = {254, 78, index, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
memcpy(&cmdbuf[3], glyph, sizeof(lcd_glyph_t));
|
||||
lcd_write(lcd, cmdbuf, sizeof(cmdbuf));
|
||||
}
|
||||
|
||||
/* immediately writes string to the lcd at current cursor pos */
|
||||
void lcd_write_str(struct lcd_t* lcd, const char* str, const uint8_t len) {
|
||||
lcd_write(lcd, (const uint8_t*)str, len);
|
||||
void lcd_write_str(struct lcd_t *lcd, const char *str, const uint8_t len) {
|
||||
lcd_write(lcd, (const uint8_t *)str, len);
|
||||
}
|
||||
|
||||
void lcd_write_str_pos(struct lcd_t* lcd, const char* str, const uint8_t len, const uint8_t posX, const uint8_t posY) {
|
||||
void lcd_write_str_pos(struct lcd_t *lcd, const char *str, const uint8_t len, const uint8_t posX, const uint8_t posY) {
|
||||
lcd_set_cursor(lcd, posX, posY);
|
||||
lcd_write(lcd, (const uint8_t*)str, len);
|
||||
lcd_write(lcd, (const uint8_t *)str, len);
|
||||
}
|
||||
|
||||
/* writes string to write buffer at calculated pos, we trust it to be null terminated */
|
||||
void lcd_write_buf(struct lcd_t* lcd, const uint8_t row, const uint8_t col, const char* str) {
|
||||
void lcd_write_buf(struct lcd_t *lcd, const uint8_t row, const uint8_t col, const char *str) {
|
||||
size_t len = 0;
|
||||
while (str[len] != '\0')
|
||||
len++;
|
||||
|
||||
len = MIN(len, sizeof(lcd->writebuf) - col);
|
||||
uint8_t pos = 4 + col + (LCD_COLS * (row % 2)); // skip 4 bytes to leave room for set cursor command
|
||||
if (row >= 2) pos += 2 * LCD_COLS + 4; // if we're writing to disp2, skip another 4 bytes for set cursor command and 2*40 bytes of disp 1
|
||||
uint8_t pos = 4 + col + (LCD_COLS * (row % 2)); // skip 4 bytes to leave room for set cursor command
|
||||
if (row >= 2)
|
||||
pos += 2 * LCD_COLS + 4; // if we're writing to disp2, skip another 4 bytes for set cursor command and 2*40 bytes of disp 1
|
||||
memcpy(lcd->writebuf + pos, str, len);
|
||||
}
|
||||
|
||||
@@ -95,27 +96,28 @@ inline void lcd_writef(struct lcd_t *lcd, const uint8_t x, const uint8_t y, cons
|
||||
uint8_t len = vsnprintf(tmp, sizeof(tmp), fmt, ap); // print fmt and ap to a temporary buffer
|
||||
va_end(ap);
|
||||
len = MIN(len, LCD_COLS - x);
|
||||
uint8_t pos = 4 + x + (LCD_COLS * (y % 2)); // skip 4 bytes to leave room for set cursor command
|
||||
if (y >= 2) pos += 2 * LCD_COLS + 4; // if we're writing to disp2, skip another 4 bytes for set cursor command and 2*40 bytes of disp 1
|
||||
memcpy(lcd->writebuf + pos, tmp, len); // copy to lcd writebuffer address + whatever pos is
|
||||
uint8_t pos = 4 + x + (LCD_COLS * (y % 2)); // skip 4 bytes to leave room for set cursor command
|
||||
if (y >= 2)
|
||||
pos += 2 * LCD_COLS + 4; // if we're writing to disp2, skip another 4 bytes for set cursor command and 2*40 bytes of disp 1
|
||||
memcpy(lcd->writebuf + pos, tmp, len); // copy to lcd writebuffer address + whatever pos is
|
||||
}
|
||||
|
||||
inline void lcd_clear_buf(struct lcd_t* lcd) {
|
||||
inline void lcd_clear_buf(struct lcd_t *lcd) {
|
||||
memset(lcd->writebuf, ' ', sizeof(lcd->writebuf));
|
||||
}
|
||||
|
||||
/* flushes writebuffer to lcd, hyperoptmized, flushes buffer and commands in a single write operation */
|
||||
inline void lcd_flush_buf(struct lcd_t* lcd) {
|
||||
const uint8_t set_disp[] = {254, 71, 1, 1}; // set cursor to char 1, line 1
|
||||
inline void lcd_flush_buf(struct lcd_t *lcd) {
|
||||
const uint8_t set_disp[] = {254, 71, 1, 1}; // set cursor to char 1, line 1
|
||||
memcpy(&lcd->writebuf[0], set_disp, 4);
|
||||
memcpy(&lcd->writebuf[2 * LCD_COLS + 4], set_disp, 4);
|
||||
lcd->writebuf[2 * LCD_COLS + 7] = 3; // overwrite set cursor c1 l1 to c1 l3
|
||||
lcd_write(lcd, (const uint8_t*)lcd->writebuf, sizeof(lcd->writebuf));
|
||||
lcd->writebuf[2 * LCD_COLS + 7] = 3; // overwrite set cursor c1 l1 to c1 l3
|
||||
lcd_write(lcd, (const uint8_t *)lcd->writebuf, sizeof(lcd->writebuf));
|
||||
}
|
||||
|
||||
// i have a whole flushbuf func to avoid too many writes, but im writing on every bar, need to rethink this.
|
||||
// we could have a separate pre-char buffer and put all the setCustomChar commands to that?
|
||||
inline char lcd_bar(struct lcd_t* lcd, const uint8_t char_id, const double value) {
|
||||
inline char lcd_bar(struct lcd_t *lcd, const uint8_t char_id, const double value) {
|
||||
uint8_t b[8];
|
||||
memset(b, 0b01110, sizeof(b));
|
||||
for (uint8_t i = 0; i < (1.0 - value) * 8; i++)
|
||||
@@ -124,7 +126,7 @@ inline char lcd_bar(struct lcd_t* lcd, const uint8_t char_id, const double value
|
||||
return (char)char_id;
|
||||
}
|
||||
|
||||
int lcd_init(struct lcd_t* lcd) {
|
||||
int lcd_init(struct lcd_t *lcd) {
|
||||
const int ret = lcd_open(lcd, false);
|
||||
if (ret < 0) {
|
||||
lcd_close(lcd);
|
||||
|
||||
130
src/log.c
130
src/log.c
@@ -20,76 +20,90 @@ static pthread_mutex_t cmtx = PTHREAD_MUTEX_INITIALIZER;
|
||||
* "int other_func(void)" → "other_func"
|
||||
*/
|
||||
static void fmt_funcname(const char *pretty, char *out, size_t outsz) {
|
||||
const char *start = pretty;
|
||||
const char *start = pretty;
|
||||
|
||||
const char *space = strchr(pretty, ' ');
|
||||
if (space) start = space + 1;
|
||||
const char *space = strchr(pretty, ' ');
|
||||
if (space)
|
||||
start = space + 1;
|
||||
|
||||
const char *paren = strrchr(start, '(');
|
||||
size_t len = paren ? (size_t)(paren - start) : strlen(start);
|
||||
if (len >= outsz) len = outsz - 1;
|
||||
const char *paren = strrchr(start, '(');
|
||||
size_t len = paren ? (size_t)(paren - start) : strlen(start);
|
||||
if (len >= outsz)
|
||||
len = outsz - 1;
|
||||
|
||||
memcpy(out, start, len);
|
||||
out[len] = '\0';
|
||||
memcpy(out, start, len);
|
||||
out[len] = '\0';
|
||||
}
|
||||
|
||||
void log_write(const log_level_t level, const char *func, const char *fmt, ...) {
|
||||
static const char *reset = "\033[0m";
|
||||
const char *color;
|
||||
static const char *reset = "\033[0m";
|
||||
const char *color;
|
||||
|
||||
switch (level) {
|
||||
case LOG_INF: color = "\033[1;32m"; break; /* bold green */
|
||||
case LOG_WRN: color = "\033[1;33m"; break; /* bold yellow */
|
||||
case LOG_ERR: color = "\033[1;31m"; break; /* bold red */
|
||||
case LOG_DBG: color = ""; break;
|
||||
case LOG_START: color = "\033[1;3;36m"; break; /* bold italic cyan */
|
||||
default: color = ""; break;
|
||||
}
|
||||
switch (level) {
|
||||
case LOG_INF:
|
||||
color = "\033[1;32m";
|
||||
break; /* bold green */
|
||||
case LOG_WRN:
|
||||
color = "\033[1;33m";
|
||||
break; /* bold yellow */
|
||||
case LOG_ERR:
|
||||
color = "\033[1;31m";
|
||||
break; /* bold red */
|
||||
case LOG_DBG:
|
||||
color = "";
|
||||
break;
|
||||
case LOG_START:
|
||||
color = "\033[1;3;36m";
|
||||
break; /* bold italic cyan */
|
||||
default:
|
||||
color = "";
|
||||
break;
|
||||
}
|
||||
|
||||
char funcname[128];
|
||||
fmt_funcname(func, funcname, sizeof(funcname));
|
||||
char funcname[128];
|
||||
fmt_funcname(func, funcname, sizeof(funcname));
|
||||
|
||||
/* ── console ─────────────────────────────────────────────────────── */
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
pthread_mutex_lock(&cmtx);
|
||||
fprintf(stderr, "[%s%s%s] ", color, funcname, reset);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fputc('\n', stderr);
|
||||
pthread_mutex_unlock(&cmtx);
|
||||
va_end(ap);
|
||||
}
|
||||
/* ── console ─────────────────────────────────────────────────────── */
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
pthread_mutex_lock(&cmtx);
|
||||
fprintf(stderr, "[%s%s%s] ", color, funcname, reset);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fputc('\n', stderr);
|
||||
pthread_mutex_unlock(&cmtx);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef LOG_FILE_LOCATION
|
||||
/* ── file ────────────────────────────────────────────────────────── */
|
||||
{
|
||||
char timebuf[32];
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
struct tm tm_info;
|
||||
localtime_r(&ts.tv_sec, &tm_info);
|
||||
strftime(timebuf, sizeof(timebuf), "%x %H:%M:%S", &tm_info);
|
||||
#ifdef LOG_FILE_LOCATION
|
||||
/* ── file ────────────────────────────────────────────────────────── */
|
||||
{
|
||||
char timebuf[32];
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
struct tm tm_info;
|
||||
localtime_r(&ts.tv_sec, &tm_info);
|
||||
strftime(timebuf, sizeof(timebuf), "%x %H:%M:%S", &tm_info);
|
||||
|
||||
char msgbuf[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int offset = snprintf(msgbuf, sizeof(msgbuf),
|
||||
"%s.%03ld [%s%s%s] ",
|
||||
timebuf, ts.tv_nsec / 1000000L,
|
||||
color, funcname, reset);
|
||||
vsnprintf(msgbuf + offset, sizeof(msgbuf) - offset, fmt, ap);
|
||||
va_end(ap);
|
||||
char msgbuf[1024];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int offset = snprintf(msgbuf, sizeof(msgbuf),
|
||||
"%s.%03ld [%s%s%s] ",
|
||||
timebuf, ts.tv_nsec / 1000000L,
|
||||
color, funcname, reset);
|
||||
vsnprintf(msgbuf + offset, sizeof(msgbuf) - offset, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
pthread_mutex_lock(&fmtx);
|
||||
gzFile file = gzopen(LOG_FILE_LOCATION, "ab");
|
||||
if (file) {
|
||||
gzprintf(file, "%s\n", msgbuf);
|
||||
gzclose(file);
|
||||
}
|
||||
pthread_mutex_unlock(&fmtx);
|
||||
}
|
||||
#endif /* LOG_FILE_LOCATION */
|
||||
pthread_mutex_lock(&fmtx);
|
||||
gzFile file = gzopen(LOG_FILE_LOCATION, "ab");
|
||||
if (file) {
|
||||
gzprintf(file, "%s\n", msgbuf);
|
||||
gzclose(file);
|
||||
}
|
||||
pthread_mutex_unlock(&fmtx);
|
||||
}
|
||||
#endif /* LOG_FILE_LOCATION */
|
||||
}
|
||||
|
||||
#endif /* APPLOG_ENABLED */
|
||||
|
||||
29
src/main.c
29
src/main.c
@@ -1,16 +1,16 @@
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "lcd.h"
|
||||
#include "log.h"
|
||||
#include "cpu.h"
|
||||
#include "gpu.h"
|
||||
#include "lcd.h"
|
||||
#include "log.h"
|
||||
#include "sys.h"
|
||||
#include "utils.h"
|
||||
|
||||
@@ -38,7 +38,7 @@ struct sensors_t {
|
||||
|
||||
static void *sensors_thread(void *arg) {
|
||||
applog(LOG_START, "sensors thread started, refresh interval is %dms", refresh_interval_ms);
|
||||
struct sensors_t* sensors = arg;
|
||||
struct sensors_t *sensors = arg;
|
||||
|
||||
struct timespec next;
|
||||
clock_gettime(CLOCK_REALTIME, &next);
|
||||
@@ -76,7 +76,7 @@ static void *sensors_thread(void *arg) {
|
||||
|
||||
static void *display_thread(void *arg) {
|
||||
applog(LOG_START, "display thread started");
|
||||
struct sensors_t* sensors = arg;
|
||||
struct sensors_t *sensors = arg;
|
||||
|
||||
struct lcd_t lcd = {
|
||||
.port = "/dev/serial/by-id/usb-Raspberry_Pi_Pico_E6616407E37AA12F-if00",
|
||||
@@ -88,11 +88,11 @@ static void *display_thread(void *arg) {
|
||||
// basic lcd setup
|
||||
lcd_set_backlight(&lcd, true);
|
||||
lcd_set_contrast(&lcd, 206);
|
||||
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_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);
|
||||
@@ -103,7 +103,7 @@ static void *display_thread(void *arg) {
|
||||
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_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
|
||||
@@ -154,6 +154,7 @@ static void *display_thread(void *arg) {
|
||||
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);
|
||||
|
||||
/* signal setup */
|
||||
sigset_t sigset;
|
||||
|
||||
18
src/sys.c
18
src/sys.c
@@ -1,14 +1,13 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sys.h"
|
||||
#include "log.h"
|
||||
#include "sys.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
void sys_get_time(struct time_date_t *td) {
|
||||
const char months[][4] = {"sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paz", "lis", "gru"};
|
||||
const char wdays[][4] = {"Nie", "Pon", "Wto", "Sro", "Czw", "Pia", "Sob"};
|
||||
@@ -31,15 +30,16 @@ void sys_get_ram(struct memory_t *ram) {
|
||||
return;
|
||||
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
sscanf(buf, "MemTotal: %lu kB", &ram->total); // NOLINT we live dangerously
|
||||
sscanf(buf, "MemTotal: %lu kB", &ram->total); // NOLINT we live dangerously
|
||||
sscanf(buf, "MemAvailable: %lu kB", &ram->free); // NOLINT (its not really that dangerous)
|
||||
if (ram->total && ram->free) break;
|
||||
if (ram->total && ram->free)
|
||||
break;
|
||||
}
|
||||
fclose(f);
|
||||
ram->used = ram->total - ram->free;
|
||||
}
|
||||
|
||||
void sys_get_disk(struct disk_t* disk) {
|
||||
void sys_get_disk(struct disk_t *disk) {
|
||||
struct statvfs diskData;
|
||||
statvfs(disk->mountpoint, &diskData);
|
||||
disk->usage.free = diskData.f_bfree * diskData.f_frsize;
|
||||
@@ -47,7 +47,7 @@ void sys_get_disk(struct disk_t* disk) {
|
||||
disk->usage.total = diskData.f_blocks * diskData.f_frsize;
|
||||
}
|
||||
|
||||
void sys_get_network(struct network_t* network) {
|
||||
void sys_get_network(struct network_t *network) {
|
||||
struct _net_t {
|
||||
struct timespec ts;
|
||||
uint64_t rx;
|
||||
@@ -69,7 +69,7 @@ void sys_get_network(struct network_t* network) {
|
||||
prev = current;
|
||||
}
|
||||
|
||||
void sys_detect(struct syssensors_t* s, const char* platform) {
|
||||
void sys_detect(struct syssensors_t *s, const char *platform) {
|
||||
snprintf(s->hwmon, sizeof(s->hwmon), "/sys/devices/platform/%s/hwmon", platform);
|
||||
const int ret = get_hwmon_dir(s->hwmon);
|
||||
if (ret != 0) {
|
||||
@@ -80,7 +80,7 @@ void sys_detect(struct syssensors_t* s, const char* platform) {
|
||||
applog(LOG_INF, "Detected system sensors in %s", s->hwmon);
|
||||
}
|
||||
|
||||
void sys_update_sensors(struct syssensors_t* s) {
|
||||
void sys_update_sensors(struct syssensors_t *s) {
|
||||
if (!s->hwmon[0])
|
||||
return;
|
||||
static char buf[8];
|
||||
|
||||
39
src/utils.c
39
src/utils.c
@@ -1,18 +1,20 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <glob.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define MKPATH(path, dir, file) do { \
|
||||
char *nt = stpcpy(path, dir); \
|
||||
*nt++ = '/'; stpcpy(nt, file); \
|
||||
#define MKPATH(path, dir, file) \
|
||||
do { \
|
||||
char *nt = stpcpy(path, dir); \
|
||||
*nt++ = '/'; \
|
||||
stpcpy(nt, file); \
|
||||
} while (0)
|
||||
|
||||
inline void timespec_add_ms(struct timespec *ts, const uint16_t ms) {
|
||||
@@ -30,7 +32,8 @@ inline uint64_t timespec_diff_us(const struct timespec *a, const struct timespec
|
||||
}
|
||||
|
||||
inline char *pretty_num(const double num, char *buf, const size_t bufsz) {
|
||||
const uint8_t decimals = (num < 10) ? 2 : (num < 100) ? 1 : 0;
|
||||
const uint8_t decimals = (num < 10) ? 2 : (num < 100) ? 1
|
||||
: 0;
|
||||
snprintf(buf, bufsz, "%.*f", decimals, num);
|
||||
return buf;
|
||||
}
|
||||
@@ -47,13 +50,12 @@ inline char *pretty_bytes(const uint64_t bytes, int8_t start_suffix, char *buf,
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
inline bool file_exists(const char* path) {
|
||||
inline bool file_exists(const char *path) {
|
||||
return access(path, F_OK) == 0;
|
||||
}
|
||||
|
||||
/* path has to have at least 8 free chars at the end for glob */
|
||||
int get_hwmon_dir(char* path) {
|
||||
int get_hwmon_dir(char *path) {
|
||||
glob_t g;
|
||||
strncat(path, "/hwmon*", 10);
|
||||
|
||||
@@ -66,47 +68,48 @@ int get_hwmon_dir(char* path) {
|
||||
}
|
||||
|
||||
/* read n bytes from path into buffer */
|
||||
inline size_t read_file(const char* path, char* buffer, const size_t n) {
|
||||
inline size_t read_file(const char *path, char *buffer, const size_t n) {
|
||||
const int fd = open(path, O_RDONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
applog(LOG_ERR, "Error reading %s", path);
|
||||
return 0;
|
||||
}
|
||||
const ssize_t len = read(fd, buffer, n);
|
||||
if (len >= 0) buffer[len] = '\0';
|
||||
if (len >= 0)
|
||||
buffer[len] = '\0';
|
||||
close(fd);
|
||||
return len;
|
||||
}
|
||||
|
||||
inline void fast_read_num_u64(const char* dir, const char* file, char* buf, uint64_t* result, const uint32_t divider) {
|
||||
inline void fast_read_num_u64(const char *dir, const char *file, char *buf, uint64_t *result, const uint32_t divider) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtoull(buf, NULL, 10) / divider;
|
||||
}
|
||||
|
||||
inline void fast_read_num_u16(const char* dir, const char* file, char* buf, uint16_t* result, const uint32_t divider) {
|
||||
inline void fast_read_num_u16(const char *dir, const char *file, char *buf, uint16_t *result, const uint32_t divider) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtol(buf, NULL, 10) / divider;
|
||||
}
|
||||
|
||||
inline void fast_read_num_u8(const char* dir, const char* file, char* buf, uint8_t* result, const uint32_t divider) {
|
||||
inline void fast_read_num_u8(const char *dir, const char *file, char *buf, uint8_t *result, const uint32_t divider) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtol(buf, NULL, 10) / divider;
|
||||
}
|
||||
|
||||
inline void fast_read_num_i16(const char* dir, const char* file, char* buf, int16_t* result, const uint32_t divider) {
|
||||
inline void fast_read_num_i16(const char *dir, const char *file, char *buf, int16_t *result, const uint32_t divider) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtol(buf, NULL, 10) / divider;
|
||||
}
|
||||
|
||||
inline void fast_read_num_f(const char* dir, const char* file, char* buf, float* result, const uint32_t divider) {
|
||||
inline void fast_read_num_f(const char *dir, const char *file, char *buf, float *result, const uint32_t divider) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
|
||||
Reference in New Issue
Block a user