Compare commits
4 commits
12b2d399d6
...
b0d86c7e2c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b0d86c7e2c | ||
![]() |
f34dfcdccd | ||
![]() |
355f96d5e7 | ||
![]() |
433837e33d |
7 changed files with 145 additions and 8 deletions
2
Makefile
2
Makefile
|
@ -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
68
binprot.c
Normal 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
11
djb2.c
|
@ -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
14
treeset/Makefile
Normal 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
7
treeset/main.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include "treeset.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
treeset_t tree = {};
|
||||
return 0;
|
||||
}
|
25
treeset/treeset.c
Normal file
25
treeset/treeset.c
Normal 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
26
treeset/treeset.h
Normal 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
|
Loading…
Add table
Reference in a new issue