#ifndef __OS_KERNEL_H_
#define __OS_KERNEL_H_

#include <stdint.h>
#include <stddef.h>

#define KERN_WAIT_INFINITE            (0xFFFFFFFF)

typedef enum
{
    KERN_STATUS_SUCCESS,
    KERN_STATUS_INVALID_MSG,
    KERN_STATUS_QUEUE_FULL,
    KERN_STATUS_TIMEOUT,
} KERN_Status;

typedef void (*TaskFunction)( void * );
typedef void (*TimerFunction)();

void  KERN_start();
void  KERN_createTask(TaskFunction task_proc, const char* name, uint8_t id, uint16_t stack_depth, uint32_t priority, void* param);
void  KERN_createQueue(uint8_t id, uint32_t length, size_t item_size);
void  KERN_sleep(uint32_t milliseconds);
void* KERN_malloc(size_t size);
void  KERN_free(void * mem);

void* KERN_createMutex();
void  KERN_destroyMutex(void* mutex);
void  KERN_lock(void* mutex);
void  KERN_unlock(void* mutex);

void* KERN_createSemaphore(const uint8_t init_value);
void  KERN_destroySemaphore(void* semaphore);
void  KERN_wait(void* semaphore, uint32_t milliseconds);
void  KERN_post(void* semaphore);

void  KERN_registerTimer(uint8_t id, uint32_t milliseconds, uint8_t reload, TimerFunction callback);
void  KERN_releaseTimer(uint8_t id);
void  KERN_startTimer(uint8_t id);
void  KERN_stopTimer(uint8_t id);
void  KERN_resetTimer(uint8_t id);
void  KERN_changeTimer(uint8_t id, uint32_t milliseconds, TimerFunction callback);

int32_t KERN_sndMsg(uint8_t queue_id, void * item, uint32_t milliseconds);
int32_t KERN_sndMsgFromISR(uint8_t queue_id, void * item);
int32_t KERN_sndMsgToFront(uint8_t queue_id, void * item, uint32_t milliseconds);
int32_t KERN_sndMsgToFrontFromISR(uint8_t queue_id, void * item);
int32_t KERN_rcvMsg(uint8_t queue_id, void * buffer, uint32_t milliseconds);

uint32_t KERN_getCurrentTime();

#endif
