Compare commits

..

4 commits

Author SHA1 Message Date
Imbus
b0d86c7e2c Treeset skeleton 2025-06-25 09:31:46 +02:00
Imbus
f34dfcdccd Fix 2025-06-25 08:41:33 +02:00
Imbus
355f96d5e7 Binary protocol example binprot.c 2025-06-25 08:37:14 +02:00
Imbus
433837e33d Makefile cleaning 2025-06-25 07:32:33 +02:00
7 changed files with 145 additions and 8 deletions

View file

@ -1,7 +1,5 @@
CC := gcc
CFLAGS := -Wall -Wextra -O2
#CFLAGS += -std=c99 # C99 breaks sbrk for some reason (likely toolchain bug)
LIBS := -lsqlite3 # Everything links to sqlite rofl
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)

68
binprot.c Normal file
View file

@ -0,0 +1,68 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
/*
* Example binary protocol for passing small, statically sized messages.
*
* These messages are efficient and easily serializable. Since there is no variable length payload in the message, no
* parsing is required, and a simple cast into whatever reciever buffer you're using, or a memcpy into a preallocated
* CommandMessage, is enough. Keep in mind; the largest member of the data union determines the size of the struct.
*/
// clang-format off
typedef enum {
CMD_SET_LEVEL = 1,
CMD_SET_LIGHTS = 2,
CMD_SET_DISTANCE_FACTOR = 3
} CommandType;
typedef struct __attribute__((__packed__)) {
uint8_t type;
union {
struct { uint8_t level; } set_level;
struct { uint8_t on; } set_lights; // 1 = on, 0 = off
struct { float factor; } set_distance;
} data;
/* NOTE: Consider adding crc checksum here, or in a wrapper struct */
} CommandMessage;
// clang-format on
void print_command(CommandMessage *m) {
switch (m->type) {
case CMD_SET_LEVEL:
printf("Type: SetLevel\nPayload: %d\n", m->data.set_level.level);
break;
case CMD_SET_LIGHTS:
printf("Type: SetLights\nPayload: %d\n", m->data.set_lights.on);
break;
case CMD_SET_DISTANCE_FACTOR:
printf("Type: SetDistanceFactor\nPayload: %.2f\n", m->data.set_distance.factor);
break;
}
}
char buf[sizeof(CommandMessage)];
int main(void) {
CommandMessage m = {CMD_SET_LIGHTS, .data.set_lights.on = 1};
memcpy(buf, &m, sizeof(CommandMessage));
/* Here we can send buf through a socket, to uart, wherever */
CommandMessage r = {0};
memcpy(&r, &buf, sizeof(CommandMessage));
/* We can then dispatch based on the message type */
print_command(&r);
m.type = CMD_SET_LEVEL;
m.data.set_level.level = 10;
print_command(&m);
m.type = CMD_SET_DISTANCE_FACTOR;
m.data.set_distance.factor = 1337.42;
print_command(&m);
return 0;
}

11
djb2.c
View file

@ -1,15 +1,14 @@
#include <stdio.h>
/*
* Simple hash function djb2, as in Daniel J. Berenstein.
*/
unsigned long djb2(const char *str) {
unsigned long h = 5381;
int c;
while ((c = *str++)) {
h = ((h << 5) + h) + c;
// Essentially equal to:
// h = h * 33 + c;
}
while ((c = *str++)) h = ((h << 5) + h) + c; // h = h * 33 + c;
return h;
}

14
treeset/Makefile Normal file
View file

@ -0,0 +1,14 @@
CC = gcc
CFLAGS = -Wall -O2
TARGET = main.elf
SRC = main.c treeset.c
#LDFLAGS =
$(TARGET): $(SRC)
@echo CC $@
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
clean:
rm -f $(TARGET)

7
treeset/main.c Normal file
View file

@ -0,0 +1,7 @@
#include "treeset.h"
#include <stdio.h>
int main() {
treeset_t tree = {};
return 0;
}

25
treeset/treeset.c Normal file
View file

@ -0,0 +1,25 @@
#include "treeset.h"
#include <stdlib.h>
#include <string.h>
struct treeset_node {
void *data;
struct treeset_node *left;
struct treeset_node *right;
};
struct treeset {
treeset_node_t *root;
size_t node_count;
};
void ts_node_destroy(treeset_node_t *n) {
if (n->left != NULL)
ts_node_destroy((treeset_node_t *)n->left);
if (n->right != NULL)
ts_node_destroy((treeset_node_t *)n->left);
free(n);
}
void treeset_destroy(treeset_t *set) { ts_node_destroy(set->root); }

26
treeset/treeset.h Normal file
View file

@ -0,0 +1,26 @@
#pragma once
#include <stddef.h>
typedef struct treeset treeset_t;
typedef struct treeset_node treeset_node_t;
/*
* Cast a and b to your custom struct and return:
* 1 for greater than
* -1 for less than
* 0 for equal
*/
int treeset_demo_cmp(void *a, void *b) {
if (*((int *)a) > *((int *)a))
return -1;
if (*((int *)a) < *((int *)a))
return 1;
return 0;
}
void treeset_destroy(treeset_t *set);
void put(treeset_t *set, void *data, int (*cmp)(void *, void *));
// contains
// remove