mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-17 05:13:15 +01:00
Merge remote-tracking branch 'kelvin_atomthreads/master'
Conflicts: tests/kern1.c tests/kern3.c tests/kern4.c tests/mutex1.c tests/mutex2.c tests/mutex3.c tests/mutex4.c tests/mutex5.c tests/mutex6.c tests/mutex7.c tests/mutex8.c tests/mutex9.c tests/queue2.c tests/queue3.c tests/queue5.c tests/queue6.c tests/queue7.c tests/queue9.c tests/sem1.c tests/sem3.c tests/sem4.c tests/sem5.c tests/sem6.c tests/sem7.c tests/sem8.c tests/sem9.c tests/timer2.c
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Library: Atomthreads
|
||||
Author: Kelvin Lawson <kelvinl@users.sf.net>
|
||||
Website: http://atomthreads.com
|
||||
License: BSD Revised
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Library: Atomthreads
|
||||
Author: Kelvin Lawson <info@atomthreads.com>
|
||||
Website: http://atomthreads.com
|
||||
License: BSD Revised
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
KERNEL SOURCES
|
||||
|
||||
@@ -21,12 +21,12 @@ Each module source file contains detailed documentation including an
|
||||
introduction to usage of the module and full descriptions of each API.
|
||||
Refer to the sources for further documentation.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
BUILDING THE KERNEL
|
||||
|
||||
The kernel is built from the architecture port folder. Build instructions
|
||||
are included in the README file for each port.
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
#ifndef __ATOM_H
|
||||
#define __ATOM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "atomtimer.h"
|
||||
#include "atomport.h"
|
||||
|
||||
@@ -62,7 +66,7 @@ typedef struct atom_tcb
|
||||
|
||||
/* Details used if thread stack-checking is required */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
POINTER stack_top; /* Pointer to top of stack allocation */
|
||||
POINTER stack_bottom; /* Pointer to bottom of stack allocation */
|
||||
uint32_t stack_size; /* Size of stack allocation in bytes */
|
||||
#endif
|
||||
|
||||
@@ -102,7 +106,7 @@ extern uint8_t atomOSStarted;
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
extern uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t stack_size);
|
||||
extern uint8_t atomOSInit (void *idle_thread_stack_bottom, uint32_t idle_thread_stack_size, uint8_t idle_thread_stack_check);
|
||||
extern void atomOSStart (void);
|
||||
|
||||
extern void atomSched (uint8_t timer_tick);
|
||||
@@ -117,7 +121,7 @@ extern ATOM_TCB *tcbDequeuePriority (ATOM_TCB **tcb_queue_ptr, uint8_t priority)
|
||||
|
||||
extern ATOM_TCB *atomCurrentContext (void);
|
||||
|
||||
extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size);
|
||||
extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check);
|
||||
extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes);
|
||||
|
||||
extern void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr);
|
||||
@@ -126,5 +130,8 @@ extern void archFirstThreadRestore(ATOM_TCB *new_tcb_ptr);
|
||||
|
||||
extern void atomTimerTick (void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ATOM_H */
|
||||
|
||||
@@ -144,7 +144,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include "atom.h"
|
||||
|
||||
|
||||
@@ -370,25 +369,31 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb)
|
||||
* new thread may be scheduled in before the function returns.
|
||||
*
|
||||
* Optionally prefills the thread stack with a known value to enable stack
|
||||
* usage checking (if the ATOM_STACK_CHECKING macro is defined).
|
||||
* usage checking (if the ATOM_STACK_CHECKING macro is defined and
|
||||
* stack_check parameter is set to TRUE).
|
||||
*
|
||||
* @param[in] tcb_ptr Pointer to the thread's TCB storage
|
||||
* @param[in] priority Priority of the thread (0 to 255)
|
||||
* @param[in] entry_point Thread entry point
|
||||
* @param[in] entry_param Parameter passed to thread entry point
|
||||
* @param[in] stack_top Top of the stack area
|
||||
* @param[in] stack_bottom Bottom of the stack area
|
||||
* @param[in] stack_size Size of the stack area in bytes
|
||||
* @param[in] stack_check TRUE to enable stack checking for this thread
|
||||
*
|
||||
* @retval ATOM_OK Success
|
||||
* @retval ATOM_ERR_PARAM Bad parameters
|
||||
* @retval ATOM_ERR_QUEUE Error putting the thread on the ready queue
|
||||
*/
|
||||
uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size)
|
||||
uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
uint8_t status;
|
||||
uint8_t *stack_top;
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
int32_t count;
|
||||
#endif
|
||||
|
||||
if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_top == NULL)
|
||||
if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_bottom == NULL)
|
||||
|| (stack_size == 0))
|
||||
{
|
||||
/* Bad parameters */
|
||||
@@ -412,6 +417,13 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin
|
||||
tcb_ptr->entry_point = entry_point;
|
||||
tcb_ptr->entry_param = entry_param;
|
||||
|
||||
/**
|
||||
* Calculate a pointer to the topmost stack entry, suitably aligned
|
||||
* for the architecture. This may discard the top few bytes if the
|
||||
* stack size is not a multiple of the stack entry/alignment size.
|
||||
*/
|
||||
stack_top = (uint8_t *)stack_bottom + (stack_size & ~(STACK_ALIGN_SIZE - 1)) - STACK_ALIGN_SIZE;
|
||||
|
||||
/**
|
||||
* Additional processing only required if stack-checking is
|
||||
* enabled. Incurs a slight overhead on each thread creation
|
||||
@@ -419,25 +431,29 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin
|
||||
* compiled out if not desired.
|
||||
*/
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
|
||||
/* Store the stack details for use by the stack-check function */
|
||||
tcb_ptr->stack_top = stack_top;
|
||||
tcb_ptr->stack_size = stack_size;
|
||||
|
||||
/**
|
||||
* Prefill the stack with a known value. This is used later in
|
||||
* calls to atomThreadStackCheck() to get an indication of how
|
||||
* much stack has been used during runtime.
|
||||
*/
|
||||
while (stack_size > 0)
|
||||
/* Set up stack-checking if enabled for this thread */
|
||||
if (stack_check)
|
||||
{
|
||||
/* Initialise all stack bytes from bottom up to 0x5A */
|
||||
*((uint8_t *)stack_top - (stack_size - 1)) = STACK_CHECK_BYTE;
|
||||
stack_size--;
|
||||
/* Store the stack details for use by the stack-check function */
|
||||
tcb_ptr->stack_bottom = stack_bottom;
|
||||
tcb_ptr->stack_size = stack_size;
|
||||
|
||||
/**
|
||||
* Prefill the stack with a known value. This is used later in
|
||||
* calls to atomThreadStackCheck() to get an indication of how
|
||||
* much stack has been used during runtime.
|
||||
*/
|
||||
count = (int32_t)stack_size;
|
||||
while (count > 0)
|
||||
{
|
||||
/* Initialise all stack bytes from top down to 0x5A */
|
||||
*((uint8_t *)stack_bottom + (count - 1)) = STACK_CHECK_BYTE;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Avoid compiler warnings due to unused stack_size variable */
|
||||
stack_size = stack_size;
|
||||
/* Avoid compiler warning due to unused parameter */
|
||||
stack_check = stack_check;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -529,10 +545,10 @@ uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Starting at the far end, count the unmodified areas until a
|
||||
* Starting at the bottom end, count the unmodified areas until a
|
||||
* modified byte is found.
|
||||
*/
|
||||
stack_ptr = (uint8_t *)tcb_ptr->stack_top - (tcb_ptr->stack_size - 1);
|
||||
stack_ptr = (uint8_t *)tcb_ptr->stack_bottom;
|
||||
for (i = 0; i < tcb_ptr->stack_size; i++)
|
||||
{
|
||||
/* Loop until a modified byte is found */
|
||||
@@ -648,13 +664,14 @@ ATOM_TCB *atomCurrentContext (void)
|
||||
* operating system facilities are being initialised. They are normally
|
||||
* enabled by the archFirstThreadRestore() routine in the architecture port.
|
||||
*
|
||||
* @param[in] idle_thread_stack_top Ptr to top of stack area for idle thread
|
||||
* @param[in] idle_thread_stack_bottom Ptr to bottom of stack for idle thread
|
||||
* @param[in] idle_thread_stack_size Size of idle thread stack in bytes
|
||||
* @param[in] idle_thread_stack_check TRUE if stack checking required on idle thread
|
||||
*
|
||||
* @retval ATOM_OK Success
|
||||
* @retval ATOM_ERROR Initialisation error
|
||||
*/
|
||||
uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size)
|
||||
uint8_t atomOSInit (void *idle_thread_stack_bottom, uint32_t idle_thread_stack_size, uint8_t idle_thread_stack_check)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
@@ -668,8 +685,9 @@ uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size
|
||||
IDLE_THREAD_PRIORITY,
|
||||
atomIdleThread,
|
||||
0,
|
||||
idle_thread_stack_top,
|
||||
idle_thread_stack_size);
|
||||
idle_thread_stack_bottom,
|
||||
idle_thread_stack_size,
|
||||
idle_thread_stack_check);
|
||||
|
||||
/* Return status */
|
||||
return (status);
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "atom.h"
|
||||
#include "atommutex.h"
|
||||
#include "atomtimer.h"
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#ifndef __ATOM_MUTEX_H
|
||||
#define __ATOM_MUTEX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct atom_mutex
|
||||
{
|
||||
ATOM_TCB * suspQ; /* Queue of threads suspended on this mutex */
|
||||
@@ -41,4 +45,8 @@ extern uint8_t atomMutexDelete (ATOM_MUTEX *mutex);
|
||||
extern uint8_t atomMutexGet (ATOM_MUTEX *mutex, int32_t timeout);
|
||||
extern uint8_t atomMutexPut (ATOM_MUTEX *mutex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ATOM_MUTEX_H */
|
||||
|
||||
@@ -34,6 +34,15 @@
|
||||
/* Required number of system ticks per second (normally 100 for 10ms tick) */
|
||||
#define SYSTEM_TICKS_PER_SEC 100
|
||||
|
||||
/**
|
||||
* Definition of NULL.
|
||||
* If stddef.h is available on the platform it is simplest to include it
|
||||
* from this header, otherwise define below.
|
||||
*/
|
||||
#define NULL ((void *)(0))
|
||||
|
||||
/* Size of each stack entry / stack alignment size (e.g. 8 bits) */
|
||||
#define STACK_ALIGN_SIZE sizeof(unsigned char)
|
||||
|
||||
/**
|
||||
* Architecture-specific types.
|
||||
@@ -51,7 +60,12 @@
|
||||
#define POINTER void *
|
||||
|
||||
|
||||
/* Critical region protection */
|
||||
/**
|
||||
* Critical region protection: this should disable interrupts
|
||||
* to protect OS data structures during modification. It must
|
||||
* allow nested calls, which means that interrupts should only
|
||||
* be re-enabled when the outer CRITICAL_END() is reached.
|
||||
*/
|
||||
#define CRITICAL_STORE uint8_t sreg
|
||||
#define CRITICAL_START() sreg = SREG; cli();
|
||||
#define CRITICAL_END() SREG = sreg
|
||||
|
||||
@@ -91,7 +91,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "atom.h"
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#ifndef __ATOM_QUEUE_H
|
||||
#define __ATOM_QUEUE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct atom_queue
|
||||
{
|
||||
ATOM_TCB * putSuspQ; /* Queue of threads waiting to send */
|
||||
@@ -46,4 +50,8 @@ extern uint8_t atomQueueDelete (ATOM_QUEUE *qptr);
|
||||
extern uint8_t atomQueueGet (ATOM_QUEUE *qptr, int32_t timeout, uint8_t *msgptr);
|
||||
extern uint8_t atomQueuePut (ATOM_QUEUE *qptr, int32_t timeout, uint8_t *msgptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ATOM_QUEUE_H */
|
||||
|
||||
@@ -88,7 +88,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "atom.h"
|
||||
#include "atomsem.h"
|
||||
#include "atomtimer.h"
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
#ifndef __ATOM_SEM_H
|
||||
#define __ATOM_SEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct atom_sem
|
||||
{
|
||||
ATOM_TCB * suspQ; /* Queue of threads suspended on this semaphore */
|
||||
@@ -42,4 +46,8 @@ extern uint8_t atomSemGet (ATOM_SEM *sem, int32_t timeout);
|
||||
extern uint8_t atomSemPut (ATOM_SEM *sem);
|
||||
extern uint8_t atomSemResetCount (ATOM_SEM *sem, uint8_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ATOM_SEM_H */
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "atom.h"
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@
|
||||
#ifndef __ATOM_TIMER_H
|
||||
#define __ATOM_TIMER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "atomport.h"
|
||||
|
||||
|
||||
@@ -58,4 +62,8 @@ extern uint8_t atomTimerDelay (uint32_t ticks);
|
||||
extern uint32_t atomTimeGet (void);
|
||||
extern void atomTimeSet (uint32_t new_time);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ATOM_TIMER_H */
|
||||
|
||||
Reference in New Issue
Block a user