c99 now
This commit is contained in:
@@ -6,9 +6,9 @@ project(linuxSmartie
|
||||
)
|
||||
|
||||
# Use C23
|
||||
set(CMAKE_C_STANDARD 23)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
#set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
#set(CMAKE_C_EXTENSIONS ON)
|
||||
|
||||
# Collect sources
|
||||
file(GLOB SOURCES
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# linuxSmartie
|
||||
Alphanumeric LCD controller software for Linux (kind of LCDSmartie for Windows but no GUI, no config file, no plugins, no Windows).
|
||||
|
||||
Big ol rewrite in C, like God intended because GOOD LORD C++ IS A MESS.
|
||||
Big ol rewrite in C, like God intended because GOOD LORD C++ IS A MESS. Originally written with C23, then ported to C99 because it's a bigger numer. Also trivially portable to ANSI C. Idk maybe I'll port it to C23 again.
|
||||
|
||||
Hardcoded to work with 4x40 character display because that's what I have and I don't plan on using anything else. Uses Matrix Orbital protocol over serial. Should work with most other display sizes by modifying `src/LCDDisplay.cpp`. Best of luck if you try to make it work with anything else.
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define GPU_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct gpu_sensors_t {
|
||||
uint64_t vram_used;
|
||||
|
||||
@@ -20,7 +20,7 @@ typedef enum {
|
||||
LOG_ERR,
|
||||
LOG_DBG,
|
||||
LOG_START,
|
||||
} LogLevel;
|
||||
} 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.
|
||||
@@ -30,7 +30,7 @@ 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(LogLevel level, const char *func, const char *fmt, ...)
|
||||
void log_write(log_level_t level, const char *func, const char *fmt, ...)
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
|
||||
#else /* APPLOG_ENABLED not defined */
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
#define UTILS_H
|
||||
|
||||
#include <time.h>
|
||||
#include <stdbool.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(const double num, char *buf, const 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);
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "utils.h"
|
||||
#include "log.h"
|
||||
|
||||
constexpr char rel_metrics_path[] = "/../../gpu_metrics"; // gpu_metrics path relative to hwmon path
|
||||
constexpr uint16_t max_metrics_length = 512; // length of the metrics buffer
|
||||
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
|
||||
|
||||
void gpu_detect(struct gpu_sensors_t *t, const char *pci) {
|
||||
snprintf(t->hwmon, sizeof(t->hwmon), "/sys/bus/pci/devices/%s/hwmon", pci);
|
||||
|
||||
@@ -36,7 +36,7 @@ void lcd_write(struct lcd_t* lcd, const uint8_t* cmdbuf, const uint8_t len) {
|
||||
}
|
||||
|
||||
void lcd_clear(struct lcd_t* lcd) {
|
||||
constexpr uint8_t cmdbuf[] = {254, 88};
|
||||
const uint8_t cmdbuf[] = {254, 88};
|
||||
lcd_write(lcd, cmdbuf, sizeof(cmdbuf));
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ inline void lcd_clear_buf(struct lcd_t* lcd) {
|
||||
|
||||
/* flushes writebuffer to lcd, hyperoptmized, flushes buffer and commands in a single write operation */
|
||||
inline void lcd_flush_buf(struct lcd_t* lcd) {
|
||||
constexpr uint8_t set_disp[] = {254, 71, 1, 1}; // set cursor to char 1, line 1
|
||||
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
|
||||
@@ -138,7 +138,7 @@ int lcd_init(struct lcd_t* lcd) {
|
||||
tcsetattr(lcd->fd, TCSANOW, &term);
|
||||
|
||||
lcd_clear_buf(lcd);
|
||||
constexpr uint8_t cmdbuf[] = {254, 75, 254, 84};
|
||||
const uint8_t cmdbuf[] = {254, 75, 254, 84};
|
||||
lcd_write(lcd, cmdbuf, sizeof(cmdbuf));
|
||||
|
||||
lcd_clear(lcd);
|
||||
|
||||
@@ -33,7 +33,7 @@ static void fmt_funcname(const char *pretty, char *out, size_t outsz) {
|
||||
out[len] = '\0';
|
||||
}
|
||||
|
||||
void log_write(const LogLevel level, const char *func, const char *fmt, ...) {
|
||||
void log_write(const log_level_t level, const char *func, const char *fmt, ...) {
|
||||
static const char *reset = "\033[0m";
|
||||
const char *color;
|
||||
|
||||
|
||||
30
src/main.c
30
src/main.c
@@ -14,10 +14,10 @@
|
||||
#include "sys.h"
|
||||
#include "utils.h"
|
||||
|
||||
static constexpr uint16_t refresh_interval_ms = 500;
|
||||
static constexpr char netif[] = "enp7s0";
|
||||
static constexpr char cpu_pcidev[] = "0000:00:18.3";
|
||||
static constexpr char gpu_pcidev[] = "0000:0a:00.0";
|
||||
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";
|
||||
|
||||
struct control_t {
|
||||
pthread_mutex_t sensors_mtx;
|
||||
@@ -67,11 +67,11 @@ static void *sensors_thread(void *arg) {
|
||||
pthread_cond_signal(&control.sensors_ready);
|
||||
|
||||
timespec_add_ms(&next, refresh_interval_ms);
|
||||
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next, nullptr);
|
||||
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next, NULL);
|
||||
}
|
||||
|
||||
applog(LOG_WRN, "sensors thread stopped");
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *display_thread(void *arg) {
|
||||
@@ -148,7 +148,7 @@ static void *display_thread(void *arg) {
|
||||
lcd_flush_buf(&lcd);
|
||||
lcd_close(&lcd);
|
||||
applog(LOG_WRN, "display thread stopped");
|
||||
return nullptr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
@@ -161,18 +161,18 @@ int main(void) {
|
||||
sigaddset(&sigset, SIGINT);
|
||||
sigaddset(&sigset, SIGTERM);
|
||||
sigaddset(&sigset, SIGQUIT);
|
||||
pthread_sigmask(SIG_BLOCK, &sigset, nullptr);
|
||||
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
|
||||
struct signalfd_siginfo info;
|
||||
const int sfd = signalfd(-1, &sigset, SFD_CLOEXEC);
|
||||
|
||||
/* control vars setup */
|
||||
pthread_mutex_init(&control.sensors_mtx, nullptr);
|
||||
pthread_cond_init(&control.sensors_ready, nullptr);
|
||||
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 == nullptr) {
|
||||
if (sensors == NULL) {
|
||||
applog(LOG_ERR, "cant allocate mem for the sensor struct");
|
||||
free(sensors);
|
||||
return -1;
|
||||
@@ -184,8 +184,8 @@ int main(void) {
|
||||
pthread_t sensors_pthread;
|
||||
|
||||
/* actually start the threads */
|
||||
pthread_create(&display_pthread, nullptr, display_thread, sensors);
|
||||
pthread_create(&sensors_pthread, nullptr, sensors_thread, sensors);
|
||||
pthread_create(&display_pthread, NULL, display_thread, sensors);
|
||||
pthread_create(&sensors_pthread, NULL, sensors_thread, sensors);
|
||||
|
||||
const ssize_t ret = read(sfd, &info, sizeof(info)); // halts on this until SIGTERM
|
||||
(void)ret;
|
||||
@@ -194,8 +194,8 @@ int main(void) {
|
||||
applog(LOG_WRN, "got stop signal, shutting down...");
|
||||
close(sfd);
|
||||
control.g_running = false;
|
||||
pthread_join(display_pthread, nullptr);
|
||||
pthread_join(sensors_pthread, nullptr);
|
||||
pthread_join(display_pthread, NULL);
|
||||
pthread_join(sensors_pthread, NULL);
|
||||
free(sensors);
|
||||
return 0;
|
||||
}
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
|
||||
void sys_get_time(struct time_date_t *td) {
|
||||
constexpr char months[][4] = {"sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paz", "lis", "gru"};
|
||||
constexpr char wdays[][4] = {"Nie", "Pon", "Wto", "Sro", "Czw", "Pia", "Sob"};
|
||||
const time_t t = time(nullptr);
|
||||
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"};
|
||||
const time_t t = time(NULL);
|
||||
const struct tm *tm = localtime(&t);
|
||||
snprintf(td->time, sizeof(td->time), "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
snprintf(td->date, sizeof(td->date), "%s, %02d %s", wdays[tm->tm_wday], tm->tm_mday, months[tm->tm_mon]);
|
||||
@@ -27,7 +27,7 @@ void sys_get_ram(struct memory_t *ram) {
|
||||
memset(ram, 0, sizeof(struct memory_t)); // zero out all values so we dont break out of the loop early
|
||||
|
||||
FILE *f = fopen("/proc/meminfo", "r");
|
||||
if (f == nullptr)
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
while (fgets(buf, sizeof(buf), f)) {
|
||||
|
||||
14
src/utils.c
14
src/utils.c
@@ -36,7 +36,7 @@ inline char *pretty_num(const double num, char *buf, const size_t bufsz) {
|
||||
}
|
||||
|
||||
inline char *pretty_bytes(const uint64_t bytes, int8_t start_suffix, char *buf, const size_t bufsz) {
|
||||
constexpr char suffix_list[] = {'K', 'M', 'G', 'T', 'P', 'E', 'Z'};
|
||||
const char suffix_list[] = {'K', 'M', 'G', 'T', 'P', 'E', 'Z'};
|
||||
start_suffix *= -1;
|
||||
double bytes_d = (double)bytes;
|
||||
while (bytes_d > 1024.0) {
|
||||
@@ -57,7 +57,7 @@ int get_hwmon_dir(char* path) {
|
||||
glob_t g;
|
||||
strncat(path, "/hwmon*", 10);
|
||||
|
||||
if (glob(path, 0, nullptr, &g) == 0) {
|
||||
if (glob(path, 0, NULL, &g) == 0) {
|
||||
strncpy(path, g.gl_pathv[0], 128); // bug prone, careful
|
||||
globfree(&g);
|
||||
return 0;
|
||||
@@ -82,33 +82,33 @@ inline void fast_read_num_u64(const char* dir, const char* file, char* buf, uint
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtoull(buf, nullptr, 10) / divider;
|
||||
*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) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtol(buf, nullptr, 10) / divider;
|
||||
*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) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtol(buf, nullptr, 10) / divider;
|
||||
*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) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = strtol(buf, nullptr, 10) / divider;
|
||||
*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) {
|
||||
char path[256];
|
||||
MKPATH(path, dir, file);
|
||||
read_file(path, buf, 32);
|
||||
*result = (float)strtoull(buf, nullptr, 10) / (float)divider;
|
||||
*result = (float)strtoull(buf, NULL, 10) / (float)divider;
|
||||
}
|
||||
Reference in New Issue
Block a user