/*
 * kernel.h
 *
 *  Created on: Jul 28, 2016
 *      Author: tkl
 */

#ifndef SOURCE_FIRMWARE_KERNEL_INTERFACE_KERNEL_H_
#define SOURCE_FIRMWARE_KERNEL_INTERFACE_KERNEL_H_

void schedule_start(void);

enum thread_priority {
	THREAD_PRIO_IDLE = 0,
	THREAD_PRIO_LOW,
	THREAD_PRIO_MEDIUM,
	THREAD_PRIO_HIGH
};

enum thread_status {
	THREAD_STATUS_INIT = 0,
	THREAD_STATUS_EXECUTING,
	THREAD_STATUS_WAITING,
	THREAD_STATUS_SLEEPING,
	THREAD_STATUS_BLOCKING
};

#pragma pack(push)
#pragma pack(1)
struct thread_context {
	stack_t *sp;					/**< thread's stack pointer */
	stack_t *stack;					/**< thread's stack start address */
	unsigned int stack_size;		/**< thread's stack size */
	unsigned int pid;				/**< thread's process id */
	enum thread_priority priority;	/**< thread's priority */
	enum thread_status status;		/**< thread's status */
	unsigned long next_executing_time;
	void *wakeup_blocking_source;
	struct queue_node sem_queue_node;
};
#pragma pack(pop)

struct kernel_version {
	unsigned int kernel_version;
	unsigned int major_version;
	unsigned int minor_version;
	unsigned int build_number;
};

int get_kernel_version(struct kernel_version *version);

struct thread_context *thread_create(
		struct thread_context *thread,
		stack_t *stack,
		unsigned int stack_size,
		void (*thread_func)(void *),
		void *arg,
		enum thread_priority priority);


void thread_exit(void);
void sleep_ms(unsigned int ms);

#endif /* SOURCE_FIRMWARE_KERNEL_INTERFACE_KERNEL_H_ */
