Compare commits
10 commits
c83cf1efd8
...
c2b9a13235
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c2b9a13235 | ||
![]() |
57d3ae36fb | ||
![]() |
cc5b27a3ab | ||
![]() |
d750f55e87 | ||
![]() |
6af488012f | ||
![]() |
582046cb58 | ||
![]() |
32acf1d6c7 | ||
![]() |
c788139f72 | ||
![]() |
905405164c | ||
![]() |
10830c8adb |
10 changed files with 576 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
|||
.cache
|
||||
.json
|
||||
*.elf
|
||||
tags
|
||||
|
|
57
break.c
Normal file
57
break.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h> // mmap and friends
|
||||
#include <unistd.h>
|
||||
|
||||
int main(void) {
|
||||
/*
|
||||
* See: "man 3 sysconf" or
|
||||
* https://www.man7.org/linux/man-pages/man3/sysconf.3.html
|
||||
*
|
||||
* See: "man 3 getauxval" or
|
||||
* https://www.man7.org/linux/man-pages/man3/getauxval.3.html
|
||||
*/
|
||||
long page_size =
|
||||
sysconf(_SC_PAGESIZE); // or _SC_PAGE_SIZE (POSIX allows both)
|
||||
if (page_size == -1) {
|
||||
perror("sysconf");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Page size: %ld bytes\n", page_size);
|
||||
|
||||
/*
|
||||
* sbrk():
|
||||
* Increase or decrease the end of accessible data space by DELTA bytes.
|
||||
* If successful, returns the address the previous end of data space
|
||||
* (i.e. the beginning of the new space, if DELTA > 0); returns (void \*) -1
|
||||
* for errors (with errno set).
|
||||
*/
|
||||
void *first = sbrk(0);
|
||||
void *second = sbrk(4096);
|
||||
void *third = sbrk(0);
|
||||
|
||||
printf("First: %p\n", first);
|
||||
printf("Second: %p\n", second);
|
||||
printf("Third: %p\n", third);
|
||||
|
||||
/*
|
||||
* mmap, munmap - map or unmap files or devices into memory
|
||||
*
|
||||
* mmap() creates a new mapping in the virtual address space of the
|
||||
* calling process. The starting address for the new mapping is specified
|
||||
* in addr. The length argument specifies the length of the mapping
|
||||
* (which must be greater than 0).
|
||||
*/
|
||||
|
||||
uint8_t *first_mmap = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
|
||||
uint8_t *second_mmap = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
|
||||
printf("First mmap: %p\n", first_mmap);
|
||||
printf("Second mmap: %p\n", second_mmap);
|
||||
|
||||
return 0;
|
||||
}
|
111
buddy_allocator.c
Normal file
111
buddy_allocator.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// This allocator lacks critical features such as coalescing
|
||||
|
||||
#define HEAP_SIZE (1 << 20) // 1 MB
|
||||
#define MIN_ORDER 5 // 32 bytes
|
||||
#define MAX_ORDER 20 // 1 MB
|
||||
|
||||
#define ORDER_TO_SZ(order) (1 << order)
|
||||
|
||||
// Round size up to nearest power-of-two order
|
||||
static int size_to_order(size_t size) {
|
||||
int order = MIN_ORDER;
|
||||
while ((1U << order) < size)
|
||||
order++;
|
||||
return order;
|
||||
}
|
||||
|
||||
typedef struct block {
|
||||
struct block *next;
|
||||
// int order;
|
||||
// int is_free;
|
||||
} block_t;
|
||||
|
||||
static char *heap;
|
||||
static block_t *free_lists[MAX_ORDER - MIN_ORDER + 1];
|
||||
|
||||
void buddy_init() {
|
||||
block_t *initial = (block_t *)heap;
|
||||
initial->next = NULL;
|
||||
// initial->order = MAX_ORDER;
|
||||
// initial->is_free = 1;
|
||||
free_lists[MAX_ORDER - MIN_ORDER] = initial;
|
||||
}
|
||||
|
||||
void *buddy_alloc(size_t size) {
|
||||
int order = size_to_order(size);
|
||||
int index = order - MIN_ORDER;
|
||||
|
||||
// Find the first available block of order >= needed
|
||||
int i = index; // i is the lowest possible order here
|
||||
while (i <= MAX_ORDER - MIN_ORDER && !free_lists[i]) {
|
||||
i++;
|
||||
}
|
||||
|
||||
// Check if were still within range, if not there are no free blocks
|
||||
if (i > MAX_ORDER - MIN_ORDER)
|
||||
return NULL;
|
||||
|
||||
// Split blocks down to the requested size
|
||||
while (i > index) { // Does not run if i == index
|
||||
block_t *bigger = free_lists[i];
|
||||
free_lists[i] = bigger->next; // This may be null, doesnt matter
|
||||
|
||||
i--; // i is now equivalent to one order below
|
||||
|
||||
size_t split_size = ORDER_TO_SZ(i);
|
||||
// FIXME: Char???
|
||||
char *middle = ((char *)bigger + split_size);
|
||||
block_t *buddy = (block_t *)middle;
|
||||
// block_t *buddy = (block_t *)((char *)bigger + split_size);
|
||||
buddy->next = NULL;
|
||||
bigger->next = buddy; // Biggers buddy is of equal size
|
||||
free_lists[i] = bigger; // Bigger is no longer bigger here
|
||||
}
|
||||
|
||||
// Allocate from free list
|
||||
block_t *block = free_lists[index];
|
||||
free_lists[index] = block->next;
|
||||
return (void *)block;
|
||||
}
|
||||
|
||||
// Free a block (no coalescing)
|
||||
void buddy_free(void *ptr, size_t size) {
|
||||
memset(ptr, 0xFFFFFFFF, size);
|
||||
|
||||
int order = size_to_order(size);
|
||||
int index = order - MIN_ORDER;
|
||||
|
||||
// Push this in front of the orders index
|
||||
block_t *block = (block_t *)ptr;
|
||||
block->next = free_lists[index];
|
||||
free_lists[index] = block;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
heap = malloc(1 << 20);
|
||||
|
||||
printf("Order: %d\n", size_to_order(100));
|
||||
printf("Order: %d\n", size_to_order(1000));
|
||||
|
||||
buddy_init();
|
||||
|
||||
void *a = buddy_alloc(100);
|
||||
void *b = buddy_alloc(1000);
|
||||
|
||||
*(int *)a = 10;
|
||||
printf("a = %d\n", *(int *)a);
|
||||
|
||||
buddy_free(a, 100);
|
||||
buddy_free(b, 1000);
|
||||
|
||||
printf("a = %d\n", *(int *)a);
|
||||
|
||||
free(heap);
|
||||
return 0;
|
||||
}
|
58
gba_header.c
Normal file
58
gba_header.c
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define HEADER_SIZE 192 // GBA header is 192 bytes
|
||||
|
||||
// Structure to hold GBA ROM header data
|
||||
typedef struct {
|
||||
uint32_t entry_point; // 0x08000000 - Entry Point
|
||||
uint8_t nintendo_logo[156]; // 0x08000004 - Nintendo Logo
|
||||
char game_title[12]; // 0x080000A0 - Game Title
|
||||
char game_code[4]; // 0x080000AC - Game Code (e.g., "AGB-XXXX")
|
||||
char maker_code[2]; // 0x080000B0 - Maker Code
|
||||
uint8_t fixed_value; // 0x080000B2 - Always 0x96
|
||||
uint8_t main_unit_code; // 0x080000B3 - Usually 0x00
|
||||
uint8_t device_type; // 0x080000B4 - Usually 0x00
|
||||
uint8_t reserved1[7]; // 0x080000B5 - Reserved
|
||||
uint8_t software_version; // 0x080000BC - Software Version
|
||||
uint8_t complement_check; // 0x080000BD - Header Checksum
|
||||
uint8_t reserved2[2]; // 0x080000BE - Reserved
|
||||
} GBAHeader;
|
||||
|
||||
// Function to read and display the ROM header
|
||||
void read_gba_header(const char *filename) {
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
perror("Error opening file");
|
||||
return;
|
||||
}
|
||||
|
||||
GBAHeader header;
|
||||
|
||||
// Read 192-byte header
|
||||
if (fread(&header, 1, HEADER_SIZE, file) != HEADER_SIZE) {
|
||||
perror("Error reading header");
|
||||
fclose(file);
|
||||
return;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
// Display ROM header information
|
||||
printf("Game Title: %.12s\n", header.game_title);
|
||||
printf("Game Code: %.4s\n", header.game_code);
|
||||
printf("Maker Code: %.2s\n", header.maker_code);
|
||||
printf("Software Version: %d\n", header.software_version);
|
||||
printf("Complement Checksum: 0x%02X\n", header.complement_check);
|
||||
printf("Entry Point: 0x%08X\n", header.entry_point);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <gba_rom_file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
read_gba_header(argv[1]);
|
||||
return 0;
|
||||
}
|
104
miller-rabin.h
Normal file
104
miller-rabin.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @brief Calculates (a * b) % c taking into account that a * b might overflow
|
||||
*
|
||||
* @param a First factor
|
||||
* @param b Second factor
|
||||
* @param mod The modulo
|
||||
* @return Resulting value
|
||||
*/
|
||||
uint64_t mulmod(uint64_t a, uint64_t b, uint64_t mod);
|
||||
|
||||
/**
|
||||
* @brief Modular exponentiation
|
||||
*
|
||||
* @param base
|
||||
* @param exponent
|
||||
* @param mod
|
||||
* @return
|
||||
*/
|
||||
uint64_t modulo(uint64_t base, uint64_t exponent, uint64_t mod);
|
||||
|
||||
/**
|
||||
* @brief Miller-Rabin Primality Test
|
||||
*
|
||||
* This function performs the Miller-Rabin primality test to determine whether
|
||||
* a given number is prime. The number of iterations increases the accuracy of
|
||||
* the test but also increases computation time.
|
||||
*
|
||||
* @param p The number to test for primality (must be a positive integer).
|
||||
* @param iteration The number of test rounds to perform (higher means more
|
||||
* accuracy).
|
||||
* @return 1 if the number is probably prime, 0 if it is composite.
|
||||
*/
|
||||
uint32_t miller_rabin(uint64_t p, uint32_t iteration);
|
||||
|
||||
/* Below code is source, not header */
|
||||
/************************************/
|
||||
|
||||
uint64_t mulmod(uint64_t a, uint64_t b, uint64_t mod) {
|
||||
uint64_t x = 0, y = a % mod;
|
||||
|
||||
while (b > 0) {
|
||||
if (b % 2 == 1) {
|
||||
x = (x + y) % mod;
|
||||
}
|
||||
y = (y * 2) % mod;
|
||||
b /= 2;
|
||||
}
|
||||
|
||||
return x % mod;
|
||||
}
|
||||
|
||||
uint64_t modulo(uint64_t base, uint64_t exponent, uint64_t mod) {
|
||||
uint64_t x = 1;
|
||||
uint64_t y = base;
|
||||
|
||||
while (exponent > 0) {
|
||||
if (exponent % 2 == 1)
|
||||
x = (x * y) % mod;
|
||||
|
||||
y = (y * y) % mod;
|
||||
|
||||
exponent = exponent / 2;
|
||||
}
|
||||
|
||||
return x % mod;
|
||||
}
|
||||
|
||||
uint32_t miller_rabin(uint64_t p, uint32_t iteration) {
|
||||
uint32_t i;
|
||||
uint64_t s;
|
||||
|
||||
if (p < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p != 2 && p % 2 == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = p - 1;
|
||||
|
||||
while (s % 2 == 0) {
|
||||
s /= 2;
|
||||
}
|
||||
|
||||
for (i = 0; i < iteration; i++) {
|
||||
uint64_t a = rand() % (p - 1) + 1, temp = s;
|
||||
uint64_t mod = modulo(a, temp, p);
|
||||
|
||||
while (temp != p - 1 && mod != 1 && mod != p - 1) {
|
||||
mod = mulmod(mod, mod, p);
|
||||
temp *= 2;
|
||||
}
|
||||
|
||||
if (mod != p - 1 && temp % 2 == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
32
mmio_mapping.h
Normal file
32
mmio_mapping.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include <stdint.h>
|
||||
|
||||
// Macro for register access (volatile pointer dereferencing, not used here)
|
||||
#define REG32(addr) (*(volatile uint32_t *)(addr))
|
||||
#define REG16(addr) (*(volatile uint16_t *)(addr))
|
||||
#define REG8(addr) (*(volatile uint8_t *)(addr))
|
||||
|
||||
typedef struct MMIO_device {
|
||||
volatile uint16_t hello;
|
||||
volatile uint8_t __RESERVED1[2];
|
||||
volatile uint16_t status;
|
||||
volatile uint8_t __RESERVED2[8];
|
||||
volatile uint32_t control;
|
||||
// ...and so on
|
||||
} __attribute__((aligned(4))) MMIO_device;
|
||||
|
||||
/* A base address pointing to the start of the 'peripherals' memory region */
|
||||
#define MEM_PERIPH_BASE 0xDEADBEEF
|
||||
|
||||
/* Specific device, often defined as an offset from a base */
|
||||
#define MY_MMIO (MEM_PERIPH_BASE + 0x10)
|
||||
|
||||
#define DVC_CTLR_ENA (0x3 << 1) /* Device Control Register Enable */
|
||||
#define DVC_CTLR_WRITE (0x1) /* Device Control Register Write */
|
||||
|
||||
volatile MMIO_device *mmio1 = (volatile MMIO_device *)MY_MMIO;
|
||||
|
||||
void configure_peripheral() {
|
||||
mmio1->hello = 0x1234; // Raw write
|
||||
mmio1->control |= DVC_CTLR_ENA | DVC_CTLR_WRITE; // Set
|
||||
mmio1->control &= ~(DVC_CTLR_ENA | DVC_CTLR_WRITE); // Clear
|
||||
}
|
74
pid.c
Normal file
74
pid.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define BUFFER_SIZE 100
|
||||
|
||||
typedef struct {
|
||||
float Kp, Ki, Kd; // PID gains
|
||||
float error_buffer[BUFFER_SIZE]; // Circular buffer for integral calculation
|
||||
int buffer_index; // Current index in the buffer
|
||||
float integral_sum; // Running sum of integral terms
|
||||
float prev_error; // Previous error for derivative term
|
||||
float dt; // Sample time (seconds)
|
||||
} PIDController;
|
||||
|
||||
// Initialize PID controller
|
||||
void pid_init(PIDController *pid, float Kp, float Ki, float Kd, float dt) {
|
||||
pid->Kp = Kp;
|
||||
pid->Ki = Ki;
|
||||
pid->Kd = Kd;
|
||||
pid->dt = dt;
|
||||
pid->buffer_index = 0;
|
||||
pid->integral_sum = 0.0f;
|
||||
pid->prev_error = 0.0f;
|
||||
memset(pid->error_buffer, 0, sizeof(pid->error_buffer));
|
||||
}
|
||||
|
||||
// Compute PID output
|
||||
float pid_compute(PIDController *pid, float setpoint, float pv) {
|
||||
float error = setpoint - pv;
|
||||
|
||||
// Update integral term using circular buffer
|
||||
pid->integral_sum -=
|
||||
pid->error_buffer[pid->buffer_index]; // Remove oldest value
|
||||
pid->error_buffer[pid->buffer_index] =
|
||||
error * pid->dt; // Store new integral term
|
||||
pid->integral_sum += pid->error_buffer[pid->buffer_index]; // Add new value
|
||||
|
||||
// Advance circular buffer index
|
||||
pid->buffer_index = (pid->buffer_index + 1) % BUFFER_SIZE;
|
||||
|
||||
// Compute derivative term
|
||||
float derivative = (error - pid->prev_error) / pid->dt;
|
||||
pid->prev_error = error;
|
||||
|
||||
// Compute PID output
|
||||
float output = (pid->Kp * error) + (pid->Ki * pid->integral_sum) +
|
||||
(pid->Kd * derivative);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int main() {
|
||||
PIDController pid;
|
||||
pid_init(&pid, 1.0f, 0.1f, 0.05f,
|
||||
0.01f); // Kp, Ki, Kd, dt (10ms sample time)
|
||||
|
||||
float setpoint = 100.0f;
|
||||
float pv = 90.0f;
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
float output = pid_compute(&pid, setpoint, pv);
|
||||
printf("Iteration %d: Setpoint: %.2f, PV: %.2f, Output: %.2f\n", i,
|
||||
setpoint, pv, output);
|
||||
|
||||
// Simulate process variable update
|
||||
pv += output * 0.1f;
|
||||
if (fabsf(output) < 0.4)
|
||||
setpoint = 150;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
69
sock.c
Normal file
69
sock.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int main(void) {
|
||||
// Get TCP protocol entry
|
||||
struct protoent *pent = getprotobyname("tcp");
|
||||
if (!pent) {
|
||||
perror("getprotobyname failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Create socket
|
||||
int server_fd = socket(AF_INET, SOCK_STREAM, pent->p_proto);
|
||||
if (server_fd < 0) {
|
||||
perror("socket failed");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Set up server address structure
|
||||
struct sockaddr_in server_addr = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = htonl(INADDR_ANY), // Bind to any available address
|
||||
.sin_port = htons(8080) // Port 8080
|
||||
};
|
||||
|
||||
// Bind socket
|
||||
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
|
||||
perror("bind failed");
|
||||
close(server_fd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Listen for incoming connections
|
||||
if (listen(server_fd, 5) < 0) {
|
||||
perror("listen failed");
|
||||
close(server_fd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Server listening on port 8080...\n");
|
||||
|
||||
// Accept one client connection
|
||||
struct sockaddr_in client_addr;
|
||||
socklen_t client_len = sizeof(client_addr);
|
||||
int client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len);
|
||||
if (client_fd < 0) {
|
||||
perror("accept failed");
|
||||
close(server_fd);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("Client connected!\n");
|
||||
|
||||
// Send a message to the client
|
||||
const char *message = "Hello from server!\n";
|
||||
send(client_fd, message, strlen(message), 0);
|
||||
|
||||
// Cleanup
|
||||
close(client_fd);
|
||||
close(server_fd);
|
||||
|
||||
printf("Exit\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
46
sqlite.c
Normal file
46
sqlite.c
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include <sqlite3.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* See: https://zetcode.com/db/sqlitec/
|
||||
* Build with:
|
||||
* gcc -o version version.c -lsqlite3 -std=c99
|
||||
*/
|
||||
|
||||
int main(void) {
|
||||
printf("%s\n", sqlite3_libversion());
|
||||
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *res;
|
||||
|
||||
int rc = sqlite3_open(":memory:", &db);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
|
||||
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = sqlite3_prepare_v2(db, "SELECT SQLITE_VERSION()", -1, &res, 0);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
|
||||
fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = sqlite3_step(res);
|
||||
|
||||
if (rc == SQLITE_ROW) {
|
||||
printf("%s\n", sqlite3_column_text(res, 0));
|
||||
}
|
||||
|
||||
sqlite3_finalize(res);
|
||||
sqlite3_close(db);
|
||||
|
||||
return 0;
|
||||
}
|
24
time.c
Normal file
24
time.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
int main() {
|
||||
char *out = malloc(200);
|
||||
struct tm *tmp;
|
||||
|
||||
time_t t = time(NULL);
|
||||
tmp = localtime(&t);
|
||||
|
||||
if (tmp == NULL) {
|
||||
perror("localtime");
|
||||
exit(EXIT_FAILURE);
|
||||
};
|
||||
|
||||
if (strftime(out, 200, "%s", tmp) == 0) {
|
||||
fprintf(stderr, "strftime returned 0");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
printf("Result string is %s", out);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
Loading…
Add table
Reference in a new issue