// // Created by rick on 28-01-21. // #include #include #include #include #include #include #include #define MAX_HANDLERS 8 #define STREAM_SIZE (32*1024) #define PRINT_BUFFER_SIZE 64 stream_t *kprint_stream = NULL; kprint_handler handlers[MAX_HANDLERS] = {0}; void kprint_register(kprint_handler handler) { for (int i = 0; i < MAX_HANDLERS; ++i) { if (handlers[i] == NULL) { handlers[i] = handler; break; } } // todo handle } void kprint(const char *msg) { if (kprint_stream == NULL) { kprint_sync(msg); } else { stream_write(kprint_stream, (const uint8_t *) msg, strlen(msg)); } } void kprint_internal(const char *msg) { for (int i = 0; i < MAX_HANDLERS; ++i) { if (handlers[i] == NULL) { continue; } handlers[i](msg); } } void kprint_sync(const char *msg) { kprint_internal(msg); } void kprint_init() { kprint_stream = stream_create(STREAM_SIZE); } void att_noreturn kprint_task(void *_) { uint32_t last_read = 0; uint8_t data[PRINT_BUFFER_SIZE + 1] = {0}; while (true) { stream_wait(kprint_stream); while (true) { last_read = stream_read(kprint_stream, data, PRINT_BUFFER_SIZE); if (last_read == 0) break; data[last_read] = 0; kprint_internal((const char *) data); }; } } void kprint_start_task() { task_spawn(kprint_task, NULL, "kprint"); } INIT_FUNCTION(100) = { .name = "kprint-task", .stage = INIT_STAGE_PRE_TASKING, .init = kprint_start_task, };