Tree reorganization.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8899 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
5e24a813be
commit
641f2c3726
|
@ -1,6 +1,7 @@
|
|||
All the code contained under ./os/ext is not part of the ChibiOS project and
|
||||
supplied as-is without any additional warranty by ChibiOS. For ownership and
|
||||
copyright statements see the license details inside the code.
|
||||
All the code contained under ./os/common/ext is not part of the ChibiOS
|
||||
project and supplied as-is without any additional warranty by ChibiOS.
|
||||
For ownership and copyright statements see the license details inside the
|
||||
code.
|
||||
|
||||
Some modules may contain changes from the ChibiOS team in order to increase
|
||||
compatibility or usability with ChibiOS itself.
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chbsem.h
|
||||
* @brief Binary semaphores structures and macros.
|
||||
*
|
||||
* @addtogroup binary_semaphores
|
||||
* @details Binary semaphores related APIs and services.
|
||||
* <h2>Operation mode</h2>
|
||||
* Binary semaphores are implemented as a set of inline functions
|
||||
* that use the existing counting semaphores primitives. The
|
||||
* difference between counting and binary semaphores is that the
|
||||
* counter of binary semaphores is not allowed to grow above the
|
||||
* value 1. Repeated signal operation are ignored. A binary
|
||||
* semaphore can thus have only two defined states:
|
||||
* - <b>Taken</b>, when its counter has a value of zero or lower
|
||||
* than zero. A negative number represent the number of threads
|
||||
* queued on the binary semaphore.
|
||||
* - <b>Not taken</b>, when its counter has a value of one.
|
||||
* .
|
||||
* Binary semaphores are different from mutexes because there is no
|
||||
* concept of ownership, a binary semaphore can be taken by a
|
||||
* thread and signaled by another thread or an interrupt handler,
|
||||
* mutexes can only be taken and released by the same thread. Another
|
||||
* difference is that binary semaphores, unlike mutexes, do not
|
||||
* implement the priority inheritance protocol.<br>
|
||||
* In order to use the binary semaphores APIs the
|
||||
* @p CH_CFG_USE_SEMAPHORES option must be enabled in @p chconf.h.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHBSEM_H_
|
||||
#define _CHBSEM_H_
|
||||
|
||||
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @extends semaphore_t
|
||||
*
|
||||
* @brief Binary semaphore type.
|
||||
*/
|
||||
typedef struct {
|
||||
semaphore_t sem;
|
||||
} binary_semaphore_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Data part of a static semaphore initializer.
|
||||
* @details This macro should be used when statically initializing a semaphore
|
||||
* that is part of a bigger structure.
|
||||
*
|
||||
* @param[in] name the name of the semaphore variable
|
||||
* @param[in] taken the semaphore initial state
|
||||
*/
|
||||
#define _BSEMAPHORE_DATA(name, taken) \
|
||||
{_SEMAPHORE_DATA(name.sem, ((taken) ? 0 : 1))}
|
||||
|
||||
/**
|
||||
* @brief Static semaphore initializer.
|
||||
* @details Statically initialized semaphores require no explicit
|
||||
* initialization using @p chBSemInit().
|
||||
*
|
||||
* @param[in] name the name of the semaphore variable
|
||||
* @param[in] taken the semaphore initial state
|
||||
*/
|
||||
#define BSEMAPHORE_DECL(name, taken) \
|
||||
binary_semaphore_t name = _BSEMAPHORE_DATA(name, taken)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes a binary semaphore.
|
||||
*
|
||||
* @param[out] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @param[in] taken initial state of the binary semaphore:
|
||||
* - @a false, the initial state is not taken.
|
||||
* - @a true, the initial state is taken.
|
||||
* .
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
static inline void chBSemObjectInit(binary_semaphore_t *bsp, bool taken) {
|
||||
|
||||
chSemObjectInit(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval MSG_OK if the binary semaphore has been successfully taken.
|
||||
* @retval MSG_RESET if the binary semaphore has been reset using
|
||||
* @p bsemReset().
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline msg_t chBSemWait(binary_semaphore_t *bsp) {
|
||||
|
||||
return chSemWait(&bsp->sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval MSG_OK if the binary semaphore has been successfully taken.
|
||||
* @retval MSG_RESET if the binary semaphore has been reset using
|
||||
* @p bsemReset().
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
static inline msg_t chBSemWaitS(binary_semaphore_t *bsp) {
|
||||
|
||||
chDbgCheckClassS();
|
||||
|
||||
return chSemWaitS(&bsp->sem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval MSG_OK if the binary semaphore has been successfully taken.
|
||||
* @retval MSG_RESET if the binary semaphore has been reset using
|
||||
* @p bsemReset().
|
||||
* @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
|
||||
* within the specified timeout.
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
static inline msg_t chBSemWaitTimeoutS(binary_semaphore_t *bsp,
|
||||
systime_t time) {
|
||||
|
||||
chDbgCheckClassS();
|
||||
|
||||
return chSemWaitTimeoutS(&bsp->sem, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait operation on the binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return A message specifying how the invoking thread has been
|
||||
* released from the semaphore.
|
||||
* @retval MSG_OK if the binary semaphore has been successfully taken.
|
||||
* @retval MSG_RESET if the binary semaphore has been reset using
|
||||
* @p bsemReset().
|
||||
* @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
|
||||
* within the specified timeout.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline msg_t chBSemWaitTimeout(binary_semaphore_t *bsp,
|
||||
systime_t time) {
|
||||
|
||||
return chSemWaitTimeout(&bsp->sem, time);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset operation on the binary semaphore.
|
||||
* @note The released threads can recognize they were waked up by a reset
|
||||
* rather than a signal because the @p bsemWait() will return
|
||||
* @p MSG_RESET instead of @p MSG_OK.
|
||||
* @note This function does not reschedule.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @param[in] taken new state of the binary semaphore
|
||||
* - @a false, the new state is not taken.
|
||||
* - @a true, the new state is taken.
|
||||
* .
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void chBSemResetI(binary_semaphore_t *bsp, bool taken) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
chSemResetI(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset operation on the binary semaphore.
|
||||
* @note The released threads can recognize they were waked up by a reset
|
||||
* rather than a signal because the @p bsemWait() will return
|
||||
* @p MSG_RESET instead of @p MSG_OK.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @param[in] taken new state of the binary semaphore
|
||||
* - @a false, the new state is not taken.
|
||||
* - @a true, the new state is taken.
|
||||
* .
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chBSemReset(binary_semaphore_t *bsp, bool taken) {
|
||||
|
||||
chSemReset(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs a signal operation on a binary semaphore.
|
||||
* @note This function does not reschedule.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void chBSemSignalI(binary_semaphore_t *bsp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
if (bsp->sem.cnt < (cnt_t)1) {
|
||||
chSemSignalI(&bsp->sem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs a signal operation on a binary semaphore.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chBSemSignal(binary_semaphore_t *bsp) {
|
||||
|
||||
chSysLock();
|
||||
chBSemSignalI(bsp);
|
||||
chSchRescheduleS();
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the binary semaphore current state.
|
||||
*
|
||||
* @param[in] bsp pointer to a @p binary_semaphore_t structure
|
||||
* @return The binary semaphore current state.
|
||||
* @retval false if the binary semaphore is not taken.
|
||||
* @retval true if the binary semaphore is taken.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline bool chBSemGetStateI(binary_semaphore_t *bsp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
return (bsp->sem.cnt > (cnt_t)0) ? false : true;
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
|
||||
|
||||
#endif /* _CHBSEM_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chdynamic.h
|
||||
* @brief Dynamic threads macros and structures.
|
||||
*
|
||||
* @addtogroup dynamic_threads
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHDYNAMIC_H_
|
||||
#define _CHDYNAMIC_H_
|
||||
|
||||
#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Module dependencies check.
|
||||
*/
|
||||
#if CH_CFG_USE_WAITEXIT == FALSE
|
||||
#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_WAITEXIT"
|
||||
#endif
|
||||
|
||||
#if (CH_CFG_USE_HEAP == FALSE) && (CH_CFG_USE_MEMPOOLS == FALSE)
|
||||
#error "CH_CFG_USE_DYNAMIC requires CH_CFG_USE_HEAP and/or CH_CFG_USE_MEMPOOLS"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Dynamic threads APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if CH_CFG_USE_HEAP == TRUE
|
||||
thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
|
||||
tprio_t prio, tfunc_t pf, void *arg);
|
||||
#endif
|
||||
#if CH_CFG_USE_MEMPOOLS == TRUE
|
||||
thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, tprio_t prio,
|
||||
tfunc_t pf, void *arg);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#endif /* CH_CFG_USE_DYNAMIC == TRUE */
|
||||
|
||||
#endif /* _CHDYNAMIC_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chheap.h
|
||||
* @brief Heaps macros and structures.
|
||||
*
|
||||
* @addtogroup heaps
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHHEAP_H_
|
||||
#define _CHHEAP_H_
|
||||
|
||||
#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Minimum alignment used for heap.
|
||||
*/
|
||||
#define CH_HEAP_ALIGNMENT sizeof (heap_header_t)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_CFG_USE_MEMCORE == FALSE
|
||||
#error "CH_CFG_USE_HEAP requires CH_CFG_USE_MEMCORE"
|
||||
#endif
|
||||
|
||||
#if (CH_CFG_USE_MUTEXES == FALSE) && (CH_CFG_USE_SEMAPHORES == FALSE)
|
||||
#error "CH_CFG_USE_HEAP requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a memory heap.
|
||||
*/
|
||||
typedef struct memory_heap memory_heap_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a memory heap header.
|
||||
*/
|
||||
typedef union heap_header heap_header_t;
|
||||
|
||||
/**
|
||||
* @brief Memory heap block header.
|
||||
*/
|
||||
union heap_header {
|
||||
stkalign_t align;
|
||||
struct {
|
||||
heap_header_t *next; /**< @brief Next block in free list. */
|
||||
size_t pages; /**< @brief Size of the area in pages. */
|
||||
} free;
|
||||
struct {
|
||||
memory_heap_t *heap; /**< @brief Block owner heap. */
|
||||
size_t size; /**< @brief Size of the area in bytes. */
|
||||
} used;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Structure describing a memory heap.
|
||||
*/
|
||||
struct memory_heap {
|
||||
memgetfunc_t provider; /**< @brief Memory blocks provider for
|
||||
this heap. */
|
||||
heap_header_t header; /**< @brief Free blocks list header. */
|
||||
#if CH_CFG_USE_MUTEXES == TRUE
|
||||
mutex_t mtx; /**< @brief Heap access mutex. */
|
||||
#else
|
||||
semaphore_t sem; /**< @brief Heap access semaphore. */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _heap_init(void);
|
||||
void chHeapObjectInit(memory_heap_t *heapp, void *buf, size_t size);
|
||||
void *chHeapAllocAligned(memory_heap_t *heapp, size_t size, unsigned align);
|
||||
void chHeapFree(void *p);
|
||||
size_t chHeapStatus(memory_heap_t *heapp, size_t *totalp, size_t *largestp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Allocates a block of memory from the heap by using the first-fit
|
||||
* algorithm.
|
||||
* @details The allocated block is guaranteed to be properly aligned for a
|
||||
* pointer data type.
|
||||
*
|
||||
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to
|
||||
* access the default heap.
|
||||
* @param[in] size the size of the block to be allocated. Note that the
|
||||
* allocated block may be a bit bigger than the requested
|
||||
* size for alignment and fragmentation reasons.
|
||||
* @return A pointer to the allocated block.
|
||||
* @retval NULL if the block cannot be allocated.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void *chHeapAlloc(memory_heap_t *heapp, size_t size) {
|
||||
|
||||
return chHeapAllocAligned(heapp, size, CH_HEAP_ALIGNMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the size of an allocated block.
|
||||
* @note The returned value is the requested size, the real size is the
|
||||
* same value aligned to the next @p CH_HEAP_ALIGNMENT multiple.
|
||||
*
|
||||
* @param[in] p pointer to the memory block
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline size_t chHeapGetSize(const void *p) {
|
||||
|
||||
return ((heap_header_t *)p)->used.size;
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_HEAP == TRUE */
|
||||
|
||||
#endif /* _CHHEAP_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmboxes.h
|
||||
* @brief Mailboxes macros and structures.
|
||||
*
|
||||
* @addtogroup mailboxes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMBOXES_H_
|
||||
#define _CHMBOXES_H_
|
||||
|
||||
#if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_CFG_USE_SEMAPHORES == FALSE
|
||||
#error "CH_CFG_USE_MAILBOXES requires CH_CFG_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Structure representing a mailbox object.
|
||||
*/
|
||||
typedef struct {
|
||||
msg_t *buffer; /**< @brief Pointer to the mailbox
|
||||
buffer. */
|
||||
msg_t *top; /**< @brief Pointer to the location
|
||||
after the buffer. */
|
||||
msg_t *wrptr; /**< @brief Write pointer. */
|
||||
msg_t *rdptr; /**< @brief Read pointer. */
|
||||
semaphore_t fullsem; /**< @brief Full counter
|
||||
@p semaphore_t. */
|
||||
semaphore_t emptysem; /**< @brief Empty counter
|
||||
@p semaphore_t. */
|
||||
} mailbox_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Data part of a static mailbox initializer.
|
||||
* @details This macro should be used when statically initializing a
|
||||
* mailbox that is part of a bigger structure.
|
||||
*
|
||||
* @param[in] name the name of the mailbox variable
|
||||
* @param[in] buffer pointer to the mailbox buffer area
|
||||
* @param[in] size size of the mailbox buffer area
|
||||
*/
|
||||
#define _MAILBOX_DATA(name, buffer, size) { \
|
||||
(msg_t *)(buffer), \
|
||||
(msg_t *)(buffer) + size, \
|
||||
(msg_t *)(buffer), \
|
||||
(msg_t *)(buffer), \
|
||||
_SEMAPHORE_DATA(name.fullsem, 0), \
|
||||
_SEMAPHORE_DATA(name.emptysem, size), \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Static mailbox initializer.
|
||||
* @details Statically initialized mailboxes require no explicit
|
||||
* initialization using @p chMBInit().
|
||||
*
|
||||
* @param[in] name the name of the mailbox variable
|
||||
* @param[in] buffer pointer to the mailbox buffer area
|
||||
* @param[in] size size of the mailbox buffer area
|
||||
*/
|
||||
#define MAILBOX_DECL(name, buffer, size) \
|
||||
mailbox_t name = _MAILBOX_DATA(name, buffer, size)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chMBObjectInit(mailbox_t *mbp, msg_t *buf, cnt_t n);
|
||||
void chMBReset(mailbox_t *mbp);
|
||||
void chMBResetI(mailbox_t *mbp);
|
||||
msg_t chMBPost(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostI(mailbox_t *mbp, msg_t msg);
|
||||
msg_t chMBPostAhead(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t timeout);
|
||||
msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg);
|
||||
msg_t chMBFetch(mailbox_t *mbp, msg_t *msgp, systime_t timeout);
|
||||
msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t timeout);
|
||||
msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Returns the mailbox buffer size.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||
* @return The size of the mailbox.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline size_t chMBGetSizeI(mailbox_t *mbp) {
|
||||
|
||||
/*lint -save -e9033 [10.8] Perfectly safe pointers
|
||||
arithmetic.*/
|
||||
return (size_t)(mbp->top - mbp->buffer);
|
||||
/*lint -restore*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of free message slots into a mailbox.
|
||||
* @note Can be invoked in any system state but if invoked out of a locked
|
||||
* state then the returned value may change after reading.
|
||||
* @note The returned value can be less than zero when there are waiting
|
||||
* threads on the internal semaphore.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||
* @return The number of empty message slots.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline cnt_t chMBGetFreeCountI(mailbox_t *mbp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
return chSemGetCounterI(&mbp->emptysem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of used message slots into a mailbox.
|
||||
* @note Can be invoked in any system state but if invoked out of a locked
|
||||
* state then the returned value may change after reading.
|
||||
* @note The returned value can be less than zero when there are waiting
|
||||
* threads on the internal semaphore.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||
* @return The number of queued messages.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline cnt_t chMBGetUsedCountI(mailbox_t *mbp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
return chSemGetCounterI(&mbp->fullsem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the next message in the queue without removing it.
|
||||
* @pre A message must be waiting in the queue for this function to work
|
||||
* or it would return garbage. The correct way to use this macro is
|
||||
* to use @p chMBGetFullCountI() and then use this macro, all within
|
||||
* a lock state.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized mailbox_t object
|
||||
* @return The next message in queue.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline msg_t chMBPeekI(mailbox_t *mbp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
return *mbp->rdptr;
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_MAILBOXES == TRUE */
|
||||
|
||||
#endif /* _CHMBOXES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmemcore.h
|
||||
* @brief Core memory manager macros and structures.
|
||||
*
|
||||
* @addtogroup memcore
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMEMCORE_H_
|
||||
#define _CHMEMCORE_H_
|
||||
|
||||
#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Managed RAM size.
|
||||
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||
* then the whole available RAM is used. The core memory is made
|
||||
* available to the heap allocator and/or can be used directly through
|
||||
* the simplified core memory allocator.
|
||||
*
|
||||
* @note In order to let the OS manage the whole RAM the linker script must
|
||||
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||
* @note Requires @p CH_CFG_USE_MEMCORE.
|
||||
*/
|
||||
#define CH_CFG_MEMCORE_SIZE 0
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_CFG_MEMCORE_SIZE < 0
|
||||
#error "invalid CH_CFG_MEMCORE_SIZE value specified"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Memory get function.
|
||||
*/
|
||||
typedef void *(*memgetfunc_t)(size_t size, unsigned align);
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _core_init(void);
|
||||
void *chCoreAllocAlignedI(size_t size, unsigned align);
|
||||
void *chCoreAllocAligned(size_t size, unsigned align);
|
||||
size_t chCoreGetStatusX(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned for a
|
||||
* pointer data type.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @return A pointer to the allocated memory block.
|
||||
* @retval NULL allocation failed, core memory exhausted.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void *chCoreAllocI(size_t size) {
|
||||
|
||||
return chCoreAllocAlignedI(size, PORT_NATURAL_ALIGN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned for a
|
||||
* pointer data type.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @return A pointer to the allocated memory block.
|
||||
* @retval NULL allocation failed, core memory exhausted.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void *chCoreAlloc(size_t size) {
|
||||
|
||||
return chCoreAllocAligned(size, PORT_NATURAL_ALIGN);
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_MEMCORE == TRUE */
|
||||
|
||||
#endif /* _CHMEMCORE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmempools.h
|
||||
* @brief Memory Pools macros and structures.
|
||||
*
|
||||
* @addtogroup pools
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHMEMPOOLS_H_
|
||||
#define _CHMEMPOOLS_H_
|
||||
|
||||
#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_CFG_USE_MEMCORE == FALSE
|
||||
#error "CH_CFG_USE_MEMPOOLS requires CH_CFG_USE_MEMCORE"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Memory pool free object header.
|
||||
*/
|
||||
struct pool_header {
|
||||
struct pool_header *next; /**< @brief Pointer to the next pool
|
||||
header in the list. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Memory pool descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
struct pool_header *next; /**< @brief Pointer to the header. */
|
||||
size_t object_size; /**< @brief Memory pool objects
|
||||
size. */
|
||||
memgetfunc_t provider; /**< @brief Memory blocks provider
|
||||
for this pool. */
|
||||
} memory_pool_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Data part of a static memory pool initializer.
|
||||
* @details This macro should be used when statically initializing a
|
||||
* memory pool that is part of a bigger structure.
|
||||
*
|
||||
* @param[in] name the name of the memory pool variable
|
||||
* @param[in] size size of the memory pool contained objects
|
||||
* @param[in] provider memory provider function for the memory pool
|
||||
*/
|
||||
#define _MEMORYPOOL_DATA(name, size, provider) \
|
||||
{NULL, size, provider}
|
||||
|
||||
/**
|
||||
* @brief Static memory pool initializer in hungry mode.
|
||||
* @details Statically initialized memory pools require no explicit
|
||||
* initialization using @p chPoolInit().
|
||||
*
|
||||
* @param[in] name the name of the memory pool variable
|
||||
* @param[in] size size of the memory pool contained objects
|
||||
* @param[in] provider memory provider function for the memory pool or @p NULL
|
||||
* if the pool is not allowed to grow automatically
|
||||
*/
|
||||
#define MEMORYPOOL_DECL(name, size, provider) \
|
||||
memory_pool_t name = _MEMORYPOOL_DATA(name, size, provider)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chPoolObjectInit(memory_pool_t *mp, size_t size, memgetfunc_t provider);
|
||||
void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n);
|
||||
void *chPoolAllocI(memory_pool_t *mp);
|
||||
void *chPoolAlloc(memory_pool_t *mp);
|
||||
void chPoolFreeI(memory_pool_t *mp, void *objp);
|
||||
void chPoolFree(memory_pool_t *mp, void *objp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Adds an object to a memory pool.
|
||||
* @pre The memory pool must be already been initialized.
|
||||
* @pre The added object must be of the right size for the specified
|
||||
* memory pool.
|
||||
* @pre The added object must be memory aligned to the size of
|
||||
* @p stkalign_t type.
|
||||
* @note This function is just an alias for @p chPoolFree() and has been
|
||||
* added for clarity.
|
||||
*
|
||||
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||
* @param[in] objp the pointer to the object to be added
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chPoolAdd(memory_pool_t *mp, void *objp) {
|
||||
|
||||
chPoolFree(mp, objp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds an object to a memory pool.
|
||||
* @pre The memory pool must be already been initialized.
|
||||
* @pre The added object must be of the right size for the specified
|
||||
* memory pool.
|
||||
* @pre The added object must be memory aligned to the size of
|
||||
* @p stkalign_t type.
|
||||
* @note This function is just an alias for @p chPoolFree() and has been
|
||||
* added for clarity.
|
||||
*
|
||||
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||
* @param[in] objp the pointer to the object to be added
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void chPoolAddI(memory_pool_t *mp, void *objp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
chPoolFreeI(mp, objp);
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
|
||||
|
||||
#endif /* _CHMEMPOOLS_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,3 @@
|
|||
All the code contained under ./os/common/oslib are optional RTOS modules
|
||||
compatible with both RT and NIL. The code is placed under ./os/common in
|
||||
order to prevent code duplication and disalignments.
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chdynamic.c
|
||||
* @brief Dynamic threads code.
|
||||
*
|
||||
* @addtogroup dynamic_threads
|
||||
* @details Dynamic threads related APIs and services.
|
||||
* @note Compatible with RT only.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if (CH_CFG_USE_DYNAMIC == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Creates a new thread allocating the memory from the heap.
|
||||
* @pre The configuration options @p CH_CFG_USE_DYNAMIC and
|
||||
* @p CH_CFG_USE_HEAP must be enabled in order to use this function.
|
||||
* @note A thread can terminate by calling @p chThdExit() or by simply
|
||||
* returning from its main function.
|
||||
* @note The memory allocated for the thread is not released automatically,
|
||||
* it is responsibility of the creator thread to call @p chThdWait()
|
||||
* and then release the allocated memory.
|
||||
*
|
||||
* @param[in] heapp heap from which allocate the memory or @p NULL for the
|
||||
* default heap
|
||||
* @param[in] size size of the working area to be allocated
|
||||
* @param[in] prio the priority level for the new thread
|
||||
* @param[in] pf the thread function
|
||||
* @param[in] arg an argument passed to the thread function. It can be
|
||||
* @p NULL.
|
||||
* @return The pointer to the @p thread_t structure allocated for
|
||||
* the thread into the working space area.
|
||||
* @retval NULL if the memory cannot be allocated.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
thread_t *chThdCreateFromHeap(memory_heap_t *heapp, size_t size,
|
||||
tprio_t prio, tfunc_t pf, void *arg) {
|
||||
void *wsp;
|
||||
|
||||
wsp = chHeapAllocAligned(heapp, size, PORT_WORKING_AREA_ALIGN);
|
||||
if (wsp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if CH_DBG_FILL_THREADS == TRUE
|
||||
_thread_memfill((uint8_t *)wsp,
|
||||
(uint8_t *)wsp + size,
|
||||
CH_DBG_STACK_FILL_VALUE);
|
||||
#endif
|
||||
|
||||
return chThdCreateStatic(wsp, size, prio, pf, arg);
|
||||
}
|
||||
#endif /* CH_CFG_USE_HEAP == TRUE */
|
||||
|
||||
#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Creates a new thread allocating the memory from the specified
|
||||
* memory pool.
|
||||
* @pre The configuration options @p CH_CFG_USE_DYNAMIC and
|
||||
* @p CH_CFG_USE_MEMPOOLS must be enabled in order to use this
|
||||
* function.
|
||||
* @pre The pool must be initialized to contain only objects with
|
||||
* alignment @p PORT_WORKING_AREA_ALIGN.
|
||||
* @note A thread can terminate by calling @p chThdExit() or by simply
|
||||
* returning from its main function.
|
||||
* @note The memory allocated for the thread is not released automatically,
|
||||
* it is responsibility of the creator thread to call @p chThdWait()
|
||||
* and then release the allocated memory.
|
||||
*
|
||||
* @param[in] mp pointer to the memory pool object
|
||||
* @param[in] prio the priority level for the new thread
|
||||
* @param[in] pf the thread function
|
||||
* @param[in] arg an argument passed to the thread function. It can be
|
||||
* @p NULL.
|
||||
* @return The pointer to the @p thread_t structure allocated for
|
||||
* the thread into the working space area.
|
||||
* @retval NULL if the memory pool is empty.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
thread_t *chThdCreateFromMemoryPool(memory_pool_t *mp, tprio_t prio,
|
||||
tfunc_t pf, void *arg) {
|
||||
void *wsp;
|
||||
|
||||
chDbgCheck(mp != NULL);
|
||||
|
||||
wsp = chPoolAlloc(mp);
|
||||
if (wsp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if CH_DBG_FILL_THREADS == TRUE
|
||||
_thread_memfill((uint8_t *)wsp,
|
||||
(uint8_t *)wsp + mp->object_size,
|
||||
CH_DBG_STACK_FILL_VALUE);
|
||||
#endif
|
||||
|
||||
return chThdCreateStatic(wsp, mp->object_size, prio, pf, arg);
|
||||
}
|
||||
#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
|
||||
|
||||
#endif /* CH_CFG_USE_DYNAMIC == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chheap.c
|
||||
* @brief Heaps code.
|
||||
*
|
||||
* @addtogroup heaps
|
||||
* @details Heap Allocator related APIs.
|
||||
* <h2>Operation mode</h2>
|
||||
* The heap allocator implements a first-fit strategy and its APIs
|
||||
* are functionally equivalent to the usual @p malloc() and @p free()
|
||||
* library functions. The main difference is that the OS heap APIs
|
||||
* are guaranteed to be thread safe and there is the ability to
|
||||
* return memory blocks aligned to arbitrary powers of two.<br>
|
||||
* @pre In order to use the heap APIs the @p CH_CFG_USE_HEAP option must
|
||||
* be enabled in @p chconf.h.
|
||||
* @note Compatible with RT and NIL.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Defaults on the best synchronization mechanism available.
|
||||
*/
|
||||
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
|
||||
#define H_LOCK(h) chMtxLock(&(h)->mtx)
|
||||
#define H_UNLOCK(h) chMtxUnlock(&(h)->mtx)
|
||||
#else
|
||||
#define H_LOCK(h) (void) chSemWait(&(h)->sem)
|
||||
#define H_UNLOCK(h) chSemSignal(&(h)->sem)
|
||||
#endif
|
||||
|
||||
#define H_BLOCK(hp) ((hp) + 1U)
|
||||
|
||||
#define H_LIMIT(hp) (H_BLOCK(hp) + H_PAGES(hp))
|
||||
|
||||
#define H_NEXT(hp) ((hp)->free.next)
|
||||
|
||||
#define H_PAGES(hp) ((hp)->free.pages)
|
||||
|
||||
#define H_HEAP(hp) ((hp)->used.heap)
|
||||
|
||||
#define H_SIZE(hp) ((hp)->used.size)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Default heap descriptor.
|
||||
*/
|
||||
static memory_heap_t default_heap;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the default heap.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _heap_init(void) {
|
||||
|
||||
default_heap.provider = chCoreAllocAligned;
|
||||
H_NEXT(&default_heap.header) = NULL;
|
||||
H_PAGES(&default_heap.header) = 0;
|
||||
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
|
||||
chMtxObjectInit(&default_heap.mtx);
|
||||
#else
|
||||
chSemObjectInit(&default_heap.sem, (cnt_t)1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes a memory heap from a static memory area.
|
||||
* @pre Both the heap buffer base and the heap size must be aligned to
|
||||
* the @p heap_header_t type size.
|
||||
*
|
||||
* @param[out] heapp pointer to the memory heap descriptor to be initialized
|
||||
* @param[in] buf heap buffer base
|
||||
* @param[in] size heap size
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
void chHeapObjectInit(memory_heap_t *heapp, void *buf, size_t size) {
|
||||
heap_header_t *hp = buf;
|
||||
|
||||
chDbgCheck((heapp != NULL) && (size > 0U) &&
|
||||
MEM_IS_ALIGNED(buf, CH_HEAP_ALIGNMENT) &&
|
||||
MEM_IS_ALIGNED(size, CH_HEAP_ALIGNMENT));
|
||||
|
||||
heapp->provider = NULL;
|
||||
H_NEXT(&heapp->header) = hp;
|
||||
H_PAGES(&heapp->header) = 0;
|
||||
H_NEXT(hp) = NULL;
|
||||
H_PAGES(hp) = (size - sizeof (heap_header_t)) / CH_HEAP_ALIGNMENT;
|
||||
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
|
||||
chMtxObjectInit(&heapp->mtx);
|
||||
#else
|
||||
chSemObjectInit(&heapp->sem, (cnt_t)1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a block of memory from the heap by using the first-fit
|
||||
* algorithm.
|
||||
* @details The allocated block is guaranteed to be properly aligned to the
|
||||
* specified alignment.
|
||||
*
|
||||
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to
|
||||
* access the default heap.
|
||||
* @param[in] size the size of the block to be allocated. Note that the
|
||||
* allocated block may be a bit bigger than the requested
|
||||
* size for alignment and fragmentation reasons.
|
||||
* @param[in] align desired memory alignment
|
||||
* @return A pointer to the aligned allocated block.
|
||||
* @retval NULL if the block cannot be allocated.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void *chHeapAllocAligned(memory_heap_t *heapp, size_t size, unsigned align) {
|
||||
heap_header_t *qp, *hp;
|
||||
size_t pages;
|
||||
|
||||
chDbgCheck((size > 0U) && MEM_IS_VALID_ALIGNMENT(align));
|
||||
|
||||
/* If an heap is not specified then the default system header is used.*/
|
||||
if (heapp == NULL) {
|
||||
heapp = &default_heap;
|
||||
}
|
||||
|
||||
/* Minimum alignment is constrained by the heap header structure size.*/
|
||||
if (align < CH_HEAP_ALIGNMENT) {
|
||||
align = CH_HEAP_ALIGNMENT;
|
||||
}
|
||||
|
||||
/* Size is converted in number of elementary allocation units.*/
|
||||
pages = MEM_ALIGN_NEXT(size, CH_HEAP_ALIGNMENT) / CH_HEAP_ALIGNMENT;
|
||||
|
||||
/* Taking heap mutex/semaphore.*/
|
||||
H_LOCK(heapp);
|
||||
|
||||
/* Start of the free blocks list.*/
|
||||
qp = &heapp->header;
|
||||
while (H_NEXT(qp) != NULL) {
|
||||
heap_header_t *ahp;
|
||||
|
||||
/* Next free block.*/
|
||||
hp = H_NEXT(qp);
|
||||
|
||||
/* Pointer aligned to the requested alignment.*/
|
||||
ahp = (heap_header_t *)MEM_ALIGN_NEXT(H_BLOCK(hp), align) - 1U;
|
||||
|
||||
if ((ahp < H_LIMIT(hp)) && (pages <= (size_t)(H_LIMIT(hp) - 1U - ahp))) {
|
||||
/* The block is large enough to contain a correctly aligned area
|
||||
of sufficient size.*/
|
||||
|
||||
if (ahp > hp) {
|
||||
/* The block is not properly aligned, must split it.*/
|
||||
size_t bpages;
|
||||
|
||||
bpages = H_LIMIT(hp) - H_BLOCK(ahp);
|
||||
H_PAGES(hp) = ahp - H_BLOCK(hp);
|
||||
if (bpages > pages) {
|
||||
/* The block is bigger than required, must split the excess.*/
|
||||
heap_header_t *fp;
|
||||
|
||||
/* Creating the excess block.*/
|
||||
fp = H_BLOCK(ahp) + pages;
|
||||
H_PAGES(fp) = bpages - pages - 1U;
|
||||
|
||||
/* Linking the excess block.*/
|
||||
H_NEXT(fp) = H_NEXT(hp);
|
||||
H_NEXT(hp) = fp;
|
||||
}
|
||||
|
||||
hp = ahp;
|
||||
}
|
||||
else {
|
||||
/* The block is already properly aligned.*/
|
||||
|
||||
if (H_PAGES(hp) == pages) {
|
||||
/* Exact size, getting the whole block.*/
|
||||
H_NEXT(qp) = H_NEXT(hp);
|
||||
}
|
||||
else {
|
||||
/* The block is bigger than required, must split the excess.*/
|
||||
heap_header_t *fp;
|
||||
|
||||
fp = H_BLOCK(hp) + pages;
|
||||
H_NEXT(fp) = H_NEXT(hp);
|
||||
H_PAGES(fp) = H_LIMIT(hp) - H_BLOCK(fp);
|
||||
H_NEXT(qp) = fp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setting in the block owner heap and size.*/
|
||||
H_SIZE(hp) = size;
|
||||
H_HEAP(hp) = heapp;
|
||||
|
||||
/* Releasing heap mutex/semaphore.*/
|
||||
H_UNLOCK(heapp);
|
||||
|
||||
/*lint -save -e9087 [11.3] Safe cast.*/
|
||||
return (void *)H_BLOCK(hp);
|
||||
/*lint -restore*/
|
||||
}
|
||||
|
||||
/* Next in the free blocks list.*/
|
||||
qp = hp;
|
||||
}
|
||||
|
||||
/* Releasing heap mutex/semaphore.*/
|
||||
H_UNLOCK(heapp);
|
||||
|
||||
/* More memory is required, tries to get it from the associated provider
|
||||
else fails.*/
|
||||
if (heapp->provider != NULL) {
|
||||
hp = heapp->provider((pages + 1U) * CH_HEAP_ALIGNMENT, align);
|
||||
if (hp != NULL) {
|
||||
H_HEAP(hp) = heapp;
|
||||
H_SIZE(hp) = size;
|
||||
|
||||
/*lint -save -e9087 [11.3] Safe cast.*/
|
||||
return (void *)H_BLOCK(hp);
|
||||
/*lint -restore*/
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees a previously allocated memory block.
|
||||
*
|
||||
* @param[in] p pointer to the memory block to be freed
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chHeapFree(void *p) {
|
||||
heap_header_t *qp, *hp;
|
||||
memory_heap_t *heapp;
|
||||
|
||||
chDbgCheck((p != NULL) && MEM_IS_ALIGNED(p, CH_HEAP_ALIGNMENT));
|
||||
|
||||
/*lint -save -e9087 [11.3] Safe cast.*/
|
||||
hp = (heap_header_t *)p - 1U;
|
||||
/*lint -restore*/
|
||||
heapp = H_HEAP(hp);
|
||||
qp = &heapp->header;
|
||||
|
||||
/* Size is converted in number of elementary allocation units.*/
|
||||
H_PAGES(hp) = MEM_ALIGN_NEXT(H_SIZE(hp),
|
||||
CH_HEAP_ALIGNMENT) / CH_HEAP_ALIGNMENT;
|
||||
|
||||
/* Taking heap mutex/semaphore.*/
|
||||
H_LOCK(heapp);
|
||||
|
||||
while (true) {
|
||||
chDbgAssert((hp < qp) || (hp >= H_LIMIT(qp)), "within free block");
|
||||
|
||||
if (((qp == &heapp->header) || (hp > qp)) &&
|
||||
((H_NEXT(qp) == NULL) || (hp < H_NEXT(qp)))) {
|
||||
/* Insertion after qp.*/
|
||||
H_NEXT(hp) = H_NEXT(qp);
|
||||
H_NEXT(qp) = hp;
|
||||
/* Verifies if the newly inserted block should be merged.*/
|
||||
if (H_LIMIT(hp) == H_NEXT(hp)) {
|
||||
/* Merge with the next block.*/
|
||||
H_PAGES(hp) += H_PAGES(H_NEXT(hp)) + 1U;
|
||||
H_NEXT(hp) = H_NEXT(H_NEXT(hp));
|
||||
}
|
||||
if ((H_LIMIT(qp) == hp)) {
|
||||
/* Merge with the previous block.*/
|
||||
H_PAGES(qp) += H_PAGES(hp) + 1U;
|
||||
H_NEXT(qp) = H_NEXT(hp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
qp = H_NEXT(qp);
|
||||
}
|
||||
|
||||
/* Releasing heap mutex/semaphore.*/
|
||||
H_UNLOCK(heapp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reports the heap status.
|
||||
* @note This function is meant to be used in the test suite, it should
|
||||
* not be really useful for the application code.
|
||||
*
|
||||
* @param[in] heapp pointer to a heap descriptor or @p NULL in order to
|
||||
* access the default heap.
|
||||
* @param[in] totalp pointer to a variable that will receive the total
|
||||
* fragmented free space or @ NULL
|
||||
* @param[in] largestp pointer to a variable that will receive the largest
|
||||
* free free block found space or @ NULL
|
||||
* @return The number of fragments in the heap.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
size_t chHeapStatus(memory_heap_t *heapp, size_t *totalp, size_t *largestp) {
|
||||
heap_header_t *qp;
|
||||
size_t n, tpages, lpages;
|
||||
|
||||
if (heapp == NULL) {
|
||||
heapp = &default_heap;
|
||||
}
|
||||
|
||||
H_LOCK(heapp);
|
||||
tpages = 0U;
|
||||
lpages = 0U;
|
||||
n = 0U;
|
||||
qp = &heapp->header;
|
||||
while (H_NEXT(qp) != NULL) {
|
||||
size_t pages = H_PAGES(H_NEXT(qp));
|
||||
|
||||
/* Updating counters.*/
|
||||
n++;
|
||||
tpages += pages;
|
||||
if (pages > lpages) {
|
||||
lpages = pages;
|
||||
}
|
||||
|
||||
qp = H_NEXT(qp);
|
||||
}
|
||||
|
||||
/* Writing out fragmented free memory.*/
|
||||
if (totalp != NULL) {
|
||||
*totalp = tpages * CH_HEAP_ALIGNMENT;
|
||||
}
|
||||
|
||||
/* Writing out unfragmented free memory.*/
|
||||
if (largestp != NULL) {
|
||||
*largestp = lpages * CH_HEAP_ALIGNMENT;
|
||||
}
|
||||
H_UNLOCK(heapp);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_HEAP == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,435 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmboxes.c
|
||||
* @brief Mailboxes code.
|
||||
*
|
||||
* @addtogroup mailboxes
|
||||
* @details Asynchronous messages.
|
||||
* <h2>Operation mode</h2>
|
||||
* A mailbox is an asynchronous communication mechanism.<br>
|
||||
* Operations defined for mailboxes:
|
||||
* - <b>Post</b>: Posts a message on the mailbox in FIFO order.
|
||||
* - <b>Post Ahead</b>: Posts a message on the mailbox with urgent
|
||||
* priority.
|
||||
* - <b>Fetch</b>: A message is fetched from the mailbox and removed
|
||||
* from the queue.
|
||||
* - <b>Reset</b>: The mailbox is emptied and all the stored messages
|
||||
* are lost.
|
||||
* .
|
||||
* A message is a variable of type msg_t that is guaranteed to have
|
||||
* the same size of and be compatible with (data) pointers (anyway an
|
||||
* explicit cast is needed).
|
||||
* If larger messages need to be exchanged then a pointer to a
|
||||
* structure can be posted in the mailbox but the posting side has
|
||||
* no predefined way to know when the message has been processed. A
|
||||
* possible approach is to allocate memory (from a memory pool for
|
||||
* example) from the posting side and free it on the fetching side.
|
||||
* Another approach is to set a "done" flag into the structure pointed
|
||||
* by the message.
|
||||
* @pre In order to use the mailboxes APIs the @p CH_CFG_USE_MAILBOXES
|
||||
* option must be enabled in @p chconf.h.
|
||||
* @note Compatible with RT and NIL.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes a @p mailbox_t object.
|
||||
*
|
||||
* @param[out] mbp the pointer to the @p mailbox_t structure to be
|
||||
* initialized
|
||||
* @param[in] buf pointer to the messages buffer as an array of @p msg_t
|
||||
* @param[in] n number of elements in the buffer array
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
void chMBObjectInit(mailbox_t *mbp, msg_t *buf, cnt_t n) {
|
||||
|
||||
chDbgCheck((mbp != NULL) && (buf != NULL) && (n > (cnt_t)0));
|
||||
|
||||
mbp->buffer = buf;
|
||||
mbp->rdptr = buf;
|
||||
mbp->wrptr = buf;
|
||||
mbp->top = &buf[n];
|
||||
chSemObjectInit(&mbp->emptysem, n);
|
||||
chSemObjectInit(&mbp->fullsem, (cnt_t)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets a @p mailbox_t object.
|
||||
* @details All the waiting threads are resumed with status @p MSG_RESET and
|
||||
* the queued messages are lost.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chMBReset(mailbox_t *mbp) {
|
||||
|
||||
chSysLock();
|
||||
chMBResetI(mbp);
|
||||
chSchRescheduleS();
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets a @p mailbox_t object.
|
||||
* @details All the waiting threads are resumed with status @p MSG_RESET and
|
||||
* the queued messages are lost.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chMBResetI(mailbox_t *mbp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(mbp != NULL);
|
||||
|
||||
mbp->wrptr = mbp->buffer;
|
||||
mbp->rdptr = mbp->buffer;
|
||||
chSemResetI(&mbp->emptysem, (cnt_t)(mbp->top - mbp->buffer));
|
||||
chSemResetI(&mbp->fullsem, (cnt_t)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts a message into a mailbox.
|
||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||
* available or the specified time runs out.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[in] msg the message to be posted on the mailbox
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly posted.
|
||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t chMBPost(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||
msg_t rdymsg;
|
||||
|
||||
chSysLock();
|
||||
rdymsg = chMBPostS(mbp, msg, timeout);
|
||||
chSysUnlock();
|
||||
|
||||
return rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts a message into a mailbox.
|
||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||
* available or the specified time runs out.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[in] msg the message to be posted on the mailbox
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly posted.
|
||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
msg_t chMBPostS(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||
msg_t rdymsg;
|
||||
|
||||
chDbgCheckClassS();
|
||||
chDbgCheck(mbp != NULL);
|
||||
|
||||
rdymsg = chSemWaitTimeoutS(&mbp->emptysem, timeout);
|
||||
if (rdymsg == MSG_OK) {
|
||||
*mbp->wrptr++ = msg;
|
||||
if (mbp->wrptr >= mbp->top) {
|
||||
mbp->wrptr = mbp->buffer;
|
||||
}
|
||||
chSemSignalI(&mbp->fullsem);
|
||||
chSchRescheduleS();
|
||||
}
|
||||
|
||||
return rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts a message into a mailbox.
|
||||
* @details This variant is non-blocking, the function returns a timeout
|
||||
* condition if the queue is full.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[in] msg the message to be posted on the mailbox
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly posted.
|
||||
* @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
|
||||
* posted.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
msg_t chMBPostI(mailbox_t *mbp, msg_t msg) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(mbp != NULL);
|
||||
|
||||
if (chSemGetCounterI(&mbp->emptysem) <= (cnt_t)0) {
|
||||
return MSG_TIMEOUT;
|
||||
}
|
||||
|
||||
chSemFastWaitI(&mbp->emptysem);
|
||||
*mbp->wrptr++ = msg;
|
||||
if (mbp->wrptr >= mbp->top) {
|
||||
mbp->wrptr = mbp->buffer;
|
||||
}
|
||||
chSemSignalI(&mbp->fullsem);
|
||||
|
||||
return MSG_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts an high priority message into a mailbox.
|
||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||
* available or the specified time runs out.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[in] msg the message to be posted on the mailbox
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly posted.
|
||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t chMBPostAhead(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||
msg_t rdymsg;
|
||||
|
||||
chSysLock();
|
||||
rdymsg = chMBPostAheadS(mbp, msg, timeout);
|
||||
chSysUnlock();
|
||||
|
||||
return rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts an high priority message into a mailbox.
|
||||
* @details The invoking thread waits until a empty slot in the mailbox becomes
|
||||
* available or the specified time runs out.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[in] msg the message to be posted on the mailbox
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly posted.
|
||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
msg_t chMBPostAheadS(mailbox_t *mbp, msg_t msg, systime_t timeout) {
|
||||
msg_t rdymsg;
|
||||
|
||||
chDbgCheckClassS();
|
||||
chDbgCheck(mbp != NULL);
|
||||
|
||||
rdymsg = chSemWaitTimeoutS(&mbp->emptysem, timeout);
|
||||
if (rdymsg == MSG_OK) {
|
||||
if (--mbp->rdptr < mbp->buffer) {
|
||||
mbp->rdptr = mbp->top - 1;
|
||||
}
|
||||
*mbp->rdptr = msg;
|
||||
chSemSignalI(&mbp->fullsem);
|
||||
chSchRescheduleS();
|
||||
}
|
||||
|
||||
return rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Posts an high priority message into a mailbox.
|
||||
* @details This variant is non-blocking, the function returns a timeout
|
||||
* condition if the queue is full.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[in] msg the message to be posted on the mailbox
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly posted.
|
||||
* @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
|
||||
* posted.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(mbp != NULL);
|
||||
|
||||
if (chSemGetCounterI(&mbp->emptysem) <= (cnt_t)0) {
|
||||
return MSG_TIMEOUT;
|
||||
}
|
||||
chSemFastWaitI(&mbp->emptysem);
|
||||
if (--mbp->rdptr < mbp->buffer) {
|
||||
mbp->rdptr = mbp->top - 1;
|
||||
}
|
||||
*mbp->rdptr = msg;
|
||||
chSemSignalI(&mbp->fullsem);
|
||||
|
||||
return MSG_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a message from a mailbox.
|
||||
* @details The invoking thread waits until a message is posted in the mailbox
|
||||
* or the specified time runs out.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[out] msgp pointer to a message variable for the received message
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly fetched.
|
||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
msg_t chMBFetch(mailbox_t *mbp, msg_t *msgp, systime_t timeout) {
|
||||
msg_t rdymsg;
|
||||
|
||||
chSysLock();
|
||||
rdymsg = chMBFetchS(mbp, msgp, timeout);
|
||||
chSysUnlock();
|
||||
|
||||
return rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a message from a mailbox.
|
||||
* @details The invoking thread waits until a message is posted in the mailbox
|
||||
* or the specified time runs out.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[out] msgp pointer to a message variable for the received message
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly fetched.
|
||||
* @retval MSG_RESET if the mailbox has been reset while waiting.
|
||||
* @retval MSG_TIMEOUT if the operation has timed out.
|
||||
*
|
||||
* @sclass
|
||||
*/
|
||||
msg_t chMBFetchS(mailbox_t *mbp, msg_t *msgp, systime_t timeout) {
|
||||
msg_t rdymsg;
|
||||
|
||||
chDbgCheckClassS();
|
||||
chDbgCheck((mbp != NULL) && (msgp != NULL));
|
||||
|
||||
rdymsg = chSemWaitTimeoutS(&mbp->fullsem, timeout);
|
||||
if (rdymsg == MSG_OK) {
|
||||
*msgp = *mbp->rdptr++;
|
||||
if (mbp->rdptr >= mbp->top) {
|
||||
mbp->rdptr = mbp->buffer;
|
||||
}
|
||||
chSemSignalI(&mbp->emptysem);
|
||||
chSchRescheduleS();
|
||||
}
|
||||
|
||||
return rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves a message from a mailbox.
|
||||
* @details This variant is non-blocking, the function returns a timeout
|
||||
* condition if the queue is empty.
|
||||
*
|
||||
* @param[in] mbp the pointer to an initialized @p mailbox_t object
|
||||
* @param[out] msgp pointer to a message variable for the received message
|
||||
* @return The operation status.
|
||||
* @retval MSG_OK if a message has been correctly fetched.
|
||||
* @retval MSG_TIMEOUT if the mailbox is empty and a message cannot be
|
||||
* fetched.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((mbp != NULL) && (msgp != NULL));
|
||||
|
||||
if (chSemGetCounterI(&mbp->fullsem) <= (cnt_t)0) {
|
||||
return MSG_TIMEOUT;
|
||||
}
|
||||
chSemFastWaitI(&mbp->fullsem);
|
||||
*msgp = *mbp->rdptr++;
|
||||
if (mbp->rdptr >= mbp->top) {
|
||||
mbp->rdptr = mbp->buffer;
|
||||
}
|
||||
chSemSignalI(&mbp->emptysem);
|
||||
|
||||
return MSG_OK;
|
||||
}
|
||||
#endif /* CH_CFG_USE_MAILBOXES == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmemcore.c
|
||||
* @brief Core memory manager code.
|
||||
*
|
||||
* @addtogroup memcore
|
||||
* @details Core Memory Manager related APIs and services.
|
||||
* <h2>Operation mode</h2>
|
||||
* The core memory manager is a simplified allocator that only
|
||||
* allows to allocate memory blocks without the possibility to
|
||||
* free them.<br>
|
||||
* This allocator is meant as a memory blocks provider for the
|
||||
* other allocators such as:
|
||||
* - C-Runtime allocator (through a compiler specific adapter module).
|
||||
* - Heap allocator (see @ref heaps).
|
||||
* - Memory pools allocator (see @ref pools).
|
||||
* .
|
||||
* By having a centralized memory provider the various allocators
|
||||
* can coexist and share the main memory.<br>
|
||||
* This allocator, alone, is also useful for very simple
|
||||
* applications that just require a simple way to get memory
|
||||
* blocks.
|
||||
* @pre In order to use the core memory manager APIs the @p CH_CFG_USE_MEMCORE
|
||||
* option must be enabled in @p chconf.h.
|
||||
* @note Compatible with RT and NIL.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static uint8_t *nextmem;
|
||||
static uint8_t *endmem;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level memory manager initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _core_init(void) {
|
||||
#if CH_CFG_MEMCORE_SIZE == 0
|
||||
extern uint8_t __heap_base__[];
|
||||
extern uint8_t __heap_end__[];
|
||||
|
||||
/*lint -save -e9033 [10.8] Required cast operations.*/
|
||||
nextmem = (uint8_t *)MEM_ALIGN_NEXT(__heap_base__, PORT_NATURAL_ALIGN);
|
||||
endmem = (uint8_t *)MEM_ALIGN_PREV(__heap_end__, PORT_NATURAL_ALIGN);
|
||||
/*lint restore*/
|
||||
#else
|
||||
static stkalign_t buffer[MEM_ALIGN_NEXT(CH_CFG_MEMCORE_SIZE) /
|
||||
PORT_NATURAL_ALIGN];
|
||||
|
||||
nextmem = (uint8_t *)&buffer[0];
|
||||
endmem = (uint8_t *)&buffer[MEM_ALIGN_NEXT(CH_CFG_MEMCORE_SIZE) /
|
||||
PORT_NATURAL_ALIGN];
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned to the
|
||||
* specified alignment.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated.
|
||||
* @param[in] align desired memory alignment
|
||||
* @return A pointer to the allocated memory block.
|
||||
* @retval NULL allocation failed, core memory exhausted.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void *chCoreAllocAlignedI(size_t size, unsigned align) {
|
||||
uint8_t *p;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(MEM_IS_VALID_ALIGNMENT(align));
|
||||
|
||||
size = MEM_ALIGN_NEXT(size, align);
|
||||
p = (uint8_t *)MEM_ALIGN_NEXT(nextmem, align);
|
||||
|
||||
/* ---????? lint -save -e9033 [10.8] The cast is safe.*/
|
||||
if ((size_t)(endmem - p) < size) {
|
||||
/* ---????? lint -restore*/
|
||||
return NULL;
|
||||
}
|
||||
nextmem = p + size;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates a memory block.
|
||||
* @details The allocated block is guaranteed to be properly aligned to the
|
||||
* specified alignment.
|
||||
*
|
||||
* @param[in] size the size of the block to be allocated
|
||||
* @param[in] align desired memory alignment
|
||||
* @return A pointer to the allocated memory block.
|
||||
* @retval NULL allocation failed, core memory exhausted.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void *chCoreAllocAligned(size_t size, unsigned align) {
|
||||
void *p;
|
||||
|
||||
chSysLock();
|
||||
p = chCoreAllocAlignedI(size, align);
|
||||
chSysUnlock();
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Core memory status.
|
||||
*
|
||||
* @return The size, in bytes, of the free core memory.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
size_t chCoreGetStatusX(void) {
|
||||
|
||||
/*lint -save -e9033 [10.8] The cast is safe.*/
|
||||
return (size_t)(endmem - nextmem);
|
||||
/*lint -restore*/
|
||||
}
|
||||
#endif /* CH_CFG_USE_MEMCORE == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chmempools.c
|
||||
* @brief Memory Pools code.
|
||||
*
|
||||
* @addtogroup pools
|
||||
* @details Memory Pools related APIs and services.
|
||||
* <h2>Operation mode</h2>
|
||||
* The Memory Pools APIs allow to allocate/free fixed size objects in
|
||||
* <b>constant time</b> and reliably without memory fragmentation
|
||||
* problems.<br>
|
||||
* Memory Pools do not enforce any alignment constraint on the
|
||||
* contained object however the objects must be properly aligned
|
||||
* to contain a pointer to void.
|
||||
* @pre In order to use the memory pools APIs the @p CH_CFG_USE_MEMPOOLS option
|
||||
* must be enabled in @p chconf.h.
|
||||
* @note Compatible with RT and NIL.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes an empty memory pool.
|
||||
*
|
||||
* @param[out] mp pointer to a @p memory_pool_t structure
|
||||
* @param[in] size the size of the objects contained in this memory pool,
|
||||
* the minimum accepted size is the size of a pointer to
|
||||
* void.
|
||||
* @param[in] provider memory provider function for the memory pool or
|
||||
* @p NULL if the pool is not allowed to grow
|
||||
* automatically
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
void chPoolObjectInit(memory_pool_t *mp, size_t size, memgetfunc_t provider) {
|
||||
|
||||
chDbgCheck((mp != NULL) && (size >= sizeof(void *)));
|
||||
|
||||
mp->next = NULL;
|
||||
mp->object_size = size;
|
||||
mp->provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Loads a memory pool with an array of static objects.
|
||||
* @pre The memory pool must be already been initialized.
|
||||
* @pre The array elements must be of the right size for the specified
|
||||
* memory pool.
|
||||
* @post The memory pool contains the elements of the input array.
|
||||
*
|
||||
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||
* @param[in] p pointer to the array first element
|
||||
* @param[in] n number of elements in the array
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n) {
|
||||
|
||||
chDbgCheck((mp != NULL) && (n != 0U));
|
||||
|
||||
while (n != 0U) {
|
||||
chPoolAdd(mp, p);
|
||||
/*lint -save -e9087 [11.3] Safe cast.*/
|
||||
p = (void *)(((uint8_t *)p) + mp->object_size);
|
||||
/*lint -restore*/
|
||||
n--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates an object from a memory pool.
|
||||
* @pre The memory pool must be already been initialized.
|
||||
*
|
||||
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||
* @return The pointer to the allocated object.
|
||||
* @retval NULL if pool is empty.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void *chPoolAllocI(memory_pool_t *mp) {
|
||||
void *objp;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(mp != NULL);
|
||||
|
||||
objp = mp->next;
|
||||
/*lint -save -e9013 [15.7] There is no else because it is not needed.*/
|
||||
if (objp != NULL) {
|
||||
mp->next = mp->next->next;
|
||||
}
|
||||
else if (mp->provider != NULL) {
|
||||
objp = mp->provider(mp->object_size, PORT_NATURAL_ALIGN); /* TODO: Alignment is not properly handled */
|
||||
}
|
||||
/*lint -restore*/
|
||||
|
||||
return objp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocates an object from a memory pool.
|
||||
* @pre The memory pool must be already been initialized.
|
||||
*
|
||||
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||
* @return The pointer to the allocated object.
|
||||
* @retval NULL if pool is empty.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void *chPoolAlloc(memory_pool_t *mp) {
|
||||
void *objp;
|
||||
|
||||
chSysLock();
|
||||
objp = chPoolAllocI(mp);
|
||||
chSysUnlock();
|
||||
|
||||
return objp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases an object into a memory pool.
|
||||
* @pre The memory pool must be already been initialized.
|
||||
* @pre The freed object must be of the right size for the specified
|
||||
* memory pool.
|
||||
* @pre The object must be properly aligned to contain a pointer to void.
|
||||
*
|
||||
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||
* @param[in] objp the pointer to the object to be released
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chPoolFreeI(memory_pool_t *mp, void *objp) {
|
||||
struct pool_header *php = objp;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((mp != NULL) && (objp != NULL));
|
||||
|
||||
php->next = mp->next;
|
||||
mp->next = php;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Releases an object into a memory pool.
|
||||
* @pre The memory pool must be already been initialized.
|
||||
* @pre The freed object must be of the right size for the specified
|
||||
* memory pool.
|
||||
* @pre The object must be properly aligned to contain a pointer to void.
|
||||
*
|
||||
* @param[in] mp pointer to a @p memory_pool_t structure
|
||||
* @param[in] objp the pointer to the object to be released
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void chPoolFree(memory_pool_t *mp, void *objp) {
|
||||
|
||||
chSysLock();
|
||||
chPoolFreeI(mp, objp);
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file templates/nilcore.c
|
||||
* @brief Port code.
|
||||
* @file ARM/chcore.c
|
||||
* @brief ARM port code.
|
||||
*
|
||||
* @addtogroup NIL_CORE
|
||||
* @addtogroup ARM_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "nil.h"
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
|
@ -0,0 +1,564 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ARM/chcore.h
|
||||
* @brief ARM7/9 architecture port macros and structures.
|
||||
*
|
||||
* @addtogroup ARM_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Port Capabilities and Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
|
||||
/**
|
||||
* @brief Natural alignment constant.
|
||||
* @note It is the minimum alignment for pointer-size variables.
|
||||
*/
|
||||
#define PORT_NATURAL_ALIGN sizeof (void *)
|
||||
|
||||
/**
|
||||
* @brief Stack alignment constant.
|
||||
* @note It is the alignement required for the stack pointer.
|
||||
*/
|
||||
#define PORT_STACK_ALIGN sizeof (stkalign_t)
|
||||
|
||||
/**
|
||||
* @brief Working Areas alignment constant.
|
||||
* @note It is the alignment to be enforced for thread working areas.
|
||||
*/
|
||||
#define PORT_WORKING_AREA_ALIGN sizeof (stkalign_t)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Architecture and Compiler
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Macro defining a generic ARM architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_ARM
|
||||
|
||||
/* The following code is not processed when the file is included from an
|
||||
asm module because those intrinsic macros are not necessarily defined
|
||||
by the assembler too.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
/**
|
||||
* @brief Compiler name and version.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__DOXYGEN__)
|
||||
#define PORT_COMPILER_NAME "GCC " __VERSION__
|
||||
|
||||
#else
|
||||
#error "unsupported compiler"
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name ARM variants
|
||||
* @{
|
||||
*/
|
||||
#define ARM_CORE_ARM7TDMI 7
|
||||
#define ARM_CORE_ARM9 9
|
||||
#define ARM_CORE_CORTEX_A8 108
|
||||
#define ARM_CORE_CORTEX_A9 109
|
||||
/** @} */
|
||||
|
||||
/* Inclusion of the ARM implementation specific parameters.*/
|
||||
#include "armparams.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables an alternative timer implementation.
|
||||
* @details Usually the port uses a timer interface defined in the file
|
||||
* @p chcore_timer.h, if this option is enabled then the file
|
||||
* @p chcore_timer_alt.h is included instead.
|
||||
*/
|
||||
#if !defined(PORT_USE_ALT_TIMER)
|
||||
#define PORT_USE_ALT_TIMER FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Stack size for the system idle thread.
|
||||
* @details This size depends on the idle thread implementation, usually
|
||||
* the idle thread should take no more space than those reserved
|
||||
* by @p PORT_INT_REQUIRED_STACK.
|
||||
* @note In this port it is set to 32 because the idle thread does have
|
||||
* a stack frame when compiling without optimizations. You may
|
||||
* reduce this value to zero when compiling with optimizations.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
|
||||
#define PORT_INT_REQUIRED_STACK 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief If enabled allows the idle thread to enter a low power mode.
|
||||
*/
|
||||
#ifndef ARM_ENABLE_WFI_IDLE
|
||||
#define ARM_ENABLE_WFI_IDLE FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/* The following code is not processed when the file is included from an
|
||||
asm module.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
/* ARM core check.*/
|
||||
#if (ARM_CORE == ARM_CORE_ARM7TDMI) || defined(__DOXYGEN__)
|
||||
#define PORT_ARCHITECTURE_ARM_ARM7
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv4T"
|
||||
#define PORT_CORE_VARIANT_NAME "ARM7"
|
||||
|
||||
#elif ARM_CORE == ARM_CORE_ARM9
|
||||
#define PORT_ARCHITECTURE_ARM_ARM9
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv5T"
|
||||
#define PORT_CORE_VARIANT_NAME "ARM9"
|
||||
|
||||
#elif ARM_CORE == ARM_CORE_CORTEX_A8
|
||||
#define PORT_ARCHITECTURE_ARM_CORTEXA8
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv7"
|
||||
#define PORT_CORE_VARIANT_NAME "ARM Cortex-A8"
|
||||
|
||||
#elif ARM_CORE == ARM_CORE_CORTEX_A9
|
||||
#define PORT_ARCHITECTURE_ARM_CORTEXA9
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv7"
|
||||
#define PORT_CORE_VARIANT_NAME "ARM Cortex-A9"
|
||||
|
||||
#else
|
||||
#error "unknown or unsupported ARM core"
|
||||
#endif
|
||||
|
||||
#if defined(THUMB_PRESENT)
|
||||
#if defined(THUMB_NO_INTERWORKING)
|
||||
#define PORT_INFO "Pure THUMB mode"
|
||||
#else
|
||||
#define PORT_INFO "Interworking mode"
|
||||
#endif
|
||||
#else
|
||||
#define PORT_INFO "Pure ARM mode"
|
||||
#endif
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/* The following code is not processed when the file is included from an
|
||||
asm module.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
/**
|
||||
* @brief Type of stack and memory alignment enforcement.
|
||||
* @note In this architecture the stack alignment is enforced to 64 bits.
|
||||
*/
|
||||
typedef uint64_t stkalign_t;
|
||||
|
||||
/**
|
||||
* @brief Generic ARM register.
|
||||
*/
|
||||
typedef void *regarm_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt saved context.
|
||||
* @details This structure represents the stack frame saved during an
|
||||
* interrupt handler.
|
||||
*/
|
||||
struct port_extctx {
|
||||
regarm_t spsr_irq;
|
||||
regarm_t lr_irq;
|
||||
regarm_t r0;
|
||||
regarm_t r1;
|
||||
regarm_t r2;
|
||||
regarm_t r3;
|
||||
regarm_t r12;
|
||||
regarm_t lr_usr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief System saved context.
|
||||
* @details This structure represents the inner stack frame during a context
|
||||
* switch.
|
||||
*/
|
||||
struct port_intctx {
|
||||
regarm_t r4;
|
||||
regarm_t r5;
|
||||
regarm_t r6;
|
||||
regarm_t r7;
|
||||
regarm_t r8;
|
||||
regarm_t r9;
|
||||
regarm_t r10;
|
||||
regarm_t r11;
|
||||
regarm_t lr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p thread_t structure.
|
||||
* @details In this port the structure just holds a pointer to the
|
||||
* @p port_intctx structure representing the stack pointer
|
||||
* at context switch time.
|
||||
*/
|
||||
struct port_context {
|
||||
struct port_intctx *r13;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
|
||||
(tp)->ctx.r13 = (struct port_intctx *)((uint8_t *)(wtop) - \
|
||||
sizeof (struct port_intctx)); \
|
||||
(tp)->ctx.r13->r4 = (regarm_t)(pf); \
|
||||
(tp)->ctx.r13->r5 = (regarm_t)(arg); \
|
||||
(tp)->ctx.r13->lr = (regarm_t)(_port_thread_start); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
* @note There is no need to perform alignments in this macro.
|
||||
*/
|
||||
#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \
|
||||
sizeof(struct port_extctx) + \
|
||||
((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*
|
||||
* @param[in] s the name to be assigned to the stack array
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
*/
|
||||
#define PORT_WORKING_AREA(s, n) \
|
||||
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
|
||||
|
||||
/**
|
||||
* @brief Priority level verification macro.
|
||||
* @todo Add the required parameters to armparams.h.
|
||||
*/
|
||||
#define PORT_IRQ_IS_VALID_PRIORITY(n) false
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
* @details This macro must be inserted at the start of all IRQ handlers
|
||||
* enabled to invoke system APIs.
|
||||
*/
|
||||
#define PORT_IRQ_PROLOGUE()
|
||||
|
||||
/**
|
||||
* @brief IRQ epilogue code.
|
||||
* @details This macro must be inserted at the end of all IRQ handlers
|
||||
* enabled to invoke system APIs.
|
||||
*/
|
||||
#define PORT_IRQ_EPILOGUE() return chSchIsPreemptionRequired()
|
||||
|
||||
/**
|
||||
* @brief IRQ handler function declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
*/
|
||||
#define PORT_IRQ_HANDLER(id) bool id(void)
|
||||
|
||||
/**
|
||||
* @brief Fast IRQ handler function declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
*/
|
||||
#define PORT_FAST_IRQ_HANDLER(id) \
|
||||
__attribute__((interrupt("FIQ"))) void id(void)
|
||||
|
||||
/**
|
||||
* @brief Performs a context switch between two threads.
|
||||
* @details This is the most critical code in any port, this function
|
||||
* is responsible for the context switch between 2 threads.
|
||||
* @note The implementation of this code affects <b>directly</b> the context
|
||||
* switch performance so optimize here as much as you can.
|
||||
* @note Implemented as inlined code for performance reasons.
|
||||
*
|
||||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#if defined(THUMB)
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||
#define port_switch(ntp, otp) { \
|
||||
register struct port_intctx *r13 asm ("r13"); \
|
||||
if ((stkalign_t *)(r13 - 1) < otp->p_stklimit) \
|
||||
chSysHalt("stack overflow"); \
|
||||
_port_switch_thumb(ntp, otp); \
|
||||
}
|
||||
#else
|
||||
#define port_switch(ntp, otp) _port_switch_thumb(ntp, otp)
|
||||
#endif
|
||||
|
||||
#else /* !defined(THUMB) */
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK == TRUE
|
||||
#define port_switch(ntp, otp) { \
|
||||
register struct port_intctx *r13 asm ("r13"); \
|
||||
if ((stkalign_t *)(r13 - 1) < otp->stklimit) \
|
||||
chSysHalt("stack overflow"); \
|
||||
_port_switch_arm(ntp, otp); \
|
||||
}
|
||||
#else
|
||||
#define port_switch(ntp, otp) _port_switch_arm(ntp, otp)
|
||||
#endif
|
||||
|
||||
#endif /* !defined(THUMB) */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if defined(THUMB_PRESENT)
|
||||
syssts_t _port_get_cpsr(void);
|
||||
#endif
|
||||
#if defined(THUMB)
|
||||
void _port_switch_thumb(thread_t *ntp, thread_t *otp);
|
||||
#else
|
||||
void _port_switch_arm(thread_t *ntp, thread_t *otp);
|
||||
#endif
|
||||
void _port_thread_start(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Port-related initialization code.
|
||||
*/
|
||||
static inline void port_init(void) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a word encoding the current interrupts status.
|
||||
*
|
||||
* @return The interrupts status.
|
||||
*/
|
||||
static inline syssts_t port_get_irq_status(void) {
|
||||
syssts_t sts;
|
||||
|
||||
#if defined(THUMB)
|
||||
sts = _port_get_cpsr();
|
||||
#else
|
||||
__asm volatile ("mrs %[p0], CPSR" : [p0] "=r" (sts) :);
|
||||
#endif
|
||||
/*lint -save -e530 [9.1] Asm instruction not seen by lint.*/
|
||||
return sts;
|
||||
/*lint -restore*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks the interrupt status.
|
||||
*
|
||||
* @param[in] sts the interrupt status word
|
||||
*
|
||||
* @return The interrupt status.
|
||||
* @retval false the word specified a disabled interrupts status.
|
||||
* @retval true the word specified an enabled interrupts status.
|
||||
*/
|
||||
static inline bool port_irq_enabled(syssts_t sts) {
|
||||
|
||||
return (sts & (syssts_t)0x80) == (syssts_t)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines the current execution context.
|
||||
*
|
||||
* @return The execution context.
|
||||
* @retval false not running in ISR mode.
|
||||
* @retval true running in ISR mode.
|
||||
*/
|
||||
static inline bool port_is_isr_context(void) {
|
||||
syssts_t sts;
|
||||
|
||||
#if defined(THUMB)
|
||||
sts = _port_get_cpsr();
|
||||
#else
|
||||
__asm volatile ("mrs %[p0], CPSR" : [p0] "=r" (sts) :);
|
||||
#endif
|
||||
|
||||
/*lint -save -e530 [9.1] Asm instruction not seen by lint.*/
|
||||
return (sts & (syssts_t)0x1F) == (syssts_t)0x12;
|
||||
/*lint -restore*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-lock action.
|
||||
* @details In this port it disables the IRQ sources and keeps FIQ sources
|
||||
* enabled.
|
||||
*/
|
||||
static inline void port_lock(void) {
|
||||
|
||||
#if defined(THUMB)
|
||||
__asm volatile ("bl _port_lock_thumb" : : : "r3", "lr", "memory");
|
||||
#else
|
||||
__asm volatile ("msr CPSR_c, #0x9F" : : : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-unlock action.
|
||||
* @details In this port it enables both the IRQ and FIQ sources.
|
||||
*/
|
||||
static inline void port_unlock(void) {
|
||||
|
||||
#if defined(THUMB)
|
||||
__asm volatile ("bl _port_unlock_thumb" : : : "r3", "lr", "memory");
|
||||
#else
|
||||
__asm volatile ("msr CPSR_c, #0x1F" : : : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-lock action from an interrupt handler.
|
||||
* @note Empty in this port.
|
||||
*/
|
||||
static inline void port_lock_from_isr(void) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-unlock action from an interrupt handler.
|
||||
* @note Empty in this port.
|
||||
*/
|
||||
static inline void port_unlock_from_isr(void) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables all the interrupt sources.
|
||||
* @details In this port it disables both the IRQ and FIQ sources.
|
||||
* @note Implements a workaround for spurious interrupts taken from the NXP
|
||||
* LPC214x datasheet.
|
||||
*/
|
||||
static inline void port_disable(void) {
|
||||
|
||||
#if defined(THUMB)
|
||||
__asm volatile ("bl _port_disable_thumb" : : : "r3", "lr", "memory");
|
||||
#else
|
||||
__asm volatile ("mrs r3, CPSR \n\t"
|
||||
"orr r3, #0x80 \n\t"
|
||||
"msr CPSR_c, r3 \n\t"
|
||||
"orr r3, #0x40 \n\t"
|
||||
"msr CPSR_c, r3" : : : "r3", "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the interrupt sources below kernel-level priority.
|
||||
* @note Interrupt sources above kernel level remains enabled.
|
||||
* @note In this port it disables the IRQ sources and enables the
|
||||
* FIQ sources.
|
||||
*/
|
||||
static inline void port_suspend(void) {
|
||||
|
||||
#if defined(THUMB)
|
||||
__asm volatile ("bl _port_suspend_thumb" : : : "r3", "lr", "memory");
|
||||
#else
|
||||
__asm volatile ("msr CPSR_c, #0x9F" : : : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables all the interrupt sources.
|
||||
* @note In this port it enables both the IRQ and FIQ sources.
|
||||
*/
|
||||
static inline void port_enable(void) {
|
||||
|
||||
#if defined(THUMB)
|
||||
__asm volatile ("bl _port_enable_thumb" : : : "r3", "lr", "memory");
|
||||
#else
|
||||
__asm volatile ("msr CPSR_c, #0x1F" : : : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters an architecture-dependent IRQ-waiting mode.
|
||||
* @details The function is meant to return when an interrupt becomes pending.
|
||||
* The simplest implementation is an empty function or macro but this
|
||||
* would not take advantage of architecture-specific power saving
|
||||
* modes.
|
||||
* @note Implemented as an inlined @p WFI instruction.
|
||||
*/
|
||||
static inline void port_wait_for_interrupt(void) {
|
||||
|
||||
#if ARM_ENABLE_WFI_IDLE == TRUE
|
||||
ARM_WFI_IMPL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
#if PORT_USE_ALT_TIMER == FALSE
|
||||
#include "chcore_timer.h"
|
||||
#else /* PORT_USE_ALT_TIMER */
|
||||
#include "chcore_timer_alt.h"
|
||||
#endif /* PORT_USE_ALT_TIMER */
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _CHCORE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -18,15 +18,18 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file templates/nilcore_timer.h
|
||||
* @file chcore_timer.h
|
||||
* @brief System timer header file.
|
||||
*
|
||||
* @addtogroup NIL_TIMER
|
||||
* @addtogroup ARM_TIMER
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_TIMER_H_
|
||||
#define _NILCORE_TIMER_H_
|
||||
#ifndef _CHCORE_TIMER_H_
|
||||
#define _CHCORE_TIMER_H_
|
||||
|
||||
/* This is the only header in the HAL designed to be include-able alone.*/
|
||||
#include "st.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
|
@ -61,13 +64,13 @@
|
|||
* @note Makes sure that no spurious alarms are triggered after
|
||||
* this call.
|
||||
*
|
||||
* @param[in] abstime the time to be set for the first alarm
|
||||
* @param[in] time the time to be set for the first alarm
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void port_timer_start_alarm(systime_t abstime) {
|
||||
static inline void port_timer_start_alarm(systime_t time) {
|
||||
|
||||
(void)abstime;
|
||||
stStartAlarm(time);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,18 +80,19 @@ static inline void port_timer_start_alarm(systime_t abstime) {
|
|||
*/
|
||||
static inline void port_timer_stop_alarm(void) {
|
||||
|
||||
stStopAlarm();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the alarm time.
|
||||
*
|
||||
* @param[in] abstime the time to be set for the next alarm
|
||||
* @param[in] time the time to be set for the next alarm
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void port_timer_set_alarm(systime_t abstime) {
|
||||
static inline void port_timer_set_alarm(systime_t time) {
|
||||
|
||||
(void)abstime;
|
||||
stSetAlarm(time);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,7 +104,7 @@ static inline void port_timer_set_alarm(systime_t abstime) {
|
|||
*/
|
||||
static inline systime_t port_timer_get_time(void) {
|
||||
|
||||
return (systime_t)0;
|
||||
return stGetCounter();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,9 +116,9 @@ static inline systime_t port_timer_get_time(void) {
|
|||
*/
|
||||
static inline systime_t port_timer_get_alarm(void) {
|
||||
|
||||
return (systime_t)0;
|
||||
return stGetAlarm();
|
||||
}
|
||||
|
||||
#endif /* _NILCORE_TIMER_H_ */
|
||||
#endif /* _CHCORE_TIMER_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,303 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ARM/compilers/GCC/chcoreasm.s
|
||||
* @brief ARM architecture port low level code.
|
||||
*
|
||||
* @addtogroup ARM_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "armparams.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* RTOS-specific context offset.
|
||||
*/
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
#define CONTEXT_OFFSET 12
|
||||
#elif defined(_CHIBIOS_NIL_CONF_)
|
||||
#define CONTEXT_OFFSET 0
|
||||
#else
|
||||
#error "invalid chconf.h"
|
||||
#endif
|
||||
|
||||
.set MODE_USR, 0x10
|
||||
.set MODE_FIQ, 0x11
|
||||
.set MODE_IRQ, 0x12
|
||||
.set MODE_SVC, 0x13
|
||||
.set MODE_ABT, 0x17
|
||||
.set MODE_UND, 0x1B
|
||||
.set MODE_SYS, 0x1F
|
||||
|
||||
.equ I_BIT, 0x80
|
||||
.equ F_BIT, 0x40
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* The following functions are only present if there is THUMB code in
|
||||
* the system.
|
||||
*/
|
||||
#if defined(THUMB_PRESENT)
|
||||
.balign 16
|
||||
.code 16
|
||||
.thumb_func
|
||||
.global _port_get_cpsr
|
||||
_port_get_cpsr:
|
||||
mov r0, pc
|
||||
bx r0
|
||||
.code 32
|
||||
mrs r0, CPSR
|
||||
bx lr
|
||||
|
||||
.balign 16
|
||||
.code 16
|
||||
.thumb_func
|
||||
.global _port_disable_thumb
|
||||
_port_disable_thumb:
|
||||
mov r3, pc
|
||||
bx r3
|
||||
.code 32
|
||||
mrs r3, CPSR
|
||||
orr r3, #I_BIT
|
||||
msr CPSR_c, r3
|
||||
orr r3, #F_BIT
|
||||
msr CPSR_c, r3
|
||||
bx lr
|
||||
|
||||
.balign 16
|
||||
.code 16
|
||||
.thumb_func
|
||||
.global _port_suspend_thumb
|
||||
_port_suspend_thumb:
|
||||
// Goes into _port_unlock_thumb
|
||||
|
||||
.code 16
|
||||
.global _port_lock_thumb
|
||||
_port_lock_thumb:
|
||||
mov r3, pc
|
||||
bx r3
|
||||
.code 32
|
||||
msr CPSR_c, #MODE_SYS | I_BIT
|
||||
bx lr
|
||||
|
||||
.balign 16
|
||||
.code 16
|
||||
.thumb_func
|
||||
.global _port_enable_thumb
|
||||
_port_enable_thumb:
|
||||
// Goes into _port_unlock_thumb
|
||||
|
||||
.code 16
|
||||
.global _port_unlock_thumb
|
||||
_port_unlock_thumb:
|
||||
mov r3, pc
|
||||
bx r3
|
||||
.code 32
|
||||
msr CPSR_c, #MODE_SYS
|
||||
bx lr
|
||||
#endif /* defined(THUMB_PRESENT) */
|
||||
|
||||
.balign 16
|
||||
#if defined(THUMB_PRESENT)
|
||||
.code 16
|
||||
.thumb_func
|
||||
.global _port_switch_thumb
|
||||
_port_switch_thumb:
|
||||
mov r2, pc
|
||||
bx r2
|
||||
// Goes into _port_switch_arm in ARM mode
|
||||
#endif /* defined(THUMB_PRESENT) */
|
||||
|
||||
.code 32
|
||||
.global _port_switch_arm
|
||||
_port_switch_arm:
|
||||
stmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
str sp, [r1, #12]
|
||||
ldr sp, [r0, #12]
|
||||
#if defined(THUMB_PRESENT)
|
||||
ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
bx lr
|
||||
#else /* !defined(THUMB_PRESENT)T */
|
||||
ldmfd sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||
#endif /* !defined(THUMB_PRESENT) */
|
||||
|
||||
/*
|
||||
* Common IRQ code. It expects a macro ARM_IRQ_VECTOR_REG with the address
|
||||
* of a register holding the address of the ISR to be invoked, the ISR
|
||||
* then returns in the common epilogue code where the context switch will
|
||||
* be performed, if required.
|
||||
* System stack frame structure after a context switch in the
|
||||
* interrupt handler:
|
||||
*
|
||||
* High +------------+
|
||||
* | LR_USR | -+
|
||||
* | r12 | |
|
||||
* | r3 | |
|
||||
* | r2 | | External context: IRQ handler frame
|
||||
* | r1 | |
|
||||
* | r0 | |
|
||||
* | LR_IRQ | | (user code return address)
|
||||
* | PSR_USR | -+ (user code status)
|
||||
* | .... | <- chSchDoReschedule() stack frame, optimize it for space
|
||||
* | LR | -+ (system code return address)
|
||||
* | r11 | |
|
||||
* | r10 | |
|
||||
* | r9 | |
|
||||
* | r8 | | Internal context: chSysSwitch() frame
|
||||
* | r7 | |
|
||||
* | r6 | |
|
||||
* | r5 | |
|
||||
* SP-> | r4 | -+
|
||||
* Low +------------+
|
||||
*/
|
||||
.balign 16
|
||||
.code 32
|
||||
.global Irq_Handler
|
||||
Irq_Handler:
|
||||
stmfd sp!, {r0-r3, r12, lr}
|
||||
ldr r0, =ARM_IRQ_VECTOR_REG
|
||||
ldr r0, [r0]
|
||||
#if !defined(THUMB_NO_INTERWORKING)
|
||||
ldr lr, =_irq_ret_arm // ISR return point.
|
||||
bx r0 // Calling the ISR.
|
||||
_irq_ret_arm:
|
||||
#else /* defined(THUMB_NO_INTERWORKING) */
|
||||
add r1, pc, #1
|
||||
bx r1
|
||||
.code 16
|
||||
bl _bxr0 // Calling the ISR.
|
||||
mov lr, pc
|
||||
bx lr
|
||||
.code 32
|
||||
#endif /* defined(THUMB_NO_INTERWORKING) */
|
||||
cmp r0, #0
|
||||
ldmfd sp!, {r0-r3, r12, lr}
|
||||
subeqs pc, lr, #4 // No reschedule, returns.
|
||||
|
||||
// Now the frame is created in the system stack, the IRQ
|
||||
// stack is empty.
|
||||
msr CPSR_c, #MODE_SYS | I_BIT
|
||||
stmfd sp!, {r0-r3, r12, lr}
|
||||
msr CPSR_c, #MODE_IRQ | I_BIT
|
||||
mrs r0, SPSR
|
||||
mov r1, lr
|
||||
msr CPSR_c, #MODE_SYS | I_BIT
|
||||
stmfd sp!, {r0, r1} // Push R0=SPSR, R1=LR_IRQ.
|
||||
|
||||
// Context switch.
|
||||
#if defined(THUMB_NO_INTERWORKING)
|
||||
add r0, pc, #1
|
||||
bx r0
|
||||
.code 16
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
mov lr, pc
|
||||
bx lr
|
||||
.code 32
|
||||
#else /* !defined(THUMB_NO_INTERWORKING) */
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#endif /* !defined(THUMB_NO_INTERWORKING) */
|
||||
|
||||
// Re-establish the IRQ conditions again.
|
||||
ldmfd sp!, {r0, r1} // Pop R0=SPSR, R1=LR_IRQ.
|
||||
msr CPSR_c, #MODE_IRQ | I_BIT
|
||||
msr SPSR_fsxc, r0
|
||||
mov lr, r1
|
||||
msr CPSR_c, #MODE_SYS | I_BIT
|
||||
ldmfd sp!, {r0-r3, r12, lr}
|
||||
msr CPSR_c, #MODE_IRQ | I_BIT
|
||||
subs pc, lr, #4
|
||||
#if defined(THUMB_NO_INTERWORKING)
|
||||
.code 16
|
||||
_bxr0: bx r0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Threads trampoline code.
|
||||
* NOTE: The threads always start in ARM mode and then switches to the
|
||||
* thread-function mode.
|
||||
*/
|
||||
.balign 16
|
||||
.code 32
|
||||
.globl _port_thread_start
|
||||
_port_thread_start:
|
||||
#if defined(THUMB_NO_INTERWORKING)
|
||||
add r0, pc, #1
|
||||
bx r0
|
||||
.code 16
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
bl _port_unlock_thumb
|
||||
mov r0, r5
|
||||
bl _bxr4
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
mov r0, #0 /* MSG_OK */
|
||||
bl chThdExit
|
||||
_zombies: b _zombies
|
||||
#endif
|
||||
#if defined(_CHIBIOS_NIL_CONF_)
|
||||
mov r0, #0
|
||||
bl chSysHalt
|
||||
#endif
|
||||
_bxr4: bx r4
|
||||
|
||||
#else /* !defined(THUMB_NO_INTERWORKING) */
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
msr CPSR_c, #MODE_SYS
|
||||
mov r0, r5
|
||||
mov lr, pc
|
||||
bx r4
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
mov r0, #0 /* MSG_OK */
|
||||
bl chThdExit
|
||||
_zombies: b _zombies
|
||||
#endif
|
||||
#if defined(_CHIBIOS_NIL_CONF_)
|
||||
mov r0, #0
|
||||
bl chSysHalt
|
||||
#endif
|
||||
|
||||
#endif /* !defined(THUMB_NO_INTERWORKING) */
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file templates/niltypes.h
|
||||
* @brief Port system types.
|
||||
* @file ARM/compilers/GCC/chtypes.h
|
||||
* @brief ARM port system types.
|
||||
*
|
||||
* @addtogroup NIL_TYPES
|
||||
* @addtogroup ARM_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILTYPES_H_
|
||||
#define _NILTYPES_H_
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -50,22 +50,25 @@
|
|||
#endif
|
||||
/** @} */
|
||||
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
|
||||
/**
|
||||
* @brief Type of system time.
|
||||
*/
|
||||
#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
|
||||
typedef uint32_t systime_t;
|
||||
#else
|
||||
typedef uint16_t systime_t;
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
|
@ -83,14 +86,13 @@ typedef uint16_t systime_t;
|
|||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) \
|
||||
__attribute__((noreturn)) void tname(void *arg)
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __attribute__((packed))
|
||||
|
||||
#endif /* _NILTYPES_H_ */
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,7 @@
|
|||
# List of the ChibiOS/RT ARM generic port files.
|
||||
PORTSRC = ${CHIBIOS}/os/common/ports/ARM/chcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/ARM/compilers/GCC/chcoreasm.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/ARM \
|
||||
${CHIBIOS}/os/common/ports/ARM/compilers/GCC
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/nilcore.c
|
||||
* @file ARMCMx/chcore.c
|
||||
* @brief ARM Cortex-Mx port code.
|
||||
*
|
||||
* @addtogroup ARMCMx_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "nil.h"
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/nilcore.h
|
||||
* @file ARMCMx/chcore.h
|
||||
* @brief ARM Cortex-Mx port macros and structures.
|
||||
*
|
||||
* @addtogroup ARMCMx_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_H_
|
||||
#define _NILCORE_H_
|
||||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
|
@ -76,8 +76,8 @@
|
|||
/**
|
||||
* @brief Enables an alternative timer implementation.
|
||||
* @details Usually the port uses a timer interface defined in the file
|
||||
* @p nilcore_timer.h, if this option is enabled then the file
|
||||
* @p nilcore_timer_alt.h is included instead.
|
||||
* @p chcore_timer.h, if this option is enabled then the file
|
||||
* @p chcore_timer_alt.h is included instead.
|
||||
*/
|
||||
#if !defined(PORT_USE_ALT_TIMER)
|
||||
#define PORT_USE_ALT_TIMER FALSE
|
||||
|
@ -128,6 +128,16 @@ struct port_extctx {};
|
|||
struct port_intctx {};
|
||||
#endif /* defined(__DOXYGEN__) */
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p thread_t structure.
|
||||
* @details In this port the structure just holds a pointer to the
|
||||
* @p port_intctx structure representing the stack pointer
|
||||
* at context switch time.
|
||||
*/
|
||||
struct port_context {
|
||||
struct port_intctx *r13;
|
||||
};
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -180,25 +190,26 @@ struct port_intctx {};
|
|||
|
||||
/* Includes the sub-architecture-specific part.*/
|
||||
#if (CORTEX_MODEL == 0) || (CORTEX_MODEL == 1)
|
||||
#include "nilcore_v6m.h"
|
||||
#include "chcore_v6m.h"
|
||||
#elif (CORTEX_MODEL == 3) || (CORTEX_MODEL == 4) || (CORTEX_MODEL == 7)
|
||||
#include "nilcore_v7m.h"
|
||||
#include "mpu.h"
|
||||
#include "chcore_v7m.h"
|
||||
#else
|
||||
#error "unknown Cortex-M variant"
|
||||
#endif
|
||||
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
#if NIL_CFG_ST_TIMEDELTA > 0
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
#if PORT_USE_ALT_TIMER == FALSE
|
||||
#include "nilcore_timer.h"
|
||||
#include "chcore_timer.h"
|
||||
#else /* PORT_USE_ALT_TIMER != FALSE */
|
||||
#include "nilcore_timer_alt.h"
|
||||
#include "chcore_timer_alt.h"
|
||||
#endif /* PORT_USE_ALT_TIMER != FALSE */
|
||||
#endif /* NIL_CFG_ST_TIMEDELTA > 0 */
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _NILCORE_H_ */
|
||||
#endif /* _CHCORE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/nilcore_timer.h
|
||||
* @file chcore_timer.h
|
||||
* @brief System timer header file.
|
||||
*
|
||||
* @addtogroup ARMCMx_TIMER
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_TIMER_H_
|
||||
#define _NILCORE_TIMER_H_
|
||||
#ifndef _CHCORE_TIMER_H_
|
||||
#define _CHCORE_TIMER_H_
|
||||
|
||||
/* This is the only header in the HAL designed to be include-able alone.*/
|
||||
#include "st.h"
|
||||
|
@ -119,6 +119,6 @@ static inline systime_t port_timer_get_alarm(void) {
|
|||
return stGetAlarm();
|
||||
}
|
||||
|
||||
#endif /* _NILCORE_TIMER_H_ */
|
||||
#endif /* _CHCORE_TIMER_H_ */
|
||||
|
||||
/** @} */
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file nilcore_v6m.c
|
||||
* @file chcore_v6m.c
|
||||
* @brief ARMv6-M architecture port code.
|
||||
*
|
||||
* @addtogroup ARMCMx_V6M_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "nil.h"
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
|
@ -129,7 +129,7 @@ void _port_irq_epilogue(regarm_t lr) {
|
|||
|
||||
/* The exit sequence is different depending on if a preemption is
|
||||
required or not.*/
|
||||
if (chSchIsRescRequiredI()) {
|
||||
if (chSchIsPreemptionRequired()) {
|
||||
/* Preemption is required we need to enforce a context switch.*/
|
||||
ctxp->pc = (regarm_t)_port_switch_from_isr;
|
||||
}
|
|
@ -33,10 +33,33 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief This port does not support a realtime counter.
|
||||
* @name Port Capabilities and Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
|
||||
/**
|
||||
* @brief Natural alignment constant.
|
||||
* @note It is the minimum alignment for pointer-size variables.
|
||||
*/
|
||||
#define PORT_NATURAL_ALIGN sizeof (void *)
|
||||
|
||||
/**
|
||||
* @brief Stack alignment constant.
|
||||
* @note It is the alignement required for the stack pointer.
|
||||
*/
|
||||
#define PORT_STACK_ALIGN sizeof (stkalign_t)
|
||||
|
||||
/**
|
||||
* @brief Working Areas alignment constant.
|
||||
* @note It is the alignment to be enforced for thread working areas.
|
||||
*/
|
||||
#define PORT_WORKING_AREA_ALIGN PORT_STACK_ALIGN
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief PendSV priority level.
|
||||
* @note This priority is enforced to be equal to @p 0,
|
||||
|
@ -66,13 +89,13 @@
|
|||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
* @note In this port this value is conservatively set to 32 because the
|
||||
* @note In this port this value is conservatively set to 64 because the
|
||||
* function @p chSchDoReschedule() can have a stack frame, especially
|
||||
* with compiler optimizations disabled. The value can be reduced
|
||||
* when compiler optimizations are enabled.
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK)
|
||||
#define PORT_INT_REQUIRED_STACK 32
|
||||
#define PORT_INT_REQUIRED_STACK 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -179,26 +202,37 @@ struct port_intctx {
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Platform dependent thread stack setup.
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||
(tp)->ctxp = (struct port_intctx *)((uint8_t *)(wend) - \
|
||||
sizeof(struct port_intctx)); \
|
||||
(tp)->ctxp->r4 = (regarm_t)(pf); \
|
||||
(tp)->ctxp->r5 = (regarm_t)(arg); \
|
||||
(tp)->ctxp->lr = (regarm_t)_port_thread_start; \
|
||||
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
|
||||
(tp)->ctx.r13 = (struct port_intctx *)((uint8_t *)(wtop) - \
|
||||
sizeof (struct port_intctx)); \
|
||||
(tp)->ctx.r13->r4 = (regarm_t)(pf); \
|
||||
(tp)->ctx.r13->r5 = (regarm_t)(arg); \
|
||||
(tp)->ctx.r13->lr = (regarm_t)_port_thread_start; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
* @note There is no need to perform alignments in this macro.
|
||||
*/
|
||||
#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \
|
||||
sizeof(struct port_extctx) + \
|
||||
#define PORT_WA_SIZE(n) (sizeof (struct port_intctx) + \
|
||||
sizeof (struct port_extctx) + \
|
||||
((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*
|
||||
* @param[in] s the name to be assigned to the stack array
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
*/
|
||||
#define PORT_WORKING_AREA(s, n) \
|
||||
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
* @details This macro must be inserted at the start of all IRQ handlers
|
||||
|
@ -246,12 +280,12 @@ struct port_intctx {
|
|||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#if (NIL_CFG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__)
|
||||
#if (CH_DBG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__)
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
#else
|
||||
#define port_switch(ntp, otp) { \
|
||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||
if ((stkalign_t *)(r13 - 1) < (otp)->stklim) { \
|
||||
if ((stkalign_t *)(r13 - 1) < (otp)->stklimit) { \
|
||||
chSysHalt("stack overflow"); \
|
||||
} \
|
||||
_port_switch(ntp, otp); \
|
||||
|
@ -266,10 +300,10 @@ struct port_intctx {
|
|||
extern "C" {
|
||||
#endif
|
||||
void _port_irq_epilogue(regarm_t lr);
|
||||
void _port_switch_from_isr(void);
|
||||
void _port_exit_from_isr(void);
|
||||
void _port_switch(thread_t *ntp, thread_t *otp);
|
||||
void _port_thread_start(void);
|
||||
void _port_switch_from_isr(void);
|
||||
void _port_exit_from_isr(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -302,8 +336,8 @@ static inline syssts_t port_get_irq_status(void) {
|
|||
* @param[in] sts the interrupt status word
|
||||
*
|
||||
* @return The interrupt status.
|
||||
* @retvel false the word specified a disabled interrupts status.
|
||||
* @retvel true the word specified an enabled interrupts status.
|
||||
* @retval false the word specified a disabled interrupts status.
|
||||
* @retval true the word specified an enabled interrupts status.
|
||||
*/
|
||||
static inline bool port_irq_enabled(syssts_t sts) {
|
||||
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file nilcore_v7m.c
|
||||
* @file chcore_v7m.c
|
||||
* @brief ARMv7-M architecture port code.
|
||||
*
|
||||
* @addtogroup ARMCMx_V7M_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "nil.h"
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
|
@ -63,7 +63,7 @@ void SVC_Handler(void) {
|
|||
/*lint -restore*/
|
||||
struct port_extctx *ctxp;
|
||||
|
||||
#if CORTEX_USE_FPU == TRUE
|
||||
#if CORTEX_USE_FPU
|
||||
/* Enforcing unstacking of the FP part of the context.*/
|
||||
FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk;
|
||||
#endif
|
||||
|
@ -95,7 +95,7 @@ void PendSV_Handler(void) {
|
|||
/*lint -restore*/
|
||||
struct port_extctx *ctxp;
|
||||
|
||||
#if CORTEX_USE_FPU == TRUE
|
||||
#if CORTEX_USE_FPU
|
||||
/* Enforcing unstacking of the FP part of the context.*/
|
||||
FPU->FPCCR &= ~FPU_FPCCR_LSPACT_Msk;
|
||||
#endif
|
||||
|
@ -139,13 +139,16 @@ void _port_irq_epilogue(void) {
|
|||
|
||||
/* Setting up a fake XPSR register value.*/
|
||||
ctxp->xpsr = (regarm_t)0x01000000;
|
||||
#if CORTEX_USE_FPU == TRUE
|
||||
ctxp->fpscr = (regarm_t)FPU->FPDSCR;
|
||||
#endif
|
||||
|
||||
/* Writing back the modified PSP value.*/
|
||||
__set_PSP((uint32_t)ctxp);
|
||||
|
||||
/* The exit sequence is different depending on if a preemption is
|
||||
required or not.*/
|
||||
if (chSchIsRescRequiredI()) {
|
||||
if (chSchIsPreemptionRequired()) {
|
||||
/* Preemption is required we need to enforce a context switch.*/
|
||||
ctxp->pc = (regarm_t)_port_switch_from_isr;
|
||||
}
|
|
@ -25,18 +25,42 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_V7M_H_
|
||||
#define _NILCORE_V7M_H_
|
||||
#ifndef _CHCORE_V7M_H_
|
||||
#define _CHCORE_V7M_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Port Capabilities and Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT TRUE
|
||||
|
||||
/**
|
||||
* @brief Natural alignment constant.
|
||||
* @note It is the minimum alignment for pointer-size variables.
|
||||
*/
|
||||
#define PORT_NATURAL_ALIGN sizeof (void *)
|
||||
|
||||
/**
|
||||
* @brief Stack alignment constant.
|
||||
* @note It is the alignement required for the stack pointer.
|
||||
*/
|
||||
#define PORT_STACK_ALIGN sizeof (stkalign_t)
|
||||
|
||||
/**
|
||||
* @brief Working Areas alignment constant.
|
||||
* @note It is the alignment to be enforced for thread working areas.
|
||||
*/
|
||||
#define PORT_WORKING_AREA_ALIGN (PORT_ENABLE_GUARD_PAGES == TRUE ? \
|
||||
32U : PORT_STACK_ALIGN)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Disabled value for BASEPRI register.
|
||||
*/
|
||||
|
@ -46,6 +70,17 @@
|
|||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables stack overflow guard pages using MPU.
|
||||
* @note This option can only be enabled if also option
|
||||
* @p CH_DBG_ENABLE_STACK_CHECK is enabled.
|
||||
* @note The use of this option has an overhead of 32 bytes for each
|
||||
* thread.
|
||||
*/
|
||||
#if !defined(PORT_ENABLE_GUARD_PAGES) || defined(__DOXYGEN__)
|
||||
#define PORT_ENABLE_GUARD_PAGES FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Stack size for the system idle thread.
|
||||
* @details This size depends on the idle thread implementation, usually
|
||||
|
@ -63,13 +98,13 @@
|
|||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
* @note In this port this value is conservatively set to 32 because the
|
||||
* @note In this port this value is conservatively set to 64 because the
|
||||
* function @p chSchDoReschedule() can have a stack frame, especially
|
||||
* with compiler optimizations disabled. The value can be reduced
|
||||
* when compiler optimizations are enabled.
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
|
||||
#define PORT_INT_REQUIRED_STACK 32
|
||||
#define PORT_INT_REQUIRED_STACK 64
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -135,6 +170,23 @@
|
|||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(_FROM_ASM_)
|
||||
/**
|
||||
* @brief MPU guard page size.
|
||||
*/
|
||||
#if (PORT_ENABLE_GUARD_PAGES == TRUE) || defined(__DOXYGEN__)
|
||||
#if CH_DBG_ENABLE_STACK_CHECK == FALSE
|
||||
#error "PORT_ENABLE_GUARD_PAGES requires CH_DBG_ENABLE_STACK_CHECK"
|
||||
#endif
|
||||
#if __MPU_PRESENT == 0
|
||||
#error "MPU not present in current device"
|
||||
#endif
|
||||
#define PORT_GUARD_PAGE_SIZE 32U
|
||||
#else
|
||||
#define PORT_GUARD_PAGE_SIZE 0U
|
||||
#endif
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
/**
|
||||
* @name Architecture and Compiler
|
||||
* @{
|
||||
|
@ -153,25 +205,45 @@
|
|||
/**
|
||||
* @brief Name of the architecture variant.
|
||||
*/
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M3"
|
||||
#if (PORT_ENABLE_GUARD_PAGES == FALSE) || defined(__DOXYGEN__)
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M3"
|
||||
#else
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M3 (MPU)"
|
||||
#endif
|
||||
|
||||
#elif (CORTEX_MODEL == 4)
|
||||
#define PORT_ARCHITECTURE_ARM_v7ME
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv7E-M"
|
||||
#if CORTEX_USE_FPU
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M4F"
|
||||
#else
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M4"
|
||||
#endif
|
||||
#define PORT_ARCHITECTURE_ARM_v7ME
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv7E-M"
|
||||
#if CORTEX_USE_FPU
|
||||
#if PORT_ENABLE_GUARD_PAGES == FALSE
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M4F"
|
||||
#else
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M4F (MPU)"
|
||||
#endif
|
||||
#else
|
||||
#if PORT_ENABLE_GUARD_PAGES == FALSE
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M4"
|
||||
#else
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M4 (MPU)"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif (CORTEX_MODEL == 7)
|
||||
#define PORT_ARCHITECTURE_ARM_v7ME
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv7E-M"
|
||||
#if CORTEX_USE_FPU
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M7F"
|
||||
#else
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M7"
|
||||
#endif
|
||||
#define PORT_ARCHITECTURE_ARM_v7ME
|
||||
#define PORT_ARCHITECTURE_NAME "ARMv7E-M"
|
||||
#if CORTEX_USE_FPU
|
||||
#if PORT_ENABLE_GUARD_PAGES == FALSE
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M7F"
|
||||
#else
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M7F (MPU)"
|
||||
#endif
|
||||
#else
|
||||
#if PORT_ENABLE_GUARD_PAGES == FALSE
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M7"
|
||||
#else
|
||||
#define PORT_CORE_VARIANT_NAME "Cortex-M7 (MPU)"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -290,21 +362,39 @@ struct port_intctx {
|
|||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||
(tp)->ctxp = (struct port_intctx *)((uint8_t *)(wend) - \
|
||||
sizeof(struct port_intctx)); \
|
||||
(tp)->ctxp->r4 = (regarm_t)(pf); \
|
||||
(tp)->ctxp->r5 = (regarm_t)(arg); \
|
||||
(tp)->ctxp->lr = (regarm_t)_port_thread_start; \
|
||||
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
|
||||
(tp)->ctx.r13 = (struct port_intctx *)((uint8_t *)(wtop) - \
|
||||
sizeof (struct port_intctx)); \
|
||||
(tp)->ctx.r13->r4 = (regarm_t)(pf); \
|
||||
(tp)->ctx.r13->r5 = (regarm_t)(arg); \
|
||||
(tp)->ctx.r13->lr = (regarm_t)_port_thread_start; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
* @note There is no need to perform alignments in this macro.
|
||||
*/
|
||||
#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \
|
||||
sizeof(struct port_extctx) + \
|
||||
((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
|
||||
#define PORT_WA_SIZE(n) ((size_t)PORT_GUARD_PAGE_SIZE + \
|
||||
sizeof (struct port_intctx) + \
|
||||
sizeof (struct port_extctx) + \
|
||||
(size_t)(n) + \
|
||||
(size_t)PORT_INT_REQUIRED_STACK)
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*
|
||||
* @param[in] s the name to be assigned to the stack array
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
*/
|
||||
#if (PORT_ENABLE_GUARD_PAGES == FALSE) || defined(__DOXYGEN__)
|
||||
#define PORT_WORKING_AREA(s, n) \
|
||||
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
|
||||
#else
|
||||
#define PORT_WORKING_AREA(s, n) \
|
||||
ALIGNED_VAR(32) stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
|
@ -344,16 +434,30 @@ struct port_intctx {
|
|||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#if (NIL_CFG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__)
|
||||
#if (CH_DBG_ENABLE_STACK_CHECK == FALSE) || defined(__DOXYGEN__)
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
#else
|
||||
#if PORT_ENABLE_GUARD_PAGES == FALSE
|
||||
#define port_switch(ntp, otp) { \
|
||||
struct port_intctx *r13 = (struct port_intctx *)__get_PSP(); \
|
||||
if ((stkalign_t *)(r13 - 1) < (otp)->stklim) { \
|
||||
if ((stkalign_t *)(r13 - 1) < (otp)->stklimit) { \
|
||||
chSysHalt("stack overflow"); \
|
||||
} \
|
||||
_port_switch(ntp, otp); \
|
||||
}
|
||||
#else
|
||||
#define port_switch(ntp, otp) { \
|
||||
_port_switch(ntp, otp); \
|
||||
\
|
||||
/* Setting up the guard page for the switched-in thread.*/ \
|
||||
mpuConfigureRegion(MPU_REGION_0, \
|
||||
chThdGetSelfX()->stklimit, \
|
||||
MPU_RASR_ATTR_AP_NA_NA | \
|
||||
MPU_RASR_ATTR_NON_CACHEABLE | \
|
||||
MPU_RASR_SIZE_32 | \
|
||||
MPU_RASR_ENABLE); \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -387,7 +491,7 @@ static inline void port_init(void) {
|
|||
/* Initializing priority grouping.*/
|
||||
NVIC_SetPriorityGrouping(CORTEX_PRIGROUP_INIT);
|
||||
|
||||
/* DWT cycle counter enable.*/
|
||||
/* DWT cycle counter enable, note, the M7 requires DWT unlocking.*/
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
#if CORTEX_MODEL == 7
|
||||
DWT->LAR = 0xC5ACCE55U;
|
||||
|
@ -399,6 +503,24 @@ static inline void port_init(void) {
|
|||
NVIC_SetPriority(SVCall_IRQn, CORTEX_PRIORITY_SVCALL);
|
||||
#endif
|
||||
NVIC_SetPriority(PendSV_IRQn, CORTEX_PRIORITY_PENDSV);
|
||||
|
||||
#if PORT_ENABLE_GUARD_PAGES == TRUE
|
||||
{
|
||||
extern stkalign_t __main_thread_stack_base__;
|
||||
|
||||
/* Setting up the guard page on the main() function stack base
|
||||
initially.*/
|
||||
mpuConfigureRegion(MPU_REGION_0,
|
||||
&__main_thread_stack_base__,
|
||||
MPU_RASR_ATTR_AP_NA_NA |
|
||||
MPU_RASR_ATTR_NON_CACHEABLE |
|
||||
MPU_RASR_SIZE_32 |
|
||||
MPU_RASR_ENABLE);
|
||||
|
||||
/* MPU is enabled.*/
|
||||
mpuEnable(MPU_CTRL_PRIVDEFENA);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -423,8 +545,8 @@ static inline syssts_t port_get_irq_status(void) {
|
|||
* @param[in] sts the interrupt status word
|
||||
*
|
||||
* @return The interrupt status.
|
||||
* @retvel false the word specified a disabled interrupts status.
|
||||
* @retvel true the word specified an enabled interrupts status.
|
||||
* @retval false the word specified a disabled interrupts status.
|
||||
* @retval true the word specified an enabled interrupts status.
|
||||
*/
|
||||
static inline bool port_irq_enabled(syssts_t sts) {
|
||||
|
||||
|
@ -456,13 +578,13 @@ static inline void port_lock(void) {
|
|||
|
||||
#if CORTEX_SIMPLIFIED_PRIORITY == FALSE
|
||||
#if defined(__CM7_REV)
|
||||
#if __CM7_REV == 0
|
||||
#if __CM7_REV <= 1
|
||||
__disable_irq();
|
||||
#endif
|
||||
#endif
|
||||
__set_BASEPRI(CORTEX_BASEPRI_KERNEL);
|
||||
#if defined(__CM7_REV)
|
||||
#if __CM7_REV == 0
|
||||
#if __CM7_REV <= 1
|
||||
__enable_irq();
|
||||
#endif
|
||||
#endif
|
||||
|
@ -571,6 +693,6 @@ static inline rtcnt_t port_rt_get_counter_value(void) {
|
|||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _NILCORE_V7M_H_ */
|
||||
#endif /* _CHCORE_V7M_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,554 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Concepts and parts of this file have been contributed by Andre R.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cmsis_os.c
|
||||
* @brief CMSIS RTOS module code.
|
||||
*
|
||||
* @addtogroup CMSIS_OS
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "cmsis_os.h"
|
||||
#include <string.h>
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
int32_t cmsis_os_started;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static memory_pool_t sempool;
|
||||
static semaphore_t semaphores[CMSIS_CFG_NUM_SEMAPHORES];
|
||||
|
||||
static memory_pool_t timpool;
|
||||
static struct os_timer_cb timers[CMSIS_CFG_NUM_TIMERS];
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Virtual timers common callback.
|
||||
*/
|
||||
static void timer_cb(void const *arg) {
|
||||
|
||||
osTimerId timer_id = (osTimerId)arg;
|
||||
timer_id->ptimer(timer_id->argument);
|
||||
if (timer_id->type == osTimerPeriodic) {
|
||||
chSysLockFromISR();
|
||||
chVTDoSetI(&timer_id->vt, MS2ST(timer_id->millisec),
|
||||
(vtfunc_t)timer_cb, timer_id);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Kernel initialization.
|
||||
*/
|
||||
osStatus osKernelInitialize(void) {
|
||||
|
||||
cmsis_os_started = 0;
|
||||
|
||||
chSysInit();
|
||||
chThdSetPriority(HIGHPRIO);
|
||||
|
||||
chPoolObjectInit(&sempool, sizeof(semaphore_t), chCoreAlloc);
|
||||
chPoolLoadArray(&sempool, semaphores, CMSIS_CFG_NUM_SEMAPHORES);
|
||||
|
||||
chPoolObjectInit(&timpool, sizeof(virtual_timer_t), chCoreAlloc);
|
||||
chPoolLoadArray(&timpool, timers, CMSIS_CFG_NUM_TIMERS);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel start.
|
||||
*/
|
||||
osStatus osKernelStart(void) {
|
||||
|
||||
cmsis_os_started = 1;
|
||||
|
||||
chThdSetPriority(NORMALPRIO);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a thread.
|
||||
*/
|
||||
osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument) {
|
||||
size_t size;
|
||||
|
||||
size = thread_def->stacksize == 0 ? CMSIS_CFG_DEFAULT_STACK :
|
||||
thread_def->stacksize;
|
||||
return (osThreadId)chThdCreateFromHeap(0,
|
||||
THD_WORKING_AREA_SIZE(size),
|
||||
NORMALPRIO+thread_def->tpriority,
|
||||
(tfunc_t)thread_def->pthread,
|
||||
argument);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Thread termination.
|
||||
* @note The thread is not really terminated but asked to terminate which
|
||||
* is not compliant.
|
||||
*/
|
||||
osStatus osThreadTerminate(osThreadId thread_id) {
|
||||
|
||||
if (thread_id == osThreadGetId()) {
|
||||
/* Note, no memory will be recovered unless a cleaner thread is
|
||||
implemented using the registry.*/
|
||||
chThdExit(0);
|
||||
}
|
||||
chThdTerminate(thread_id);
|
||||
chThdWait((thread_t *)thread_id);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change thread priority.
|
||||
* @note This can interfere with the priority inheritance mechanism.
|
||||
*/
|
||||
osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio) {
|
||||
osPriority oldprio;
|
||||
thread_t * tp = (thread_t *)thread_id;
|
||||
|
||||
chSysLock();
|
||||
|
||||
/* Changing priority.*/
|
||||
#if CH_CFG_USE_MUTEXES
|
||||
oldprio = (osPriority)tp->p_realprio;
|
||||
if ((tp->p_prio == tp->p_realprio) || ((tprio_t)newprio > tp->p_prio))
|
||||
tp->p_prio = (tprio_t)newprio;
|
||||
tp->p_realprio = (tprio_t)newprio;
|
||||
#else
|
||||
oldprio = tp->p_prio;
|
||||
tp->p_prio = (tprio_t)newprio;
|
||||
#endif
|
||||
|
||||
/* The following states need priority queues reordering.*/
|
||||
switch (tp->p_state) {
|
||||
#if CH_CFG_USE_MUTEXES | \
|
||||
CH_CFG_USE_CONDVARS | \
|
||||
(CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY) | \
|
||||
(CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY)
|
||||
#if CH_CFG_USE_MUTEXES
|
||||
case CH_STATE_WTMTX:
|
||||
#endif
|
||||
#if CH_CFG_USE_CONDVARS
|
||||
case CH_STATE_WTCOND:
|
||||
#endif
|
||||
#if CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY
|
||||
case CH_STATE_WTSEM:
|
||||
#endif
|
||||
#if CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY
|
||||
case CH_STATE_SNDMSGQ:
|
||||
#endif
|
||||
/* Re-enqueues tp with its new priority on the queue.*/
|
||||
queue_prio_insert(queue_dequeue(tp),
|
||||
(threads_queue_t *)tp->p_u.wtobjp);
|
||||
break;
|
||||
#endif
|
||||
case CH_STATE_READY:
|
||||
#if CH_DBG_ENABLE_ASSERTS
|
||||
/* Prevents an assertion in chSchReadyI().*/
|
||||
tp->p_state = CH_STATE_CURRENT;
|
||||
#endif
|
||||
/* Re-enqueues tp with its new priority on the ready list.*/
|
||||
chSchReadyI(queue_dequeue(tp));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Rescheduling.*/
|
||||
chSchRescheduleS();
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return oldprio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a timer.
|
||||
*/
|
||||
osTimerId osTimerCreate(const osTimerDef_t *timer_def,
|
||||
os_timer_type type,
|
||||
void *argument) {
|
||||
|
||||
osTimerId timer = chPoolAlloc(&timpool);
|
||||
chVTObjectInit(&timer->vt);
|
||||
timer->ptimer = timer_def->ptimer;
|
||||
timer->type = type;
|
||||
timer->argument = argument;
|
||||
return timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a timer.
|
||||
*/
|
||||
osStatus osTimerStart(osTimerId timer_id, uint32_t millisec) {
|
||||
|
||||
if ((millisec == 0) || (millisec == osWaitForever))
|
||||
return osErrorValue;
|
||||
|
||||
timer_id->millisec = millisec;
|
||||
chVTSet(&timer_id->vt, MS2ST(millisec), (vtfunc_t)timer_cb, timer_id);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop a timer.
|
||||
*/
|
||||
osStatus osTimerStop(osTimerId timer_id) {
|
||||
|
||||
chVTReset(&timer_id->vt);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete a timer.
|
||||
*/
|
||||
osStatus osTimerDelete(osTimerId timer_id) {
|
||||
|
||||
chVTReset(&timer_id->vt);
|
||||
chPoolFree(&timpool, (void *)timer_id);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send signals.
|
||||
*/
|
||||
int32_t osSignalSet(osThreadId thread_id, int32_t signals) {
|
||||
int32_t oldsignals;
|
||||
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
oldsignals = (int32_t)thread_id->p_epending;
|
||||
chEvtSignalI((thread_t *)thread_id, (eventmask_t)signals);
|
||||
chSysRestoreStatusX(sts);
|
||||
|
||||
return oldsignals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear signals.
|
||||
*/
|
||||
int32_t osSignalClear(osThreadId thread_id, int32_t signals) {
|
||||
eventmask_t m;
|
||||
|
||||
chSysLock();
|
||||
|
||||
m = thread_id->p_epending & (eventmask_t)signals;
|
||||
thread_id->p_epending &= ~(eventmask_t)signals;
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return (int32_t)m;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for signals.
|
||||
*/
|
||||
osEvent osSignalWait(int32_t signals, uint32_t millisec) {
|
||||
osEvent event;
|
||||
systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
|
||||
TIME_INFINITE : MS2ST(millisec);
|
||||
|
||||
if (signals == 0)
|
||||
event.value.signals = (uint32_t)chEvtWaitAnyTimeout(ALL_EVENTS, timeout);
|
||||
else
|
||||
event.value.signals = (uint32_t)chEvtWaitAllTimeout((eventmask_t)signals,
|
||||
timeout);
|
||||
|
||||
/* Type of event.*/
|
||||
if (event.value.signals == 0)
|
||||
event.status = osEventTimeout;
|
||||
else
|
||||
event.status = osEventSignal;
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a semaphore.
|
||||
* @note @p semaphore_def is not used.
|
||||
* @note Can involve memory allocation.
|
||||
*/
|
||||
osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def,
|
||||
int32_t count) {
|
||||
|
||||
(void)semaphore_def;
|
||||
|
||||
semaphore_t *sem = chPoolAlloc(&sempool);
|
||||
chSemObjectInit(sem, (cnt_t)count);
|
||||
return sem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait on a semaphore.
|
||||
*/
|
||||
int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec) {
|
||||
systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
|
||||
TIME_INFINITE : MS2ST(millisec);
|
||||
|
||||
msg_t msg = chSemWaitTimeout((semaphore_t *)semaphore_id, timeout);
|
||||
switch (msg) {
|
||||
case MSG_OK:
|
||||
return osOK;
|
||||
case MSG_TIMEOUT:
|
||||
return osErrorTimeoutResource;
|
||||
}
|
||||
return osErrorResource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a semaphore.
|
||||
*/
|
||||
osStatus osSemaphoreRelease(osSemaphoreId semaphore_id) {
|
||||
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
chSemSignalI((semaphore_t *)semaphore_id);
|
||||
chSysRestoreStatusX(sts);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deletes a semaphore.
|
||||
* @note After deletion there could be references in the system to a
|
||||
* non-existent semaphore.
|
||||
*/
|
||||
osStatus osSemaphoreDelete(osSemaphoreId semaphore_id) {
|
||||
|
||||
chSemReset((semaphore_t *)semaphore_id, 0);
|
||||
chPoolFree(&sempool, (void *)semaphore_id);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a mutex.
|
||||
* @note @p mutex_def is not used.
|
||||
* @note Can involve memory allocation.
|
||||
*/
|
||||
osMutexId osMutexCreate(const osMutexDef_t *mutex_def) {
|
||||
|
||||
(void)mutex_def;
|
||||
|
||||
binary_semaphore_t *mtx = chPoolAlloc(&sempool);
|
||||
chBSemObjectInit(mtx, false);
|
||||
return mtx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait on a mutex.
|
||||
*/
|
||||
osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec) {
|
||||
systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
|
||||
TIME_INFINITE : MS2ST(millisec);
|
||||
|
||||
msg_t msg = chBSemWaitTimeout((binary_semaphore_t *)mutex_id, timeout);
|
||||
switch (msg) {
|
||||
case MSG_OK:
|
||||
return osOK;
|
||||
case MSG_TIMEOUT:
|
||||
return osErrorTimeoutResource;
|
||||
}
|
||||
return osErrorResource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release a mutex.
|
||||
*/
|
||||
osStatus osMutexRelease(osMutexId mutex_id) {
|
||||
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
chBSemSignalI((binary_semaphore_t *)mutex_id);
|
||||
chSysRestoreStatusX(sts);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deletes a mutex.
|
||||
* @note After deletion there could be references in the system to a
|
||||
* non-existent semaphore.
|
||||
*/
|
||||
osStatus osMutexDelete(osMutexId mutex_id) {
|
||||
|
||||
chSemReset((semaphore_t *)mutex_id, 0);
|
||||
chPoolFree(&sempool, (void *)mutex_id);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a memory pool.
|
||||
* @note The pool is not really created because it is allocated statically,
|
||||
* this function just re-initializes it.
|
||||
*/
|
||||
osPoolId osPoolCreate(const osPoolDef_t *pool_def) {
|
||||
|
||||
chPoolObjectInit(pool_def->pool, (size_t)pool_def->item_sz, NULL);
|
||||
chPoolLoadArray(pool_def->pool, pool_def->items, (size_t)pool_def->pool_sz);
|
||||
|
||||
return (osPoolId)pool_def->pool;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate an object.
|
||||
*/
|
||||
void *osPoolAlloc(osPoolId pool_id) {
|
||||
void *object;
|
||||
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
object = chPoolAllocI((memory_pool_t *)pool_id);
|
||||
chSysRestoreStatusX(sts);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate an object clearing it.
|
||||
*/
|
||||
void *osPoolCAlloc(osPoolId pool_id) {
|
||||
void *object;
|
||||
|
||||
object = chPoolAllocI((memory_pool_t *)pool_id);
|
||||
memset(object, 0, pool_id->mp_object_size);
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free an object.
|
||||
*/
|
||||
osStatus osPoolFree(osPoolId pool_id, void *block) {
|
||||
|
||||
syssts_t sts = chSysGetStatusAndLockX();
|
||||
chPoolFreeI((memory_pool_t *)pool_id, block);
|
||||
chSysRestoreStatusX(sts);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a message queue.
|
||||
* @note The queue is not really created because it is allocated statically,
|
||||
* this function just re-initializes it.
|
||||
*/
|
||||
osMessageQId osMessageCreate(const osMessageQDef_t *queue_def,
|
||||
osThreadId thread_id) {
|
||||
|
||||
/* Ignoring this parameter for now.*/
|
||||
(void)thread_id;
|
||||
|
||||
if (queue_def->item_sz > sizeof (msg_t))
|
||||
return NULL;
|
||||
|
||||
chMBObjectInit(queue_def->mailbox,
|
||||
queue_def->items,
|
||||
(size_t)queue_def->queue_sz);
|
||||
|
||||
return (osMessageQId) queue_def->mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Put a message in the queue.
|
||||
*/
|
||||
osStatus osMessagePut(osMessageQId queue_id,
|
||||
uint32_t info,
|
||||
uint32_t millisec) {
|
||||
msg_t msg;
|
||||
systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
|
||||
TIME_INFINITE : MS2ST(millisec);
|
||||
|
||||
if (port_is_isr_context()) {
|
||||
|
||||
/* Waiting makes no sense in ISRs so any value except "immediate"
|
||||
makes no sense.*/
|
||||
if (millisec != 0)
|
||||
return osErrorValue;
|
||||
|
||||
chSysLockFromISR();
|
||||
msg = chMBPostI((mailbox_t *)queue_id, (msg_t)info);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
else
|
||||
msg = chMBPost((mailbox_t *)queue_id, (msg_t)info, timeout);
|
||||
|
||||
return msg == MSG_OK ? osOK : osEventTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a message from the queue.
|
||||
*/
|
||||
osEvent osMessageGet(osMessageQId queue_id,
|
||||
uint32_t millisec) {
|
||||
msg_t msg;
|
||||
osEvent event;
|
||||
systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
|
||||
TIME_INFINITE : MS2ST(millisec);
|
||||
|
||||
event.def.message_id = queue_id;
|
||||
|
||||
if (port_is_isr_context()) {
|
||||
|
||||
/* Waiting makes no sense in ISRs so any value except "immediate"
|
||||
makes no sense.*/
|
||||
if (millisec != 0) {
|
||||
event.status = osErrorValue;
|
||||
return event;
|
||||
}
|
||||
|
||||
chSysLockFromISR();
|
||||
msg = chMBFetchI((mailbox_t *)queue_id, (msg_t*)&event.value.v);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
else {
|
||||
msg = chMBFetch((mailbox_t *)queue_id, (msg_t*)&event.value.v, timeout);
|
||||
}
|
||||
|
||||
/* Returned event type.*/
|
||||
event.status = msg == MSG_OK ? osEventMessage : osEventTimeout;
|
||||
return event;
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,520 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/*
|
||||
Concepts and parts of this file have been contributed by Andre R.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file cmsis_os.h
|
||||
* @brief CMSIS RTOS module macros and structures.
|
||||
*
|
||||
* @addtogroup CMSIS_OS
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CMSIS_OS_H_
|
||||
#define _CMSIS_OS_H_
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief API version.
|
||||
*/
|
||||
#define osCMSIS 0x10002
|
||||
|
||||
/**
|
||||
* @brief Kernel version.
|
||||
*/
|
||||
#define osKernelSystemId "KERNEL V1.00"
|
||||
|
||||
/**
|
||||
* @brief ChibiOS/RT version encoded for CMSIS.
|
||||
*/
|
||||
#define osCMSIS_KERNEL ((CH_KERNEL_MAJOR << 16) | \
|
||||
(CH_KERNEL_MINOR << 8) | \
|
||||
(CH_KERNEL_PATCH))
|
||||
|
||||
/**
|
||||
* @name CMSIS Capabilities
|
||||
* @{
|
||||
*/
|
||||
#define osFeature_MainThread 1
|
||||
#define osFeature_Pool 1
|
||||
#define osFeature_MailQ 0
|
||||
#define osFeature_MessageQ 1
|
||||
#define osFeature_Signals 24
|
||||
#define osFeature_Semaphore ((1U << 31) - 1U)
|
||||
#define osFeature_Wait 0
|
||||
#define osFeature_SysTick 1
|
||||
/**< @} */
|
||||
|
||||
/**
|
||||
* @brief Wait forever specification for timeouts.
|
||||
*/
|
||||
#define osWaitForever TIME_INFINITE
|
||||
|
||||
/**
|
||||
* @brief System tick frequency.
|
||||
*/
|
||||
#define osKernelSysTickFrequency CH_CFG_FREQUENCY
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of pre-allocated static semaphores/mutexes.
|
||||
*/
|
||||
#if !defined(CMSIS_CFG_DEFAULT_STACK)
|
||||
#define CMSIS_CFG_DEFAULT_STACK 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of pre-allocated static semaphores/mutexes.
|
||||
*/
|
||||
#if !defined(CMSIS_CFG_NUM_SEMAPHORES)
|
||||
#define CMSIS_CFG_NUM_SEMAPHORES 4
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of pre-allocated static timers.
|
||||
*/
|
||||
#if !defined(CMSIS_CFG_NUM_TIMERS)
|
||||
#define CMSIS_CFG_NUM_TIMERS 4
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !CH_CFG_USE_MEMPOOLS
|
||||
#error "CMSIS RTOS requires CH_CFG_USE_MEMPOOLS"
|
||||
#endif
|
||||
|
||||
#if !CH_CFG_USE_EVENTS
|
||||
#error "CMSIS RTOS requires CH_CFG_USE_EVENTS"
|
||||
#endif
|
||||
|
||||
#if !CH_CFG_USE_EVENTS_TIMEOUT
|
||||
#error "CMSIS RTOS requires CH_CFG_USE_EVENTS_TIMEOUT"
|
||||
#endif
|
||||
|
||||
#if !CH_CFG_USE_SEMAPHORES
|
||||
#error "CMSIS RTOS requires CH_CFG_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
#if !CH_CFG_USE_DYNAMIC
|
||||
#error "CMSIS RTOS requires CH_CFG_USE_DYNAMIC"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of priority levels.
|
||||
*/
|
||||
typedef enum {
|
||||
osPriorityIdle = -3,
|
||||
osPriorityLow = -2,
|
||||
osPriorityBelowNormal = -1,
|
||||
osPriorityNormal = 0,
|
||||
osPriorityAboveNormal = +1,
|
||||
osPriorityHigh = +2,
|
||||
osPriorityRealtime = +3,
|
||||
osPriorityError = 0x84
|
||||
} osPriority;
|
||||
|
||||
/**
|
||||
* @brief Type of error codes.
|
||||
*/
|
||||
typedef enum {
|
||||
osOK = 0,
|
||||
osEventSignal = 0x08,
|
||||
osEventMessage = 0x10,
|
||||
osEventMail = 0x20,
|
||||
osEventTimeout = 0x40,
|
||||
osErrorParameter = 0x80,
|
||||
osErrorResource = 0x81,
|
||||
osErrorTimeoutResource = 0xC1,
|
||||
osErrorISR = 0x82,
|
||||
osErrorISRRecursive = 0x83,
|
||||
osErrorPriority = 0x84,
|
||||
osErrorNoMemory = 0x85,
|
||||
osErrorValue = 0x86,
|
||||
osErrorOS = 0xFF,
|
||||
os_status_reserved = 0x7FFFFFFF
|
||||
} osStatus;
|
||||
|
||||
/**
|
||||
* @brief Type of a timer mode.
|
||||
*/
|
||||
typedef enum {
|
||||
osTimerOnce = 0,
|
||||
osTimerPeriodic = 1
|
||||
} os_timer_type;
|
||||
|
||||
/**
|
||||
* @brief Type of thread functions.
|
||||
*/
|
||||
typedef void (*os_pthread) (void const *argument);
|
||||
|
||||
/**
|
||||
* @brief Type of timer callback.
|
||||
*/
|
||||
typedef void (*os_ptimer) (void const *argument);
|
||||
|
||||
/**
|
||||
* @brief Type of pointer to thread control block.
|
||||
*/
|
||||
typedef thread_t *osThreadId;
|
||||
|
||||
/**
|
||||
* @brief Type of pointer to timer control block.
|
||||
*/
|
||||
typedef struct os_timer_cb {
|
||||
virtual_timer_t vt;
|
||||
os_timer_type type;
|
||||
os_ptimer ptimer;
|
||||
void *argument;
|
||||
uint32_t millisec;
|
||||
} *osTimerId;
|
||||
|
||||
/**
|
||||
* @brief Type of pointer to mutex control block.
|
||||
*/
|
||||
typedef binary_semaphore_t *osMutexId;
|
||||
|
||||
/**
|
||||
* @brief Type of pointer to semaphore control block.
|
||||
*/
|
||||
typedef semaphore_t *osSemaphoreId;
|
||||
|
||||
/**
|
||||
* @brief Type of pointer to memory pool control block.
|
||||
*/
|
||||
typedef memory_pool_t *osPoolId;
|
||||
|
||||
/**
|
||||
* @brief Type of pointer to message queue control block.
|
||||
*/
|
||||
typedef struct mailbox *osMessageQId;
|
||||
|
||||
/**
|
||||
* @brief Type of an event.
|
||||
*/
|
||||
typedef struct {
|
||||
osStatus status;
|
||||
union {
|
||||
uint32_t v;
|
||||
void *p;
|
||||
int32_t signals;
|
||||
} value;
|
||||
union {
|
||||
/* osMailQId mail_id;*/
|
||||
osMessageQId message_id;
|
||||
} def;
|
||||
} osEvent;
|
||||
|
||||
/**
|
||||
* @brief Type of a thread definition block.
|
||||
*/
|
||||
typedef struct os_thread_def {
|
||||
os_pthread pthread;
|
||||
osPriority tpriority;
|
||||
uint32_t stacksize;
|
||||
} osThreadDef_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a timer definition block.
|
||||
*/
|
||||
typedef struct os_timer_def {
|
||||
os_ptimer ptimer;
|
||||
} osTimerDef_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a mutex definition block.
|
||||
*/
|
||||
typedef struct os_mutex_def {
|
||||
uint32_t dummy;
|
||||
} osMutexDef_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a semaphore definition block.
|
||||
*/
|
||||
typedef struct os_semaphore_def {
|
||||
uint32_t dummy;
|
||||
} osSemaphoreDef_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a memory pool definition block.
|
||||
*/
|
||||
typedef struct os_pool_def {
|
||||
uint32_t pool_sz;
|
||||
uint32_t item_sz;
|
||||
memory_pool_t *pool;
|
||||
void *items;
|
||||
} osPoolDef_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a message queue definition block.
|
||||
*/
|
||||
typedef struct os_messageQ_def {
|
||||
uint32_t queue_sz;
|
||||
uint32_t item_sz;
|
||||
mailbox_t *mailbox;
|
||||
void *items;
|
||||
} osMessageQDef_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Convert a microseconds value to a RTOS kernel system timer value.
|
||||
*/
|
||||
#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * \
|
||||
(osKernelSysTickFrequency)) / \
|
||||
1000000)
|
||||
|
||||
/**
|
||||
* @brief Create a Thread definition.
|
||||
*/
|
||||
#if defined(osObjectsExternal)
|
||||
#define osThreadDef(name, priority, instances, stacksz) \
|
||||
extern const osThreadDef_t os_thread_def_##name
|
||||
#else
|
||||
#define osThreadDef(name, priority, stacksz) \
|
||||
const osThreadDef_t os_thread_def_##name = { \
|
||||
(name), \
|
||||
(priority), \
|
||||
(stacksz) \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Access a Thread definition.
|
||||
*/
|
||||
#define osThread(name) &os_thread_def_##name
|
||||
|
||||
/**
|
||||
* @brief Define a Timer object.
|
||||
*/
|
||||
#if defined(osObjectsExternal)
|
||||
#define osTimerDef(name, function) \
|
||||
extern const osTimerDef_t os_timer_def_##name
|
||||
#else
|
||||
#define osTimerDef(name, function) \
|
||||
const osTimerDef_t os_timer_def_##name = { \
|
||||
(function) \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Access a Timer definition.
|
||||
*/
|
||||
#define osTimer(name) &os_timer_def_##name
|
||||
|
||||
/**
|
||||
* @brief Define a Mutex.
|
||||
*/
|
||||
#if defined(osObjectsExternal)
|
||||
#define osMutexDef(name) extern const osMutexDef_t os_mutex_def_##name
|
||||
#else
|
||||
#define osMutexDef(name) const osMutexDef_t os_mutex_def_##name = {0}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Access a Mutex definition.
|
||||
*/
|
||||
#define osMutex(name) &os_mutex_def_##name
|
||||
|
||||
/**
|
||||
* @brief Define a Semaphore.
|
||||
*/
|
||||
#if defined(osObjectsExternal)
|
||||
#define osSemaphoreDef(name) \
|
||||
extern const osSemaphoreDef_t os_semaphore_def_##name
|
||||
#else // define the object
|
||||
#define osSemaphoreDef(name) \
|
||||
const osSemaphoreDef_t os_semaphore_def_##name = {0}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Access a Semaphore definition.
|
||||
*/
|
||||
#define osSemaphore(name) &os_semaphore_def_##name
|
||||
|
||||
/**
|
||||
* @brief Define a Memory Pool.
|
||||
*/
|
||||
#if defined(osObjectsExternal)
|
||||
#define osPoolDef(name, no, type) \
|
||||
extern const osPoolDef_t os_pool_def_##name
|
||||
#else
|
||||
#define osPoolDef(name, no, type) \
|
||||
static const type os_pool_buf_##name[no]; \
|
||||
static memory_pool_t os_pool_obj_##name; \
|
||||
const osPoolDef_t os_pool_def_##name = { \
|
||||
(no), \
|
||||
sizeof (type), \
|
||||
(void *)&os_pool_obj_##name, \
|
||||
(void *)&os_pool_buf_##name[0] \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Access a Memory Pool definition.
|
||||
*/
|
||||
#define osPool(name) &os_pool_def_##name
|
||||
|
||||
/**
|
||||
* @brief Define a Message Queue.
|
||||
*/
|
||||
#if defined(osObjectsExternal)
|
||||
#define osMessageQDef(name, queue_sz, type) \
|
||||
extern const osMessageQDef_t os_messageQ_def_##name
|
||||
#else
|
||||
#define osMessageQDef(name, queue_sz, type) \
|
||||
static const msg_t os_messageQ_buf_##name[queue_sz]; \
|
||||
static mailbox_t os_messageQ_obj_##name; \
|
||||
const osMessageQDef_t os_messageQ_def_##name = { \
|
||||
(queue_sz), \
|
||||
sizeof (type) \
|
||||
(void *)&os_messageQ_obj_##name, \
|
||||
(void *)&os_messageQ_buf_##name[0] \
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Access a Message Queue definition.
|
||||
*/
|
||||
#define osMessageQ(name) &os_messageQ_def_##name
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
extern int32_t cmsis_os_started;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
osStatus osKernelInitialize(void);
|
||||
osStatus osKernelStart(void);
|
||||
osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument);
|
||||
osStatus osThreadTerminate(osThreadId thread_id);
|
||||
osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio);
|
||||
/*osEvent osWait(uint32_t millisec);*/
|
||||
osTimerId osTimerCreate(const osTimerDef_t *timer_def,
|
||||
os_timer_type type,
|
||||
void *argument);
|
||||
osStatus osTimerStart(osTimerId timer_id, uint32_t millisec);
|
||||
osStatus osTimerStop(osTimerId timer_id);
|
||||
osStatus osTimerDelete(osTimerId timer_id);
|
||||
int32_t osSignalSet(osThreadId thread_id, int32_t signals);
|
||||
int32_t osSignalClear(osThreadId thread_id, int32_t signals);
|
||||
osEvent osSignalWait(int32_t signals, uint32_t millisec);
|
||||
osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def,
|
||||
int32_t count);
|
||||
int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec);
|
||||
osStatus osSemaphoreRelease(osSemaphoreId semaphore_id);
|
||||
osStatus osSemaphoreDelete(osSemaphoreId semaphore_id);
|
||||
osMutexId osMutexCreate(const osMutexDef_t *mutex_def);
|
||||
osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec);
|
||||
osStatus osMutexRelease(osMutexId mutex_id);
|
||||
osStatus osMutexDelete(osMutexId mutex_id);
|
||||
osPoolId osPoolCreate(const osPoolDef_t *pool_def);
|
||||
void *osPoolAlloc(osPoolId pool_id);
|
||||
void *osPoolCAlloc(osPoolId pool_id);
|
||||
osStatus osPoolFree(osPoolId pool_id, void *block);
|
||||
osMessageQId osMessageCreate(const osMessageQDef_t *queue_def,
|
||||
osThreadId thread_id);
|
||||
osStatus osMessagePut(osMessageQId queue_id,
|
||||
uint32_t info,
|
||||
uint32_t millisec);
|
||||
osEvent osMessageGet(osMessageQId queue_id,
|
||||
uint32_t millisec);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief To be or not to be.
|
||||
*/
|
||||
static inline int32_t osKernelRunning(void) {
|
||||
|
||||
return cmsis_os_started;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System ticks since start.
|
||||
*/
|
||||
static inline uint32_t osKernelSysTick(void) {
|
||||
|
||||
return (uint32_t)chVTGetSystemTimeX();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the current thread.
|
||||
*/
|
||||
static inline osThreadId osThreadGetId(void) {
|
||||
|
||||
return (osThreadId)chThdGetSelfX();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Thread time slice yield.
|
||||
*/
|
||||
static inline osStatus osThreadYield(void) {
|
||||
|
||||
chThdYield();
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns priority of a thread.
|
||||
*/
|
||||
static inline osPriority osThreadGetPriority(osThreadId thread_id) {
|
||||
|
||||
return thread_id->p_prio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Thread delay in milliseconds.
|
||||
*/
|
||||
static inline osStatus osDelay(uint32_t millisec) {
|
||||
|
||||
chThdSleepMilliseconds(millisec);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
#endif /* _CMSIS_OS_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,4 @@
|
|||
# List of the ChibiOS/RT CMSIS RTOS wrapper.
|
||||
CMSISRTOSSRC = ${CHIBIOS}/os/rt/ports/ARMCMx/cmsis_os/cmsis_os.c
|
||||
|
||||
CMSISRTOSINC = ${CHIBIOS}/os/rt/ports/ARMCMx/cmsis_os
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/compilers/GCC/nilcoreasm_v6m.s
|
||||
* @file compilers/GCC/chcoreasm_v6m.s
|
||||
* @brief ARMv6-M architecture port low level code.
|
||||
*
|
||||
* @addtogroup ARMCMx_GCC_CORE
|
||||
|
@ -34,12 +34,22 @@
|
|||
#endif
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "nilconf.h"
|
||||
#include "nilcore.h"
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
.set CONTEXT_OFFSET, 0
|
||||
/*
|
||||
* RTOS-specific context offset.
|
||||
*/
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
#define CONTEXT_OFFSET 12
|
||||
#elif defined(_CHIBIOS_NIL_CONF_)
|
||||
#define CONTEXT_OFFSET 0
|
||||
#else
|
||||
#error "invalid chconf.h"
|
||||
#endif
|
||||
|
||||
.set SCB_ICSR, 0xE000ED04
|
||||
.set ICSR_PENDSVSET, 0x10000000
|
||||
.set ICSR_NMIPENDSET, 0x80000000
|
||||
|
@ -86,11 +96,17 @@ _port_switch:
|
|||
.thumb_func
|
||||
.globl _port_thread_start
|
||||
_port_thread_start:
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
cpsie i
|
||||
mov r0, r5
|
||||
blx r4
|
||||
mov r3, #0
|
||||
bl chSysHalt
|
||||
movs r0, #0 /* MSG_OK */
|
||||
bl chThdExit
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* Post-IRQ switch code.
|
||||
|
@ -100,7 +116,19 @@ _port_thread_start:
|
|||
.thumb_func
|
||||
.globl _port_switch_from_isr
|
||||
_port_switch_from_isr:
|
||||
bl chSchRescheduleS
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
.globl _port_exit_from_isr
|
||||
_port_exit_from_isr:
|
||||
ldr r2, .L2
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/compilers/GCC/nilcoreasm_v7m.s
|
||||
* @file compilers/GCC/chcoreasm_v7m.s
|
||||
* @brief ARMv7-M architecture port low level code.
|
||||
*
|
||||
* @addtogroup ARMCMx_GCC_CORE
|
||||
|
@ -34,12 +34,22 @@
|
|||
#endif
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "nilconf.h"
|
||||
#include "nilcore.h"
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
.set CONTEXT_OFFSET, 0
|
||||
/*
|
||||
* RTOS-specific context offset.
|
||||
*/
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
#define CONTEXT_OFFSET 12
|
||||
#elif defined(_CHIBIOS_NIL_CONF_)
|
||||
#define CONTEXT_OFFSET 0
|
||||
#else
|
||||
#error "invalid chconf.h"
|
||||
#endif
|
||||
|
||||
.set SCB_ICSR, 0xE000ED04
|
||||
.set ICSR_PENDSVSET, 0x10000000
|
||||
|
||||
|
@ -92,16 +102,28 @@ _port_switch:
|
|||
.thumb_func
|
||||
.globl _port_thread_start
|
||||
_port_thread_start:
|
||||
#if !CORTEX_SIMPLIFIED_PRIORITY
|
||||
movs r3, #0
|
||||
msr BASEPRI, r3
|
||||
#else /* CORTEX_SIMPLIFIED_PRIORITY */
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
#if CORTEX_SIMPLIFIED_PRIORITY
|
||||
cpsie i
|
||||
#endif /* CORTEX_SIMPLIFIED_PRIORITY */
|
||||
#else
|
||||
movs r3, #0 /* CORTEX_BASEPRI_DISABLED */
|
||||
msr BASEPRI, r3
|
||||
#endif
|
||||
mov r0, r5
|
||||
blx r4
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
movs r0, #0 /* MSG_OK */
|
||||
bl chThdExit
|
||||
#endif
|
||||
#if defined(_CHIBIOS_NIL_CONF_)
|
||||
mov r3, #0
|
||||
bl chSysHalt
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------*
|
||||
* Post-IRQ switch code.
|
||||
|
@ -111,7 +133,19 @@ _port_thread_start:
|
|||
.thumb_func
|
||||
.globl _port_switch_from_isr
|
||||
_port_switch_from_isr:
|
||||
bl chSchRescheduleS
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
.globl _port_exit_from_isr
|
||||
_port_exit_from_isr:
|
||||
#if CORTEX_SIMPLIFIED_PRIORITY
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/compilers/GCC/niltypes.h
|
||||
* @file ARMCMx/compilers/GCC/chtypes.h
|
||||
* @brief ARM Cortex-Mx port system types.
|
||||
*
|
||||
* @addtogroup ARMCMx_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILTYPES_H_
|
||||
#define _NILTYPES_H_
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -50,22 +50,25 @@
|
|||
#endif
|
||||
/** @} */
|
||||
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
|
||||
/**
|
||||
* @brief Type of system time.
|
||||
*/
|
||||
#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
|
||||
typedef uint32_t systime_t;
|
||||
#else
|
||||
typedef uint16_t systime_t;
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
|
@ -83,14 +86,18 @@ typedef uint16_t systime_t;
|
|||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) \
|
||||
__attribute__((noreturn)) void tname(void *arg)
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __attribute__((packed))
|
||||
|
||||
#endif /* _NILTYPES_H_ */
|
||||
/**
|
||||
* @brief Memory alignment enforcement for variables.
|
||||
*/
|
||||
#define ALIGNED_VAR(n) __attribute__((aligned(n)))
|
||||
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,8 @@
|
|||
# List of the ChibiOS/RT Cortex-M0 STM32F0xx port files.
|
||||
PORTSRC = $(CHIBIOS)/os/common/ports/ARMCMx/chcore.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/chcore_v6m.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v6m.s
|
||||
|
||||
PORTINC = $(CHIBIOS)/os/common/ports/ARMCMx \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC
|
|
@ -0,0 +1,8 @@
|
|||
# List of the ChibiOS/RT ARMv7M generic port files.
|
||||
PORTSRC = $(CHIBIOS)/os/common/ports/ARMCMx/chcore.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/chcore_v7m.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/chcoreasm_v7m.s
|
||||
|
||||
PORTINC = $(CHIBIOS)/os/common/ports/ARMCMx \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compilers/IAR/chcoreasm_v6m.s
|
||||
* @brief ARMv6-M architecture port low level code.
|
||||
*
|
||||
* @addtogroup ARMCMx_IAR_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
MODULE ?chcoreasm_v6m
|
||||
|
||||
AAPCS INTERWORK, VFP_COMPATIBLE
|
||||
PRESERVE8
|
||||
|
||||
CONTEXT_OFFSET SET 12
|
||||
SCB_ICSR SET 0xE000ED04
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
EXTERN chThdExit
|
||||
EXTERN chSchDoReschedule
|
||||
#if CH_DBG_STATISTICS
|
||||
EXTERN _stats_start_measure_crit_thd
|
||||
EXTERN _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
EXTERN _dbg_check_unlock
|
||||
EXTERN _dbg_check_lock
|
||||
#endif
|
||||
|
||||
THUMB
|
||||
|
||||
/*
|
||||
* Performs a context switch between two threads.
|
||||
*/
|
||||
PUBLIC _port_switch
|
||||
_port_switch:
|
||||
push {r4, r5, r6, r7, lr}
|
||||
mov r4, r8
|
||||
mov r5, r9
|
||||
mov r6, r10
|
||||
mov r7, r11
|
||||
push {r4, r5, r6, r7}
|
||||
mov r3, sp
|
||||
str r3, [r1, #CONTEXT_OFFSET]
|
||||
ldr r3, [r0, #CONTEXT_OFFSET]
|
||||
mov sp, r3
|
||||
pop {r4, r5, r6, r7}
|
||||
mov r8, r4
|
||||
mov r9, r5
|
||||
mov r10, r6
|
||||
mov r11, r7
|
||||
pop {r4, r5, r6, r7, pc}
|
||||
|
||||
/*
|
||||
* Start a thread by invoking its work function.
|
||||
* If the work function returns @p chThdExit() is automatically invoked.
|
||||
*/
|
||||
PUBLIC _port_thread_start
|
||||
_port_thread_start:
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
cpsie i
|
||||
mov r0, r5
|
||||
blx r4
|
||||
bl chThdExit
|
||||
|
||||
/*
|
||||
* Post-IRQ switch code.
|
||||
* Exception handlers return here for context switching.
|
||||
*/
|
||||
PUBLIC _port_switch_from_isr
|
||||
PUBLIC _port_exit_from_isr
|
||||
_port_switch_from_isr:
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
_port_exit_from_isr:
|
||||
ldr r2, =SCB_ICSR
|
||||
movs r3, #128
|
||||
#if CORTEX_ALTERNATE_SWITCH
|
||||
lsls r3, r3, #21
|
||||
str r3, [r2, #0]
|
||||
cpsie i
|
||||
#else
|
||||
lsls r3, r3, #24
|
||||
str r3, [r2, #0]
|
||||
#endif
|
||||
waithere:
|
||||
b waithere
|
||||
|
||||
END
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compilers/IAR/chcoreasm_v7m.s
|
||||
* @brief ARMv7-M architecture port low level code.
|
||||
*
|
||||
* @addtogroup ARMCMx_IAR_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
MODULE ?chcoreasm_v7m
|
||||
|
||||
AAPCS INTERWORK, VFP_COMPATIBLE
|
||||
PRESERVE8
|
||||
|
||||
CONTEXT_OFFSET SET 12
|
||||
SCB_ICSR SET 0xE000ED04
|
||||
ICSR_PENDSVSET SET 0x10000000
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
EXTERN chThdExit
|
||||
EXTERN chSchDoReschedule
|
||||
#if CH_DBG_STATISTICS
|
||||
EXTERN _stats_start_measure_crit_thd
|
||||
EXTERN _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
EXTERN _dbg_check_unlock
|
||||
EXTERN _dbg_check_lock
|
||||
#endif
|
||||
|
||||
THUMB
|
||||
|
||||
/*
|
||||
* Performs a context switch between two threads.
|
||||
*/
|
||||
PUBLIC _port_switch
|
||||
_port_switch:
|
||||
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
#if CORTEX_USE_FPU
|
||||
vpush {s16-s31}
|
||||
#endif
|
||||
|
||||
str sp, [r1, #CONTEXT_OFFSET]
|
||||
#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) && \
|
||||
((CORTEX_MODEL == 3) || (CORTEX_MODEL == 4))
|
||||
/* Workaround for ARM errata 752419, only applied if
|
||||
condition exists for it to be triggered.*/
|
||||
ldr r3, [r0, #CONTEXT_OFFSET]
|
||||
mov sp, r3
|
||||
#else
|
||||
ldr sp, [r0, #CONTEXT_OFFSET]
|
||||
#endif
|
||||
|
||||
#if CORTEX_USE_FPU
|
||||
vpop {s16-s31}
|
||||
#endif
|
||||
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||
|
||||
/*
|
||||
* Start a thread by invoking its work function.
|
||||
* If the work function returns @p chThdExit() is automatically invoked.
|
||||
*/
|
||||
PUBLIC _port_thread_start
|
||||
_port_thread_start:
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
#if CORTEX_SIMPLIFIED_PRIORITY
|
||||
cpsie i
|
||||
#else
|
||||
movs r3, #0 /* CORTEX_BASEPRI_DISABLED */
|
||||
msr BASEPRI, r3
|
||||
#endif
|
||||
mov r0, r5
|
||||
blx r4
|
||||
bl chThdExit
|
||||
|
||||
/*
|
||||
* Post-IRQ switch code.
|
||||
* Exception handlers return here for context switching.
|
||||
*/
|
||||
PUBLIC _port_switch_from_isr
|
||||
PUBLIC _port_exit_from_isr
|
||||
_port_switch_from_isr:
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
_port_exit_from_isr:
|
||||
#if CORTEX_SIMPLIFIED_PRIORITY
|
||||
mov r3, #LWRD SCB_ICSR
|
||||
movt r3, #HWRD SCB_ICSR
|
||||
mov r2, #ICSR_PENDSVSET
|
||||
str r2, [r3]
|
||||
cpsie i
|
||||
#else
|
||||
svc #0
|
||||
#endif
|
||||
.L3: b .L3
|
||||
|
||||
END
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/compilers/IAR/chtypes.h
|
||||
* @brief ARM Cortex-Mx port system types.
|
||||
*
|
||||
* @addtogroup ARMCMx_IAR_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @name Common constants
|
||||
*/
|
||||
/**
|
||||
* @brief Generic 'false' boolean constant.
|
||||
*/
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generic 'true' boolean constant.
|
||||
*/
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
* @note It is set to use the "const" keyword in this port.
|
||||
*/
|
||||
#define ROMCONST const
|
||||
|
||||
/**
|
||||
* @brief Makes functions not inlineable.
|
||||
* @note If the compiler does not support such attribute then the
|
||||
* realtime counter precision could be degraded.
|
||||
*/
|
||||
#define NOINLINE
|
||||
|
||||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __packed
|
||||
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compilers/RVCT/chcoreasm_v6m.s
|
||||
* @brief ARMv6-M architecture port low level code.
|
||||
*
|
||||
* @addtogroup ARMCMx_RVCT_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
CONTEXT_OFFSET EQU 12
|
||||
SCB_ICSR EQU 0xE000ED04
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
IMPORT chThdExit
|
||||
IMPORT chSchDoReschedule
|
||||
#if CH_DBG_STATISTICS
|
||||
IMPORT _stats_start_measure_crit_thd
|
||||
IMPORT _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
IMPORT _dbg_check_unlock
|
||||
IMPORT _dbg_check_lock
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Performs a context switch between two threads.
|
||||
*/
|
||||
EXPORT _port_switch
|
||||
_port_switch PROC
|
||||
push {r4, r5, r6, r7, lr}
|
||||
mov r4, r8
|
||||
mov r5, r9
|
||||
mov r6, r10
|
||||
mov r7, r11
|
||||
push {r4, r5, r6, r7}
|
||||
mov r3, sp
|
||||
str r3, [r1, #CONTEXT_OFFSET]
|
||||
ldr r3, [r0, #CONTEXT_OFFSET]
|
||||
mov sp, r3
|
||||
pop {r4, r5, r6, r7}
|
||||
mov r8, r4
|
||||
mov r9, r5
|
||||
mov r10, r6
|
||||
mov r11, r7
|
||||
pop {r4, r5, r6, r7, pc}
|
||||
ENDP
|
||||
|
||||
/*
|
||||
* Start a thread by invoking its work function.
|
||||
* If the work function returns @p chThdExit() is automatically invoked.
|
||||
*/
|
||||
EXPORT _port_thread_start
|
||||
_port_thread_start PROC
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
cpsie i
|
||||
mov r0, r5
|
||||
blx r4
|
||||
bl chThdExit
|
||||
ENDP
|
||||
|
||||
/*
|
||||
* Post-IRQ switch code.
|
||||
* Exception handlers return here for context switching.
|
||||
*/
|
||||
EXPORT _port_switch_from_isr
|
||||
EXPORT _port_exit_from_isr
|
||||
_port_switch_from_isr PROC
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
_port_exit_from_isr
|
||||
ldr r2, =SCB_ICSR
|
||||
movs r3, #128
|
||||
#if CORTEX_ALTERNATE_SWITCH
|
||||
lsls r3, r3, #21
|
||||
str r3, [r2, #0]
|
||||
cpsie i
|
||||
#else
|
||||
lsls r3, r3, #24
|
||||
str r3, [r2, #0]
|
||||
#endif
|
||||
waithere b waithere
|
||||
ENDP
|
||||
|
||||
END
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file compilers/RVCT/chcoreasm_v7m.s
|
||||
* @brief ARMv7-M architecture port low level code.
|
||||
*
|
||||
* @addtogroup ARMCMx_RVCT_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
CONTEXT_OFFSET EQU 12
|
||||
SCB_ICSR EQU 0xE000ED04
|
||||
ICSR_PENDSVSET EQU 0x10000000
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
IMPORT chThdExit
|
||||
IMPORT chSchDoReschedule
|
||||
#if CH_DBG_STATISTICS
|
||||
IMPORT _stats_start_measure_crit_thd
|
||||
IMPORT _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
IMPORT _dbg_check_unlock
|
||||
IMPORT _dbg_check_lock
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Performs a context switch between two threads.
|
||||
*/
|
||||
EXPORT _port_switch
|
||||
_port_switch PROC
|
||||
push {r4, r5, r6, r7, r8, r9, r10, r11, lr}
|
||||
#if CORTEX_USE_FPU
|
||||
vpush {s16-s31}
|
||||
#endif
|
||||
|
||||
str sp, [r1, #CONTEXT_OFFSET]
|
||||
#if (CORTEX_SIMPLIFIED_PRIORITY == FALSE) && \
|
||||
((CORTEX_MODEL == 3) || (CORTEX_MODEL == 4))
|
||||
/* Workaround for ARM errata 752419, only applied if
|
||||
condition exists for it to be triggered.*/
|
||||
ldr r3, [r0, #CONTEXT_OFFSET]
|
||||
mov sp, r3
|
||||
#else
|
||||
ldr sp, [r0, #CONTEXT_OFFSET]
|
||||
#endif
|
||||
|
||||
#if CORTEX_USE_FPU
|
||||
vpop {s16-s31}
|
||||
#endif
|
||||
pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}
|
||||
ENDP
|
||||
|
||||
/*
|
||||
* Start a thread by invoking its work function.
|
||||
* If the work function returns @p chThdExit() is automatically invoked.
|
||||
*/
|
||||
EXPORT _port_thread_start
|
||||
_port_thread_start PROC
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
#if CORTEX_SIMPLIFIED_PRIORITY
|
||||
cpsie i
|
||||
#else
|
||||
movs r3, #0 /* CORTEX_BASEPRI_DISABLED */
|
||||
msr BASEPRI, r3
|
||||
#endif
|
||||
mov r0, r5
|
||||
blx r4
|
||||
bl chThdExit
|
||||
ENDP
|
||||
|
||||
/*
|
||||
* Post-IRQ switch code.
|
||||
* Exception handlers return here for context switching.
|
||||
*/
|
||||
EXPORT _port_switch_from_isr
|
||||
EXPORT _port_exit_from_isr
|
||||
_port_switch_from_isr PROC
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchDoReschedule
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
_port_exit_from_isr
|
||||
#if CORTEX_SIMPLIFIED_PRIORITY
|
||||
mov r3, #SCB_ICSR :AND: 0xFFFF
|
||||
movt r3, #SCB_ICSR :SHR: 16
|
||||
mov r2, #ICSR_PENDSVSET
|
||||
str r2, [r3, #0]
|
||||
cpsie i
|
||||
#else
|
||||
svc #0
|
||||
#endif
|
||||
waithere b waithere
|
||||
ENDP
|
||||
|
||||
END
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ARMCMx/compilers/RVCT/chtypes.h
|
||||
* @brief ARM Cortex-Mx port system types.
|
||||
*
|
||||
* @addtogroup ARMCMx_RVCT_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @name Common constants
|
||||
*/
|
||||
/**
|
||||
* @brief Generic 'false' boolean constant.
|
||||
*/
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generic 'true' boolean constant.
|
||||
*/
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
* @note It is set to use the "const" keyword in this port.
|
||||
*/
|
||||
#define ROMCONST const
|
||||
|
||||
/**
|
||||
* @brief Makes functions not inlineable.
|
||||
* @note If the compiler does not support such attribute then the
|
||||
* realtime counter precision could be degraded.
|
||||
*/
|
||||
#define NOINLINE
|
||||
|
||||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __packed
|
||||
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/ARMCMx/mpu.h
|
||||
* @brief Cortex-Mx MPU support macros and structures.
|
||||
*
|
||||
* @addtogroup COMMON_ARMCMx_MPU
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MPU_H_
|
||||
#define _MPU_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name MPU registers definitions
|
||||
* @{
|
||||
*/
|
||||
#define MPU_TYPE_SEPARATED (1U << 0U)
|
||||
#define MPU_TYPE_DREGION(n) (((n) >> 8U) & 255U)
|
||||
#define MPU_TYPE_IREGION(n) (((n) >> 16U) & 255U)
|
||||
|
||||
#define MPU_CTRL_ENABLE (1U << 0U)
|
||||
#define MPU_CTRL_HFNMIENA (1U << 1U)
|
||||
#define MPU_CTRL_PRIVDEFENA (1U << 2U)
|
||||
|
||||
#define MPU_RNR_REGION_MASK (255U << 0U)
|
||||
#define MPU_RNR_REGION(n) ((n) << 0U)
|
||||
|
||||
#define MPU_RBAR_REGION_MASK (15U << 0U)
|
||||
#define MPU_RBAR_REGION(n) ((n) << 0U)
|
||||
#define MPU_RBAR_VALID (1U << 4U)
|
||||
#define MPU_RBAR_ADDR_MASK 0xFFFFFFE0U
|
||||
#define MPU_RBAR_ADDR(n) ((n) << 5U)
|
||||
|
||||
#define MPU_RASR_ENABLE (1U << 0U)
|
||||
#define MPU_RASR_SIZE_MASK (31U << 1U)
|
||||
#define MPU_RASR_SIZE(n) ((n) << 1U)
|
||||
#define MPU_RASR_SIZE_32 MPU_RASR_SIZE(4U)
|
||||
#define MPU_RASR_SIZE_64 MPU_RASR_SIZE(5U)
|
||||
#define MPU_RASR_SIZE_128 MPU_RASR_SIZE(6U)
|
||||
#define MPU_RASR_SIZE_256 MPU_RASR_SIZE(7U)
|
||||
#define MPU_RASR_SIZE_512 MPU_RASR_SIZE(8U)
|
||||
#define MPU_RASR_SIZE_1K MPU_RASR_SIZE(9U)
|
||||
#define MPU_RASR_SIZE_2K MPU_RASR_SIZE(10U)
|
||||
#define MPU_RASR_SIZE_4K MPU_RASR_SIZE(11U)
|
||||
#define MPU_RASR_SIZE_8K MPU_RASR_SIZE(12U)
|
||||
#define MPU_RASR_SIZE_16K MPU_RASR_SIZE(13U)
|
||||
#define MPU_RASR_SIZE_32K MPU_RASR_SIZE(14U)
|
||||
#define MPU_RASR_SIZE_64K MPU_RASR_SIZE(15U)
|
||||
#define MPU_RASR_SIZE_128K MPU_RASR_SIZE(16U)
|
||||
#define MPU_RASR_SIZE_256K MPU_RASR_SIZE(17U)
|
||||
#define MPU_RASR_SIZE_512K MPU_RASR_SIZE(18U)
|
||||
#define MPU_RASR_SIZE_1M MPU_RASR_SIZE(19U)
|
||||
#define MPU_RASR_SIZE_2M MPU_RASR_SIZE(20U)
|
||||
#define MPU_RASR_SIZE_4M MPU_RASR_SIZE(21U)
|
||||
#define MPU_RASR_SIZE_8M MPU_RASR_SIZE(22U)
|
||||
#define MPU_RASR_SIZE_16M MPU_RASR_SIZE(23U)
|
||||
#define MPU_RASR_SIZE_32M MPU_RASR_SIZE(24U)
|
||||
#define MPU_RASR_SIZE_64M MPU_RASR_SIZE(25U)
|
||||
#define MPU_RASR_SIZE_128M MPU_RASR_SIZE(26U)
|
||||
#define MPU_RASR_SIZE_256M MPU_RASR_SIZE(27U)
|
||||
#define MPU_RASR_SIZE_512M MPU_RASR_SIZE(28U)
|
||||
#define MPU_RASR_SIZE_1G MPU_RASR_SIZE(29U)
|
||||
#define MPU_RASR_SIZE_2G MPU_RASR_SIZE(30U)
|
||||
#define MPU_RASR_SIZE_4G MPU_RASR_SIZE(31U)
|
||||
#define MPU_RASR_SRD_MASK (255U << 8U)
|
||||
#define MPU_RASR_SRD(n) ((n) << 8U)
|
||||
#define MPU_RASR_SRD_ALL (0U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB0 (1U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB1 (2U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB2 (4U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB3 (8U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB4 (16U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB5 (32U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB6 (64U << 8U)
|
||||
#define MPU_RASR_SRD_DISABLE_SUB7 (128U << 8U)
|
||||
#define MPU_RASR_ATTR_B (1U << 16U)
|
||||
#define MPU_RASR_ATTR_C (1U << 17U)
|
||||
#define MPU_RASR_ATTR_S (1U << 18U)
|
||||
#define MPU_RASR_ATTR_TEX_MASK (7U << 19U)
|
||||
#define MPU_RASR_ATTR_TEX(n) ((n) << 19U)
|
||||
#define MPU_RASR_ATTR_AP_MASK (7U << 24U)
|
||||
#define MPU_RASR_ATTR_AP(n) ((n) << 24U)
|
||||
#define MPU_RASR_ATTR_AP_NA_NA (0U << 24U)
|
||||
#define MPU_RASR_ATTR_AP_RW_NA (1U << 24U)
|
||||
#define MPU_RASR_ATTR_AP_RW_RO (2U << 24U)
|
||||
#define MPU_RASR_ATTR_AP_RW_RW (3U << 24U)
|
||||
#define MPU_RASR_ATTR_AP_RO_NA (5U << 24U)
|
||||
#define MPU_RASR_ATTR_AP_RO_RO (6U << 24U)
|
||||
#define MPU_RASR_ATTR_XN (1U << 28U)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Region attributes
|
||||
* @{
|
||||
*/
|
||||
#define MPU_RASR_ATTR_STRONGLY_ORDERED (MPU_RASR_ATTR_TEX(0))
|
||||
#define MPU_RASR_ATTR_SHARED_DEVICE (MPU_RASR_ATTR_TEX(0) | MPU_RASR_ATTR_B)
|
||||
#define MPU_RASR_ATTR_CACHEABLE_WT_NWA (MPU_RASR_ATTR_TEX(0) | MPU_RASR_ATTR_C)
|
||||
#define MPU_RASR_ATTR_CACHEABLE_WB_NWA (MPU_RASR_ATTR_TEX(0) | MPU_RASR_ATTR_B | MPU_RASR_ATTR_C)
|
||||
#define MPU_RASR_ATTR_NON_CACHEABLE (MPU_RASR_ATTR_TEX(1))
|
||||
#define MPU_RASR_ATTR_CACHEABLE_WB_WA (MPU_RASR_ATTR_TEX(1) | MPU_RASR_ATTR_B | MPU_RASR_ATTR_C)
|
||||
#define MPU_RASR_ATTR_NON_SHARED_DEVICE (MPU_RASR_ATTR_TEX(2))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Region identifiers
|
||||
* @{
|
||||
*/
|
||||
#define MPU_REGION_0 0U
|
||||
#define MPU_REGION_1 1U
|
||||
#define MPU_REGION_2 2U
|
||||
#define MPU_REGION_3 3U
|
||||
#define MPU_REGION_4 4U
|
||||
#define MPU_REGION_5 5U
|
||||
#define MPU_REGION_6 6U
|
||||
#define MPU_REGION_7 7U
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the MPU.
|
||||
* @note MEMFAULENA is enabled in SCB_SHCSR.
|
||||
*
|
||||
* @param[in] ctrl MPU control modes as defined in @p MPU_CTRL register,
|
||||
* the enable bit is enforced
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define mpuEnable(ctrl) { \
|
||||
MPU->CTRL = ((uint32_t)ctrl) | MPU_CTRL_ENABLE; \
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the MPU.
|
||||
* @note MEMFAULENA is disabled in SCB_SHCSR.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define mpuDisable() { \
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; \
|
||||
MPU->CTRL = 0; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures an MPU region.
|
||||
*
|
||||
* @param[in] region the region number
|
||||
* @param[in] address start address of the region, note, there are alignment
|
||||
* constraints
|
||||
* @param[in] attribs attributes mask as defined in @p MPU_RASR register
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define mpuConfigureRegion(region, addr, attribs) { \
|
||||
MPU->RNR = ((uint32_t)region); \
|
||||
MPU->RBAR = ((uint32_t)addr); \
|
||||
MPU->RASR = ((uint32_t)attribs); \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _MPU_H_ */
|
||||
|
||||
/** @} */
|
|
@ -18,14 +18,14 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/nilcore.c
|
||||
* @brief AVR port code.
|
||||
* @file AVR/chcore.c
|
||||
* @brief AVR architecture port code.
|
||||
*
|
||||
* @addtogroup AVR_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "nil.h"
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
|
@ -35,6 +35,9 @@
|
|||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/* Executing-in-ISR global flag.*/
|
||||
bool __avr_in_isr;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
@ -57,16 +60,16 @@
|
|||
* is responsible for the context switch between 2 threads.
|
||||
* @note The implementation of this code affects <b>directly</b> the context
|
||||
* switch performance so optimize here as much as you can.
|
||||
* @note The function is declared as a weak symbol, it is possible to
|
||||
* redefine it in your application code.
|
||||
*
|
||||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*
|
||||
* @todo Put into an asm module, use of naked attribute is problematic.
|
||||
*/
|
||||
#if !defined(__DOXYGEN__)
|
||||
__attribute__((naked, weak))
|
||||
#endif
|
||||
void _port_switch(thread_t *ntp, thread_t *otp) {
|
||||
void port_switch(thread_t *ntp, thread_t *otp) {
|
||||
|
||||
asm volatile ("push r2");
|
||||
asm volatile ("push r3");
|
||||
|
@ -87,6 +90,21 @@ void _port_switch(thread_t *ntp, thread_t *otp) {
|
|||
asm volatile ("push r28");
|
||||
asm volatile ("push r29");
|
||||
|
||||
#if defined(_CHIBIOS_RT_)
|
||||
asm volatile ("movw r30, r22");
|
||||
asm volatile ("in r0, 0x3d");
|
||||
asm volatile ("std Z+5, r0");
|
||||
asm volatile ("in r0, 0x3e");
|
||||
asm volatile ("std Z+6, r0");
|
||||
|
||||
asm volatile ("movw r30, r24");
|
||||
asm volatile ("ldd r0, Z+5");
|
||||
asm volatile ("out 0x3d, r0");
|
||||
asm volatile ("ldd r0, Z+6");
|
||||
asm volatile ("out 0x3e, r0");
|
||||
#endif
|
||||
|
||||
#if defined(_CHIBIOS_NIL_)
|
||||
asm volatile ("movw r30, r22");
|
||||
asm volatile ("in r0, 0x3d");
|
||||
asm volatile ("std Z+0, r0");
|
||||
|
@ -98,6 +116,7 @@ void _port_switch(thread_t *ntp, thread_t *otp) {
|
|||
asm volatile ("out 0x3d, r0");
|
||||
asm volatile ("ldd r0, Z+1");
|
||||
asm volatile ("out 0x3e, r0");
|
||||
#endif
|
||||
|
||||
asm volatile ("pop r29");
|
||||
asm volatile ("pop r28");
|
||||
|
@ -131,7 +150,7 @@ void _port_thread_start(void) {
|
|||
asm volatile ("movw r24, r4");
|
||||
asm volatile ("movw r30, r2");
|
||||
asm volatile ("icall");
|
||||
chSysHalt(0);
|
||||
asm volatile ("call chThdExit");
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -18,41 +18,68 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/nilcore.h
|
||||
* @brief AVR port macros and structures.
|
||||
* @file templates/chcore.h
|
||||
* @brief Port related template macros and structures.
|
||||
* @details This file is a template of the system driver macros provided by
|
||||
* a port.
|
||||
*
|
||||
* @addtogroup AVR_CORE
|
||||
* @addtogroup core
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_H_
|
||||
#define _NILCORE_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Port Capabilities and Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
|
||||
/**
|
||||
* @brief Natural alignment constant.
|
||||
* @note It is the minimum alignment for pointer-size variables.
|
||||
*/
|
||||
#define PORT_NATURAL_ALIGN 1U
|
||||
|
||||
/**
|
||||
* @brief Stack alignment constant.
|
||||
* @note It is the alignement required for the stack pointer.
|
||||
*/
|
||||
#define PORT_STACK_ALIGN 1U
|
||||
|
||||
/**
|
||||
* @brief Working Areas alignment constant.
|
||||
* @note It is the alignment to be enforced for thread working areas.
|
||||
*/
|
||||
#define PORT_WORKING_AREA_ALIGN 1U
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Architecture and Compiler
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Macro defining the port architecture.
|
||||
* @brief Macro defining an AVR architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_AVR
|
||||
|
||||
/**
|
||||
* @brief Name of the implemented architecture.
|
||||
* @brief Macro defining the specific AVR architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_NAME "AVR"
|
||||
#define PORT_ARCHITECTURE_AVR_MEGAAVR
|
||||
|
||||
/**
|
||||
* @brief Name of the architecture variant.
|
||||
* @brief Name of the implemented architecture.
|
||||
*/
|
||||
#define PORT_CORE_VARIANT_NAME "MegaAVR"
|
||||
#define PORT_ARCHITECTURE_NAME "MegaAVR"
|
||||
|
||||
/**
|
||||
* @brief Compiler name and version.
|
||||
|
@ -67,12 +94,7 @@
|
|||
/**
|
||||
* @brief Port-specific information string.
|
||||
*/
|
||||
#define PORT_INFO "16 bits code addressing"
|
||||
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
#define PORT_INFO "None"
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -84,7 +106,6 @@
|
|||
* @details This size depends on the idle thread implementation, usually
|
||||
* the idle thread should take no more space than those reserved
|
||||
* by @p PORT_INT_REQUIRED_STACK.
|
||||
* @note In this port it is set to 8.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 8
|
||||
|
@ -94,7 +115,6 @@
|
|||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
* @note In this port the default is 32 bytes per thread.
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
|
||||
#define PORT_INT_REQUIRED_STACK 32
|
||||
|
@ -103,13 +123,26 @@
|
|||
/**
|
||||
* @brief Enables an alternative timer implementation.
|
||||
* @details Usually the port uses a timer interface defined in the file
|
||||
* @p nilcore_timer.h, if this option is enabled then the file
|
||||
* @p nilcore_timer_alt.h is included instead.
|
||||
* @p chcore_timer.h, if this option is enabled then the file
|
||||
* @p chcore_timer_alt.h is included instead.
|
||||
*/
|
||||
#if !defined(PORT_USE_ALT_TIMER)
|
||||
#if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__)
|
||||
#define PORT_USE_ALT_TIMER FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Activate for devices with extended code addressing.
|
||||
*/
|
||||
#if !defined(PORT_AVR_3BYTES_PC) || defined(__DOXYGEN__)
|
||||
#define PORT_AVR_3BYTES_PC FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Enables a "wait for interrupt" instruction in the idle loop.
|
||||
*/
|
||||
#if !defined(PORT_AVR_WFI_SLEEP_IDLE) || defined(__DOXYGEN__)
|
||||
#define PORT_AVR_WFI_SLEEP_IDLE FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
@ -124,13 +157,48 @@
|
|||
|
||||
/**
|
||||
* @brief Type of stack and memory alignment enforcement.
|
||||
* @note In this architecture the stack alignment is enforced to 8 bits.
|
||||
*/
|
||||
typedef uint8_t stkalign_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt saved context.
|
||||
* @details This structure represents the stack frame saved during a
|
||||
* preemption-capable interrupt handler.
|
||||
* @note R2 and R13 are not saved because those are assumed to be immutable
|
||||
* during the system life cycle.
|
||||
*/
|
||||
struct port_extctx {
|
||||
uint8_t _next;
|
||||
uint8_t r31;
|
||||
uint8_t r30;
|
||||
uint8_t r27;
|
||||
uint8_t r26;
|
||||
uint8_t r25;
|
||||
uint8_t r24;
|
||||
uint8_t r23;
|
||||
uint8_t r22;
|
||||
uint8_t r21;
|
||||
uint8_t r20;
|
||||
uint8_t r19;
|
||||
uint8_t r18;
|
||||
uint8_t sr;
|
||||
uint8_t r1;
|
||||
uint8_t r0;
|
||||
#if PORT_AVR_3BYTES_PC
|
||||
uint8_t pcx;
|
||||
#endif
|
||||
uint16_t pc;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief System saved context.
|
||||
* @details This structure represents the inner stack frame during a context
|
||||
* switching.
|
||||
* @note R2 and R13 are not saved because those are assumed to be immutable
|
||||
* during the system life cycle.
|
||||
* @note LR is stored in the caller context so it is not present in this
|
||||
* structure.
|
||||
*/
|
||||
struct port_intctx {
|
||||
uint8_t _next;
|
||||
|
@ -152,13 +220,22 @@ struct port_intctx {
|
|||
uint8_t r4;
|
||||
uint8_t r3;
|
||||
uint8_t r2;
|
||||
#ifdef __AVR_3_BYTE_PC__
|
||||
#if PORT_AVR_3BYTES_PC
|
||||
uint8_t pcx;
|
||||
#endif
|
||||
uint8_t pcl;
|
||||
uint8_t pch;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p thread_t structure.
|
||||
* @details This structure usually contains just the saved stack pointer
|
||||
* defined as a pointer to a @p port_intctx structure.
|
||||
*/
|
||||
struct port_context {
|
||||
struct port_intctx *sp;
|
||||
};
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -166,40 +243,64 @@ struct port_intctx {
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Platform dependent thread stack setup.
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#ifdef __AVR_3_BYTE_PC__
|
||||
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||
(tp)->ctxp = (struct port_intctx*)(((uint8_t *)(wend)) - \
|
||||
#if PORT_AVR_3BYTES_PC || defined(__DOXYGEN__)
|
||||
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
|
||||
tp->ctx.sp = (struct port_intctx *)((uint8_t *)(wtop) - \
|
||||
sizeof(struct port_intctx)); \
|
||||
(tp)->ctxp->r2 = (int)pf; \
|
||||
(tp)->ctxp->r3 = (int)pf >> 8; \
|
||||
(tp)->ctxp->r4 = (int)arg; \
|
||||
(tp)->ctxp->r5 = (int)arg >> 8; \
|
||||
(tp)->ctxp->pcx = (int)0; \
|
||||
(tp)->ctxp->pcl = (int)_port_thread_start >> 8; \
|
||||
(tp)->ctxp->pch = (int)_port_thread_start; \
|
||||
tp->ctx.sp->r2 = (uint8_t)(pf); \
|
||||
tp->ctx.sp->r3 = (uint8_t)((pf) >> 8); \
|
||||
tp->ctx.sp->r4 = (uint8_t)(arg); \
|
||||
tp->ctx.sp->r5 = (uint8_t)((arg) >> 8); \
|
||||
tp->ctx.sp->pcx = (uint8_t)0; \
|
||||
tp->ctx.sp->pcl = (uint8_t)_port_thread_start >> 8; \
|
||||
tp->ctx.sp->pch = (uint8_t)_port_thread_start; \
|
||||
}
|
||||
#else /* __AVR_3_BYTE_PC__ */
|
||||
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||
(tp)->ctxp = (struct port_intctx*)(((uint8_t *)(wend)) - \
|
||||
#else /* !PORT_AVR_3BYTES_PC */
|
||||
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
|
||||
tp->ctx.sp = (struct port_intctx *)((uint8_t *)(wtop) - \
|
||||
sizeof(struct port_intctx)); \
|
||||
(tp)->ctxp->r2 = (int)pf; \
|
||||
(tp)->ctxp->r3 = (int)pf >> 8; \
|
||||
(tp)->ctxp->r4 = (int)arg; \
|
||||
(tp)->ctxp->r5 = (int)arg >> 8; \
|
||||
(tp)->ctxp->pcl = (int)_port_thread_start >> 8; \
|
||||
(tp)->ctxp->pch = (int)_port_thread_start; \
|
||||
tp->ctx.sp->r2 = (uint8_t)(pf); \
|
||||
tp->ctx.sp->r3 = (uint8_t)((pf) >> 8); \
|
||||
tp->ctx.sp->r4 = (uint8_t)(arg); \
|
||||
tp->ctx.sp->r5 = (uint8_t)((arg) >> 8); \
|
||||
tp->ctx.sp->pcl = (uint8_t)_port_thread_start >> 8; \
|
||||
tp->ctx.sp->pch = (uint8_t)_port_thread_start; \
|
||||
}
|
||||
#endif /* __AVR_3_BYTE_PC__ */
|
||||
}
|
||||
#endif /* !PORT_AVR_3BYTES_PC */
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
* @note There is no need to perform alignments in this macro.
|
||||
*/
|
||||
#define PORT_WA_SIZE(n) ((sizeof(struct port_intctx) - 1) + \
|
||||
(n) + (PORT_INT_REQUIRED_STACK))
|
||||
(sizeof(struct port_extctx) - 1) + \
|
||||
((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*
|
||||
* @param[in] s the name to be assigned to the stack array
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
*/
|
||||
#define PORT_WORKING_AREA(s, n) \
|
||||
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
|
||||
|
||||
/**
|
||||
* @brief Priority level verification macro.
|
||||
*/
|
||||
#define PORT_IRQ_IS_VALID_PRIORITY(n) false
|
||||
|
||||
/**
|
||||
* @brief Priority level verification macro.
|
||||
*/
|
||||
#define PORT_IRQ_IS_VALID_KERNEL_PRIORITY(n) false
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
|
@ -211,6 +312,7 @@ struct port_intctx {
|
|||
#define PORT_IRQ_PROLOGUE() { \
|
||||
asm ("" : : : "r18", "r19", "r20", "r21", "r22", "r23", "r24", \
|
||||
"r25", "r26", "r27", "r30", "r31"); \
|
||||
__avr_in_isr = true; \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,7 +320,13 @@ struct port_intctx {
|
|||
* @details This macro must be inserted at the end of all IRQ handlers
|
||||
* enabled to invoke system APIs.
|
||||
*/
|
||||
#define PORT_IRQ_EPILOGUE() chSchRescheduleS()
|
||||
#define PORT_IRQ_EPILOGUE() { \
|
||||
__avr_in_isr == false; \
|
||||
_dbg_check_lock(); \
|
||||
if (chSchIsPreemptionRequired()) \
|
||||
chSchDoReschedule(); \
|
||||
_dbg_check_unlock(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRQ handler function declaration.
|
||||
|
@ -235,16 +343,12 @@ struct port_intctx {
|
|||
#define PORT_FAST_IRQ_HANDLER(id) ISR(id)
|
||||
|
||||
/**
|
||||
* @brief Performs a context switch between two threads.
|
||||
* @details This is the most critical code in any port, this function
|
||||
* is responsible for the context switch between 2 threads.
|
||||
* @note The implementation of this code affects <b>directly</b> the context
|
||||
* switch performance so optimize here as much as you can.
|
||||
*
|
||||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
* @brief Port-related initialization code.
|
||||
* @note This function is empty in this port.
|
||||
*/
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
#define port_init() { \
|
||||
__avr_in_isr = true; \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
@ -257,8 +361,7 @@ struct port_intctx {
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _port_irq_epilogue(void);
|
||||
void _port_switch(thread_t *ntp, thread_t *otp);
|
||||
void port_switch(thread_t *ntp, thread_t *otp);
|
||||
void _port_thread_start(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -274,13 +377,6 @@ extern "C" {
|
|||
asm module.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
/**
|
||||
* @brief Port-related initialization code.
|
||||
*/
|
||||
static inline void port_init(void) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a word encoding the current interrupts status.
|
||||
*
|
||||
|
@ -288,7 +384,7 @@ static inline void port_init(void) {
|
|||
*/
|
||||
static inline syssts_t port_get_irq_status(void) {
|
||||
|
||||
return 0;
|
||||
return SREG;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,12 +393,12 @@ static inline syssts_t port_get_irq_status(void) {
|
|||
* @param[in] sts the interrupt status word
|
||||
*
|
||||
* @return The interrupt status.
|
||||
* @retvel false the word specified a disabled interrupts status.
|
||||
* @retvel true the word specified an enabled interrupts status.
|
||||
* @retval false the word specified a disabled interrupts status.
|
||||
* @retval true the word specified an enabled interrupts status.
|
||||
*/
|
||||
static inline bool port_irq_enabled(syssts_t sts) {
|
||||
|
||||
return false;
|
||||
return (bool)((sts & 0x80) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,11 +410,13 @@ static inline bool port_irq_enabled(syssts_t sts) {
|
|||
*/
|
||||
static inline bool port_is_isr_context(void) {
|
||||
|
||||
return false;
|
||||
return __avr_in_isr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-lock action.
|
||||
* @details Usually this function just disables interrupts but may perform more
|
||||
* actions.
|
||||
*/
|
||||
static inline void port_lock(void) {
|
||||
|
||||
|
@ -327,6 +425,8 @@ static inline void port_lock(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-unlock action.
|
||||
* @details Usually this function just enables interrupts but may perform more
|
||||
* actions.
|
||||
*/
|
||||
static inline void port_unlock(void) {
|
||||
|
||||
|
@ -335,6 +435,9 @@ static inline void port_unlock(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-lock action from an interrupt handler.
|
||||
* @details This function is invoked before invoking I-class APIs from
|
||||
* interrupt handlers. The implementation is architecture dependent,
|
||||
* in its simplest form it is void.
|
||||
* @note This function is empty in this port.
|
||||
*/
|
||||
static inline void port_lock_from_isr(void) {
|
||||
|
@ -343,6 +446,9 @@ static inline void port_lock_from_isr(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-unlock action from an interrupt handler.
|
||||
* @details This function is invoked after invoking I-class APIs from interrupt
|
||||
* handlers. The implementation is architecture dependent, in its
|
||||
* simplest form it is void.
|
||||
* @note This function is empty in this port.
|
||||
*/
|
||||
static inline void port_unlock_from_isr(void) {
|
||||
|
@ -351,6 +457,7 @@ static inline void port_unlock_from_isr(void) {
|
|||
|
||||
/**
|
||||
* @brief Disables all the interrupt sources.
|
||||
* @note Of course non-maskable interrupt sources are not included.
|
||||
*/
|
||||
static inline void port_disable(void) {
|
||||
|
||||
|
@ -359,6 +466,7 @@ static inline void port_disable(void) {
|
|||
|
||||
/**
|
||||
* @brief Disables the interrupt sources below kernel-level priority.
|
||||
* @note Interrupt sources above kernel level remains enabled.
|
||||
*/
|
||||
static inline void port_suspend(void) {
|
||||
|
||||
|
@ -382,7 +490,9 @@ static inline void port_enable(void) {
|
|||
*/
|
||||
static inline void port_wait_for_interrupt(void) {
|
||||
|
||||
#if PORT_AVR_WFI_SLEEP_IDLE
|
||||
asm volatile ("sleep" : : : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -401,18 +511,20 @@ static inline rtcnt_t port_rt_get_counter_value(void) {
|
|||
/* Module late inclusions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/* The following code is not processed when the file is included from an
|
||||
asm module.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
#if NIL_CFG_ST_TIMEDELTA > 0
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
#if !PORT_USE_ALT_TIMER
|
||||
#include "nilcore_timer.h"
|
||||
#include "chcore_timer.h"
|
||||
#else /* PORT_USE_ALT_TIMER */
|
||||
#include "nilcore_timer_alt.h"
|
||||
#include "chcore_timer_alt.h"
|
||||
#endif /* PORT_USE_ALT_TIMER */
|
||||
#endif /* NIL_CFG_ST_TIMEDELTA > 0 */
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _NILCORE_H_ */
|
||||
#endif /* _CHCORE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/nilcore_timer.h
|
||||
* @file AVR/chcore_timer.h
|
||||
* @brief System timer header file.
|
||||
*
|
||||
* @addtogroup AVR_TIMER
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_TIMER_H_
|
||||
#define _NILCORE_TIMER_H_
|
||||
#ifndef _CHCORE_TIMER_H_
|
||||
#define _CHCORE_TIMER_H_
|
||||
|
||||
/* This is the only header in the HAL designed to be include-able alone.*/
|
||||
#include "st.h"
|
||||
|
@ -119,6 +119,6 @@ static inline systime_t port_timer_get_alarm(void) {
|
|||
return stGetAlarm();
|
||||
}
|
||||
|
||||
#endif /* _NILCORE_TIMER_H_ */
|
||||
#endif /* _CHCORE_TIMER_H_ */
|
||||
|
||||
/** @} */
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/compilers/GCC/niltypes.h
|
||||
* @brief AVR port system types.
|
||||
* @file AVR/compilers/GCC/chtypes.h
|
||||
* @brief AVR architecture port system types.
|
||||
*
|
||||
* @addtogroup AVR_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILTYPES_H_
|
||||
#define _NILTYPES_H_
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -50,22 +50,25 @@
|
|||
#endif
|
||||
/** @} */
|
||||
|
||||
typedef uint8_t syssts_t; /**< System status word. */
|
||||
typedef uint16_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef int16_t msg_t; /**< Inter-thread message. */
|
||||
typedef uint8_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef int8_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint8_t ucnt_t; /**< Generic unsigned counter. */
|
||||
|
||||
/**
|
||||
* @brief Type of system time.
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
|
||||
typedef uint32_t systime_t;
|
||||
#else
|
||||
typedef uint16_t systime_t;
|
||||
#endif
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint8_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint8_t tprio_t; /**< Thread priority. */
|
||||
typedef int16_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint8_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint8_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef uint8_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint8_t ucnt_t; /**< Generic unsigned counter. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
|
@ -83,14 +86,18 @@ typedef uint16_t systime_t;
|
|||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) \
|
||||
__attribute__((noreturn)) void tname(void *arg)
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __attribute__((packed))
|
||||
|
||||
#endif /* _NILTYPES_H_ */
|
||||
/**
|
||||
* @brief Memory alignment enforcement for variables.
|
||||
*/
|
||||
#define ALIGNED_VAR(n) __attribute__((aligned(n)))
|
||||
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,7 @@
|
|||
# List of the ChibiOS/RT AVR port files.
|
||||
PORTSRC = ${CHIBIOS}/os/rt/ports/AVR/chcore.c
|
||||
|
||||
PORTASM =
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/rt/ports/AVR \
|
||||
${CHIBIOS}/os/rt/ports/AVR/compilers/GCC
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file SIMIA32/chcore.c
|
||||
* @brief Simulator on IA32 port code.
|
||||
*
|
||||
* @addtogroup SIMIA32_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
bool port_isr_context_flag;
|
||||
syssts_t port_irq_sts;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* Performs a context switch between two threads.
|
||||
* @param otp the thread to be switched out
|
||||
* @param ntp the thread to be switched in
|
||||
*/
|
||||
__attribute__((used))
|
||||
static void __dummy(thread_t *ntp, thread_t *otp) {
|
||||
(void)ntp; (void)otp;
|
||||
|
||||
asm volatile (
|
||||
#if defined(WIN32)
|
||||
".globl @port_switch@8 \n\t"
|
||||
"@port_switch@8:"
|
||||
#elif defined(__APPLE__)
|
||||
".globl _port_switch \n\t"
|
||||
"_port_switch:"
|
||||
#else
|
||||
".globl port_switch \n\t"
|
||||
"port_switch:"
|
||||
#endif
|
||||
"push %ebp \n\t"
|
||||
"push %esi \n\t"
|
||||
"push %edi \n\t"
|
||||
"push %ebx \n\t"
|
||||
"movl %esp, 12(%edx) \n\t"
|
||||
"movl 12(%ecx), %esp \n\t"
|
||||
"pop %ebx \n\t"
|
||||
"pop %edi \n\t"
|
||||
"pop %esi \n\t"
|
||||
"pop %ebp \n\t"
|
||||
"ret");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a thread by invoking its work function.
|
||||
* @details If the work function returns @p chThdExit() is automatically
|
||||
* invoked.
|
||||
*/
|
||||
__attribute__((cdecl, noreturn))
|
||||
void _port_thread_start(msg_t (*pf)(void *), void *p) {
|
||||
|
||||
chSysUnlock();
|
||||
pf(p);
|
||||
chThdExit(0);
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the current value of the realtime counter.
|
||||
*
|
||||
* @return The realtime counter value.
|
||||
*/
|
||||
rtcnt_t port_rt_get_counter_value(void) {
|
||||
LARGE_INTEGER n;
|
||||
|
||||
QueryPerformanceCounter(&n);
|
||||
|
||||
return (rtcnt_t)(n.QuadPart / 1000LL);
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,382 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file SIMIA32/chcore.h
|
||||
* @brief Simulator on IA32 port macros and structures.
|
||||
*
|
||||
* @addtogroup SIMIA32_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* Macro defining the a simulated architecture into x86.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_SIMIA32
|
||||
|
||||
/**
|
||||
* Name of the implemented architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_NAME "Simulator"
|
||||
|
||||
/**
|
||||
* @brief Name of the architecture variant (optional).
|
||||
*/
|
||||
#define PORT_CORE_VARIANT_NAME "x86 (integer only)"
|
||||
|
||||
/**
|
||||
* @brief Name of the compiler supported by this port.
|
||||
*/
|
||||
#define PORT_COMPILER_NAME "GCC " __VERSION__
|
||||
|
||||
/**
|
||||
* @brief Port-specific information string.
|
||||
*/
|
||||
#define PORT_INFO "No preemption"
|
||||
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT TRUE
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Stack size for the system idle thread.
|
||||
* @details This size depends on the idle thread implementation, usually
|
||||
* the idle thread should take no more space than those reserved
|
||||
* by @p PORT_INT_REQUIRED_STACK.
|
||||
*/
|
||||
#ifndef PORT_IDLE_THREAD_STACK_SIZE
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
*/
|
||||
#ifndef PORT_INT_REQUIRED_STACK
|
||||
#define PORT_INT_REQUIRED_STACK 16384
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables an alternative timer implementation.
|
||||
* @details Usually the port uses a timer interface defined in the file
|
||||
* @p chcore_timer.h, if this option is enabled then the file
|
||||
* @p chcore_timer_alt.h is included instead.
|
||||
*/
|
||||
#if !defined(PORT_USE_ALT_TIMER)
|
||||
#define PORT_USE_ALT_TIMER FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if CH_DBG_ENABLE_STACK_CHECK
|
||||
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 16 bytes stack and memory alignment enforcement.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t a[16];
|
||||
} stkalign_t __attribute__((aligned(16)));
|
||||
|
||||
/**
|
||||
* @brief Type of a generic x86 register.
|
||||
*/
|
||||
typedef void *regx86;
|
||||
|
||||
/**
|
||||
* @brief Interrupt saved context.
|
||||
* @details This structure represents the stack frame saved during a
|
||||
* preemption-capable interrupt handler.
|
||||
*/
|
||||
struct port_extctx {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief System saved context.
|
||||
* @details This structure represents the inner stack frame during a context
|
||||
* switch.
|
||||
*/
|
||||
struct port_intctx {
|
||||
regx86 ebx;
|
||||
regx86 edi;
|
||||
regx86 esi;
|
||||
regx86 ebp;
|
||||
regx86 eip;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p thread_t structure.
|
||||
* @details In this port the structure just holds a pointer to the
|
||||
* @p port_intctx structure representing the stack pointer
|
||||
* at context switch time.
|
||||
*/
|
||||
struct context {
|
||||
struct port_intctx *esp;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define APUSH(p, a) do { \
|
||||
(p) -= sizeof(void *); \
|
||||
*(void **)(p) = (void*)(a); \
|
||||
} while (false)
|
||||
|
||||
/* Darwin requires the stack to be aligned to a 16-byte boundary at
|
||||
* the time of a call instruction (in case the called function needs
|
||||
* to save MMX registers). This aligns to 'mod' module 16, so that we'll end
|
||||
* up with the right alignment after pushing the args. */
|
||||
#define AALIGN(p, mask, mod) \
|
||||
p = (void *)((((uint32_t)(p) - (uint32_t)(mod)) & ~(uint32_t)(mask)) + (uint32_t)(mod)) \
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
|
||||
/*lint -save -e611 -e9033 -e9074 -e9087 [10.8, 11.1, 11.3] Valid casts.*/ \
|
||||
uint8_t *esp = (uint8_t *)workspace + wsize; \
|
||||
APUSH(esp, 0); \
|
||||
uint8_t *savebp = esp; \
|
||||
AALIGN(esp, 15, 8); \
|
||||
APUSH(esp, arg); \
|
||||
APUSH(esp, pf); \
|
||||
APUSH(esp, 0); \
|
||||
esp -= sizeof(struct port_intctx); \
|
||||
((struct port_intctx *)esp)->eip = (void *)_port_thread_start; \
|
||||
((struct port_intctx *)esp)->ebx = NULL; \
|
||||
((struct port_intctx *)esp)->edi = NULL; \
|
||||
((struct port_intctx *)esp)->esi = NULL; \
|
||||
((struct port_intctx *)esp)->ebp = (void *)savebp; \
|
||||
(tp)->p_ctx.esp = (struct port_intctx *)esp; \
|
||||
/*lint -restore*/ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
* @note There is no need to perform alignments in this macro.
|
||||
*/
|
||||
#define PORT_WA_SIZE(n) ((sizeof(void *) * 4U) + \
|
||||
sizeof(struct port_intctx) + \
|
||||
((size_t)(n)) + \
|
||||
((size_t)(PORT_INT_REQUIRED_STACK)))
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
* @details This macro must be inserted at the start of all IRQ handlers
|
||||
* enabled to invoke system APIs.
|
||||
*/
|
||||
#define PORT_IRQ_PROLOGUE() { \
|
||||
port_isr_context_flag = true; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRQ epilogue code.
|
||||
* @details This macro must be inserted at the end of all IRQ handlers
|
||||
* enabled to invoke system APIs.
|
||||
*/
|
||||
#define PORT_IRQ_EPILOGUE() { \
|
||||
port_isr_context_flag = false; \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief IRQ handler function declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
*/
|
||||
#define PORT_IRQ_HANDLER(id) void id(void)
|
||||
|
||||
/**
|
||||
* @brief Fast IRQ handler function declaration.
|
||||
* @note @p id can be a function name or a vector number depending on the
|
||||
* port implementation.
|
||||
*/
|
||||
#define PORT_FAST_IRQ_HANDLER(id) void id(void)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
extern bool port_isr_context_flag;
|
||||
extern syssts_t port_irq_sts;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*lint -save -e950 [Dir-2.1] Non-ANSI keywords are fine in the port layer.*/
|
||||
__attribute__((fastcall)) void port_switch(thread_t *ntp, thread_t *otp);
|
||||
__attribute__((cdecl, noreturn)) void _port_thread_start(msg_t (*pf)(void *p),
|
||||
void *p);
|
||||
/*lint -restore*/
|
||||
rtcnt_t port_rt_get_counter_value(void);
|
||||
void _sim_check_for_interrupts(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Port-related initialization code.
|
||||
*/
|
||||
static inline void port_init(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)0;
|
||||
port_isr_context_flag = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a word encoding the current interrupts status.
|
||||
*
|
||||
* @return The interrupts status.
|
||||
*/
|
||||
static inline syssts_t port_get_irq_status(void) {
|
||||
|
||||
return port_irq_sts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks the interrupt status.
|
||||
*
|
||||
* @param[in] sts the interrupt status word
|
||||
*
|
||||
* @return The interrupt status.
|
||||
* @retval false the word specified a disabled interrupts status.
|
||||
* @retval true the word specified an enabled interrupts status.
|
||||
*/
|
||||
static inline bool port_irq_enabled(syssts_t sts) {
|
||||
|
||||
return sts == (syssts_t)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines the current execution context.
|
||||
*
|
||||
* @return The execution context.
|
||||
* @retval false not running in ISR mode.
|
||||
* @retval true running in ISR mode.
|
||||
*/
|
||||
static inline bool port_is_isr_context(void) {
|
||||
|
||||
return port_isr_context_flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-lock action.
|
||||
* @details In this port this function disables interrupts globally.
|
||||
*/
|
||||
static inline void port_lock(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-unlock action.
|
||||
* @details In this port this function enables interrupts globally.
|
||||
*/
|
||||
static inline void port_unlock(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-lock action from an interrupt handler.
|
||||
* @details In this port this function disables interrupts globally.
|
||||
* @note Same as @p port_lock() in this port.
|
||||
*/
|
||||
static inline void port_lock_from_isr(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Kernel-unlock action from an interrupt handler.
|
||||
* @details In this port this function enables interrupts globally.
|
||||
* @note Same as @p port_lock() in this port.
|
||||
*/
|
||||
static inline void port_unlock_from_isr(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables all the interrupt sources.
|
||||
*/
|
||||
static inline void port_disable(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the interrupt sources below kernel-level priority.
|
||||
*/
|
||||
static inline void port_suspend(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables all the interrupt sources.
|
||||
*/
|
||||
static inline void port_enable(void) {
|
||||
|
||||
port_irq_sts = (syssts_t)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters an architecture-dependent IRQ-waiting mode.
|
||||
* @details The function is meant to return when an interrupt becomes pending.
|
||||
* The simplest implementation is an empty function or macro but this
|
||||
* would not take advantage of architecture-specific power saving
|
||||
* modes.
|
||||
* @note Implemented as an inlined @p WFI instruction.
|
||||
*/
|
||||
static inline void port_wait_for_interrupt(void) {
|
||||
|
||||
_sim_check_for_interrupts();
|
||||
}
|
||||
|
||||
#endif /* _CHCORE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file SIMIA32/compilers/GCC/chtypes.h
|
||||
* @brief Simulator on IA32 port system types.
|
||||
*
|
||||
* @addtogroup SIMIA32_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @name Common constants
|
||||
*/
|
||||
/**
|
||||
* @brief Generic 'false' boolean constant.
|
||||
*/
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generic 'true' boolean constant.
|
||||
*/
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Derived generic types
|
||||
* @{
|
||||
*/
|
||||
typedef volatile int8_t vint8_t; /**< Volatile signed 8 bits. */
|
||||
typedef volatile uint8_t vuint8_t; /**< Volatile unsigned 8 bits. */
|
||||
typedef volatile int16_t vint16_t; /**< Volatile signed 16 bits. */
|
||||
typedef volatile uint16_t vuint16_t; /**< Volatile unsigned 16 bits. */
|
||||
typedef volatile int32_t vint32_t; /**< Volatile signed 32 bits. */
|
||||
typedef volatile uint32_t vuint32_t; /**< Volatile unsigned 32 bits. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
* @note It is set to use the "const" keyword in this port.
|
||||
*/
|
||||
#define ROMCONST const
|
||||
|
||||
/**
|
||||
* @brief Makes functions not inlineable.
|
||||
* @note If the compiler does not support such attribute then the
|
||||
* realtime counter precision could be degraded.
|
||||
*/
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
|
||||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __attribute__((packed))
|
||||
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,7 @@
|
|||
# List of the ChibiOS/RT SIMIA32 port files.
|
||||
PORTSRC = ${CHIBIOS}/os/rt/ports/SIMIA32/chcore.c
|
||||
|
||||
PORTASM =
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/rt/ports/SIMIA32/compilers/GCC \
|
||||
${CHIBIOS}/os/rt/ports/SIMIA32
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file e200/chcore.c
|
||||
* @brief Power e200 port code.
|
||||
*
|
||||
* @addtogroup PPC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @} */
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file templates/nilcore.h
|
||||
* @brief Port macros and structures.
|
||||
* @file PPC/chcore.h
|
||||
* @brief Power e200 port macros and structures.
|
||||
*
|
||||
* @addtogroup NIL_CORE
|
||||
* @addtogroup PPC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_H_
|
||||
#define _NILCORE_H_
|
||||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
#include "intc.h"
|
||||
|
||||
|
@ -34,6 +34,34 @@
|
|||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Port Capabilities and Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
|
||||
/**
|
||||
* @brief Natural alignment constant.
|
||||
* @note It is the minimum alignment for pointer-size variables.
|
||||
*/
|
||||
#define PORT_NATURAL_ALIGN sizeof (void *)
|
||||
|
||||
/**
|
||||
* @brief Stack alignment constant.
|
||||
* @note It is the alignement required for the stack pointer.
|
||||
*/
|
||||
#define PORT_STACK_ALIGN sizeof (stkalign_t)
|
||||
|
||||
/**
|
||||
* @brief Working Areas alignment constant.
|
||||
* @note It is the alignment to be enforced for thread working areas.
|
||||
*/
|
||||
#define PORT_WORKING_AREA_ALIGN sizeof (stkalign_t)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Architecture and Compiler
|
||||
* @{
|
||||
|
@ -59,14 +87,12 @@
|
|||
#if defined(__GNUC__) || defined(__DOXYGEN__)
|
||||
#define PORT_COMPILER_NAME "GCC " __VERSION__
|
||||
|
||||
#elif defined(__MWERKS__)
|
||||
#define PORT_COMPILER_NAME "CW"
|
||||
|
||||
#else
|
||||
#error "unsupported compiler"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -87,10 +113,25 @@
|
|||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Stack size for the system idle thread.
|
||||
* @details This size depends on the idle thread implementation, usually
|
||||
* the idle thread should take no more space than those reserved
|
||||
* by @p PORT_INT_REQUIRED_STACK.
|
||||
* @note In this port it is set to 32 because the idle thread does have
|
||||
* a stack frame when compiling without optimizations. You may
|
||||
* reduce this value to zero when compiling with optimizations.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
* @note In this port this value is conservatively is set to 256 because
|
||||
* there is no separate interrupts stack (yet).
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
|
||||
#define PORT_INT_REQUIRED_STACK 256
|
||||
|
@ -99,8 +140,8 @@
|
|||
/**
|
||||
* @brief Enables an alternative timer implementation.
|
||||
* @details Usually the port uses a timer interface defined in the file
|
||||
* @p nilcore_timer.h, if this option is enabled then the file
|
||||
* @p nilcore_timer_alt.h is included instead.
|
||||
* @p chcore_timer.h, if this option is enabled then the file
|
||||
* @p chcore_timer_alt.h is included instead.
|
||||
*/
|
||||
#if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__)
|
||||
#define PORT_USE_ALT_TIMER FALSE
|
||||
|
@ -167,6 +208,7 @@
|
|||
|
||||
/**
|
||||
* @brief Type of stack and memory alignment enforcement.
|
||||
* @note In this architecture the stack alignment is enforced to 64 bits.
|
||||
*/
|
||||
typedef uint64_t stkalign_t;
|
||||
|
||||
|
@ -213,7 +255,7 @@ struct port_extctx {
|
|||
regppc_t r11;
|
||||
regppc_t r12;
|
||||
regppc_t padding;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief System saved context.
|
||||
|
@ -247,6 +289,15 @@ struct port_intctx {
|
|||
regppc_t padding;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p thread_t structure.
|
||||
* @details This structure usually contains just the saved stack pointer
|
||||
* defined as a pointer to a @p port_intctx structure.
|
||||
*/
|
||||
struct port_context {
|
||||
struct port_intctx *sp;
|
||||
};
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -254,18 +305,17 @@ struct port_intctx {
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Platform dependent thread stack setup.
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) { \
|
||||
uint8_t *sp = (uint8_t *)(wend) - \
|
||||
sizeof(struct port_eabi_frame); \
|
||||
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
|
||||
uint8_t *sp = (uint8_t *)(wtop) - sizeof(struct port_eabi_frame); \
|
||||
((struct port_eabi_frame *)sp)->slink = 0; \
|
||||
((struct port_eabi_frame *)sp)->shole = (uint32_t)_port_thread_start; \
|
||||
(tp)->ctxp = (struct port_intctx *)(sp - sizeof(struct port_intctx)); \
|
||||
(tp)->ctxp->r31 = (regppc_t)(arg); \
|
||||
(tp)->ctxp->r30 = (regppc_t)(pf); \
|
||||
(tp)->ctx.sp = (struct port_intctx *)(sp - sizeof(struct port_intctx)); \
|
||||
(tp)->ctx.sp->r31 = (regppc_t)(arg); \
|
||||
(tp)->ctx.sp->r30 = (regppc_t)(pf); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -274,7 +324,18 @@ struct port_intctx {
|
|||
*/
|
||||
#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \
|
||||
sizeof(struct port_extctx) + \
|
||||
(n) + (PORT_INT_REQUIRED_STACK))
|
||||
((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*
|
||||
* @param[in] s the name to be assigned to the stack array
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
*/
|
||||
#define PORT_WORKING_AREA(s, n) \
|
||||
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
|
||||
|
||||
/**
|
||||
* @brief IRQ prologue code.
|
||||
|
@ -326,12 +387,12 @@ struct port_intctx {
|
|||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#if !NIL_CFG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
|
||||
#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
#else
|
||||
#define port_switch(ntp, otp) { \
|
||||
register struct port_intctx *sp asm ("%r1"); \
|
||||
if ((stkalign_t *)(sp - 1) < otp->stklim) \
|
||||
if ((stkalign_t *)(sp - 1) < otp->stklimit) \
|
||||
chSysHalt("stack overflow"); \
|
||||
_port_switch(ntp, otp); \
|
||||
}
|
||||
|
@ -383,7 +444,8 @@ extern "C" {
|
|||
#if !defined(_FROM_ASM_)
|
||||
|
||||
/**
|
||||
* @brief Port-related initialization code.
|
||||
* @brief Kernel port layer initialization.
|
||||
* @details IVOR4 and IVOR10 initialization.
|
||||
*/
|
||||
static inline void port_init(void) {
|
||||
uint32_t n;
|
||||
|
@ -395,12 +457,17 @@ static inline void port_init(void) {
|
|||
port_write_spr(272, n);
|
||||
|
||||
#if PPC_SUPPORTS_IVORS
|
||||
{
|
||||
/* The CPU supports IVOR registers, the kernel requires IVOR4 and IVOR10
|
||||
and the initialization is performed here.*/
|
||||
asm volatile ("li %%r3, _IVOR4@l \t\n"
|
||||
"mtIVOR4 %%r3 \t\n"
|
||||
"li %%r3, _IVOR10@l \t\n"
|
||||
"mtIVOR10 %%r3" : : : "r3", "memory");
|
||||
extern void _IVOR4(void);
|
||||
port_write_spr(404, _IVOR4);
|
||||
|
||||
#if PPC_SUPPORTS_DECREMENTER
|
||||
extern void _IVOR10(void);
|
||||
port_write_spr(410, _IVOR10);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* INTC initialization, software vector mode, 4 bytes vectors, starting
|
||||
|
@ -430,8 +497,8 @@ static inline syssts_t port_get_irq_status(void) {
|
|||
* @param[in] sts the interrupt status word
|
||||
*
|
||||
* @return The interrupt status.
|
||||
* @retvel false the word specified a disabled interrupts status.
|
||||
* @retvel true the word specified an enabled interrupts status.
|
||||
* @retval false the word specified a disabled interrupts status.
|
||||
* @retval true the word specified an enabled interrupts status.
|
||||
*/
|
||||
static inline bool port_irq_enabled(syssts_t sts) {
|
||||
|
||||
|
@ -456,6 +523,7 @@ static inline bool port_is_isr_context(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-lock action.
|
||||
* @note Implemented as global interrupt disable.
|
||||
*/
|
||||
static inline void port_lock(void) {
|
||||
|
||||
|
@ -464,6 +532,7 @@ static inline void port_lock(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-unlock action.
|
||||
* @note Implemented as global interrupt enable.
|
||||
*/
|
||||
static inline void port_unlock(void) {
|
||||
|
||||
|
@ -472,6 +541,7 @@ static inline void port_unlock(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-lock action from an interrupt handler.
|
||||
* @note Implementation not needed.
|
||||
*/
|
||||
static inline void port_lock_from_isr(void) {
|
||||
|
||||
|
@ -479,6 +549,7 @@ static inline void port_lock_from_isr(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-unlock action from an interrupt handler.
|
||||
* @note Implementation not needed.
|
||||
*/
|
||||
static inline void port_unlock_from_isr(void) {
|
||||
|
||||
|
@ -486,6 +557,7 @@ static inline void port_unlock_from_isr(void) {
|
|||
|
||||
/**
|
||||
* @brief Disables all the interrupt sources.
|
||||
* @note Implemented as global interrupt disable.
|
||||
*/
|
||||
static inline void port_disable(void) {
|
||||
|
||||
|
@ -494,6 +566,8 @@ static inline void port_disable(void) {
|
|||
|
||||
/**
|
||||
* @brief Disables the interrupt sources below kernel-level priority.
|
||||
* @note Same as @p port_disable() in this port, there is no difference
|
||||
* between the two states.
|
||||
*/
|
||||
static inline void port_suspend(void) {
|
||||
|
||||
|
@ -502,6 +576,7 @@ static inline void port_suspend(void) {
|
|||
|
||||
/**
|
||||
* @brief Enables all the interrupt sources.
|
||||
* @note Implemented as global interrupt enable.
|
||||
*/
|
||||
static inline void port_enable(void) {
|
||||
|
||||
|
@ -514,6 +589,7 @@ static inline void port_enable(void) {
|
|||
* The simplest implementation is an empty function or macro but this
|
||||
* would not take advantage of architecture-specific power saving
|
||||
* modes.
|
||||
* @note Implemented as an inlined @p wait instruction.
|
||||
*/
|
||||
static inline void port_wait_for_interrupt(void) {
|
||||
|
||||
|
@ -540,16 +616,16 @@ static inline rtcnt_t port_rt_get_counter_value(void) {
|
|||
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
#if NIL_CFG_ST_TIMEDELTA > 0
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
#if !PORT_USE_ALT_TIMER
|
||||
#include "nilcore_timer.h"
|
||||
#include "chcore_timer.h"
|
||||
#else /* PORT_USE_ALT_TIMER */
|
||||
#include "nilcore_timer_alt.h"
|
||||
#include "chcore_timer_alt.h"
|
||||
#endif /* PORT_USE_ALT_TIMER */
|
||||
#endif /* NIL_CFG_ST_TIMEDELTA > 0 */
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _NILCORE_H_ */
|
||||
#endif /* _CHCORE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file e200/compilers/GCC/chcoreasm.s
|
||||
* @brief Power Architecture port low level code.
|
||||
*
|
||||
* @addtogroup PPC_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Code section. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Imports the PPC configuration headers.
|
||||
*/
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* RTOS-specific context offset.
|
||||
*/
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
#define CONTEXT_OFFSET 12
|
||||
#elif defined(_CHIBIOS_NIL_CONF_)
|
||||
#define CONTEXT_OFFSET 0
|
||||
#else
|
||||
#error "invalid chconf.h"
|
||||
#endif
|
||||
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
.extern chThdExit
|
||||
#endif
|
||||
|
||||
#if PPC_USE_VLE == TRUE
|
||||
.section .text_vle, 16
|
||||
|
||||
.align 2
|
||||
.globl _port_switch
|
||||
.type _port_switch, @function
|
||||
_port_switch:
|
||||
e_subi r1, r1, 80
|
||||
se_mflr r0
|
||||
e_stw r0, 84(r1)
|
||||
mfcr r0
|
||||
se_stw r0, 0(r1)
|
||||
e_stmw r14, 4(r1)
|
||||
|
||||
se_stw r1, 12(r4)
|
||||
se_lwz r1, 12(r3)
|
||||
|
||||
e_lmw r14, 4(r1)
|
||||
se_lwz r0, 0(r1)
|
||||
mtcr r0
|
||||
e_lwz r0, 84(r1)
|
||||
se_mtlr r0
|
||||
e_addi r1, r1, 80
|
||||
se_blr
|
||||
|
||||
.align 2
|
||||
.globl _port_thread_start
|
||||
.type _port_thread_start, @function
|
||||
_port_thread_start:
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
wrteei 1
|
||||
mr r3, r31
|
||||
mtctr r30
|
||||
se_bctrl
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
se_li r0, 0
|
||||
e_bl chThdExit
|
||||
#endif
|
||||
#if defined(_CHIBIOS_NIL_CONF_)
|
||||
se_li r0, 0
|
||||
e_bl chSysHalt
|
||||
#endif
|
||||
|
||||
#else /* PPC_USE_VLE == FALSE */
|
||||
|
||||
#error "non-VLE mode not yet implemented"
|
||||
|
||||
#endif /* PPC_USE_VLE == FALSE */
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file e200/compilers/CW/chtypes.h
|
||||
* @brief Power e200 port system types.
|
||||
*
|
||||
* @addtogroup PPC_CW_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @name Common constants
|
||||
*/
|
||||
/**
|
||||
* @brief Generic 'false' boolean constant.
|
||||
*/
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generic 'true' boolean constant.
|
||||
*/
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
* @note It is set to use the "const" keyword in this port.
|
||||
*/
|
||||
#define ROMCONST const
|
||||
|
||||
/**
|
||||
* @brief Makes functions not inlineable.
|
||||
* @note If the compiler does not support such attribute then the
|
||||
* realtime counter precision could be degraded.
|
||||
*/
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
|
||||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file ivor.s
|
||||
* @brief Kernel ISRs.
|
||||
*
|
||||
* @addtogroup PPC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Code section. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Imports the PPC configuration headers.
|
||||
*/
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
.extern _stats_start_measure_crit_thd
|
||||
.extern _stats_stop_measure_crit_thd
|
||||
.extern _dbg_check_lock
|
||||
.extern _dbg_check_unlock
|
||||
.extern chSchIsPreemptionRequired
|
||||
.extern chSchDoReschedule
|
||||
.extern chSysTimerHandlerI
|
||||
|
||||
.section .handlers, text_vle
|
||||
|
||||
#if PPC_USE_VLE == TRUE
|
||||
|
||||
#if PPC_SUPPORTS_DECREMENTER
|
||||
/*
|
||||
* _IVOR10 handler (Book-E decrementer).
|
||||
*/
|
||||
.align 16
|
||||
.globl _IVOR10
|
||||
.type _IVOR10, @function
|
||||
_IVOR10:
|
||||
/* Saving the external context (port_extctx structure).*/
|
||||
e_stwu r1, -80(r1)
|
||||
e_stmvsrrw 8(r1) /* Saves PC, MSR. */
|
||||
e_stmvsprw 16(r1) /* Saves CR, LR, CTR, XER. */
|
||||
e_stmvgprw 32(r1) /* Saves GPR0, GPR3...GPR12. */
|
||||
|
||||
/* Increasing the SPGR0 register.*/
|
||||
mfspr r0, 272
|
||||
se_addi r0, 1
|
||||
mtspr 272, r0
|
||||
|
||||
/* Reset DIE bit in TSR register.*/
|
||||
e_lis r3, 0x0800 /* DIS bit mask. */
|
||||
mtspr 336, r3 /* TSR register. */
|
||||
|
||||
/* Restoring pre-IRQ MSR register value.*/
|
||||
mfSRR1 r0
|
||||
#if !PPC_USE_IRQ_PREEMPTION
|
||||
/* No preemption, keeping EE disabled.*/
|
||||
se_bclri r0, 16 /* EE = bit 16. */
|
||||
#endif
|
||||
mtMSR r0
|
||||
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_enter_isr
|
||||
bl _dbg_check_lock_from_isr
|
||||
#endif
|
||||
/* System tick handler invocation.*/
|
||||
e_bl chSysTimerHandlerI
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock_from_isr
|
||||
bl _dbg_check_leave_isr
|
||||
#endif
|
||||
|
||||
#if PPC_USE_IRQ_PREEMPTION
|
||||
/* Prevents preemption again.*/
|
||||
wrteei 0
|
||||
#endif
|
||||
|
||||
/* Jumps to the common IVOR epilogue code.*/
|
||||
se_b _ivor_exit
|
||||
#endif /* PPC_SUPPORTS_DECREMENTER */
|
||||
|
||||
/*
|
||||
* _IVOR4 handler (Book-E external interrupt).
|
||||
*/
|
||||
.align 16
|
||||
.globl _IVOR4
|
||||
.type _IVOR4, @function
|
||||
_IVOR4:
|
||||
/* Saving the external context (port_extctx structure).*/
|
||||
e_stwu r1, -80(r1)
|
||||
e_stmvsrrw 8(r1) /* Saves PC, MSR. */
|
||||
e_stmvsprw 16(r1) /* Saves CR, LR, CTR, XER. */
|
||||
e_stmvgprw 32(r1) /* Saves GPR0, GPR3...GPR12. */
|
||||
|
||||
/* Increasing the SPGR0 register.*/
|
||||
mfspr r0, 272
|
||||
se_addi r0, 1
|
||||
mtspr 272, r0
|
||||
|
||||
/* Software vector address from the INTC register.*/
|
||||
e_lis r3, INTC_IACKR_ADDR@h
|
||||
e_or2i r3, INTC_IACKR_ADDR@l /* IACKR register address. */
|
||||
se_lwz r3, 0(r3) /* IACKR register value. */
|
||||
se_lwz r3, 0(r3)
|
||||
mtCTR r3 /* Software handler address. */
|
||||
|
||||
/* Restoring pre-IRQ MSR register value.*/
|
||||
mfSRR1 r0
|
||||
#if !PPC_USE_IRQ_PREEMPTION
|
||||
/* No preemption, keeping EE disabled.*/
|
||||
se_bclri r0, 16 /* EE = bit 16. */
|
||||
#endif
|
||||
mtMSR r0
|
||||
|
||||
/* Exectes the software handler.*/
|
||||
se_bctrl
|
||||
|
||||
#if PPC_USE_IRQ_PREEMPTION
|
||||
/* Prevents preemption again.*/
|
||||
wrteei 0
|
||||
#endif
|
||||
|
||||
/* Informs the INTC that the interrupt has been served.*/
|
||||
mbar 0
|
||||
e_lis r3, INTC_EOIR_ADDR@h
|
||||
e_or2i r3, INTC_EOIR_ADDR@l
|
||||
se_stw r3, 0(r3) /* Writing any value should do. */
|
||||
|
||||
/* Common IVOR epilogue code, context restore.*/
|
||||
.globl _ivor_exit
|
||||
_ivor_exit:
|
||||
/* Decreasing the SPGR0 register.*/
|
||||
mfspr r0, 272
|
||||
se_subi r0, 1
|
||||
mtspr 272, r0
|
||||
|
||||
#if CH_DBG_STATISTICS
|
||||
e_bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
e_bl _dbg_check_lock
|
||||
#endif
|
||||
e_bl chSchIsPreemptionRequired
|
||||
e_cmpli cr0, r3, 0
|
||||
se_beq .noresch
|
||||
e_bl chSchDoReschedule
|
||||
.noresch:
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
e_bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
e_bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
|
||||
/* Restoring the external context.*/
|
||||
e_lmvgprw 32(r1) /* Restores GPR0, GPR3...GPR12. */
|
||||
e_lmvsprw 16(r1) /* Restores CR, LR, CTR, XER. */
|
||||
e_lmvsrrw 8(r1) /* Restores PC, MSR. */
|
||||
e_addi r1, r1, 80 /* Back to the previous frame. */
|
||||
se_rfi
|
||||
|
||||
#else /* PPC_USE_VLE == FALSE */
|
||||
|
||||
#error "non-VLE mode not yet implemented"
|
||||
|
||||
#endif /* PPC_USE_VLE == FALSE */
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file e200/compilers/GCC/chcoreasm.s
|
||||
* @brief Power Architecture port low level code.
|
||||
*
|
||||
* @addtogroup PPC_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Code section. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define _FROM_ASM_
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
/*
|
||||
* RTOS-specific context offset.
|
||||
*/
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
#define CONTEXT_OFFSET 12
|
||||
#elif defined(_CHIBIOS_NIL_CONF_)
|
||||
#define CONTEXT_OFFSET 0
|
||||
#else
|
||||
#error "invalid chconf.h"
|
||||
#endif
|
||||
|
||||
#if PPC_USE_VLE == TRUE
|
||||
.section .text_vle, "ax"
|
||||
#else
|
||||
.section .text, "ax"
|
||||
#endif
|
||||
|
||||
.align 2
|
||||
.globl _port_switch
|
||||
.type _port_switch, @function
|
||||
_port_switch:
|
||||
subi %sp, %sp, 80
|
||||
mflr %r0
|
||||
stw %r0, 84(%sp)
|
||||
mfcr %r0
|
||||
stw %r0, 0(%sp)
|
||||
stmw %r14, 4(%sp)
|
||||
|
||||
stw %sp, 12(%r4)
|
||||
lwz %sp, 12(%r3)
|
||||
|
||||
lmw %r14, 4(%sp)
|
||||
lwz %r0, 0(%sp)
|
||||
mtcr %r0
|
||||
lwz %r0, 84(%sp)
|
||||
mtlr %r0
|
||||
addi %sp, %sp, 80
|
||||
blr
|
||||
|
||||
.align 2
|
||||
.globl _port_thread_start
|
||||
.type _port_thread_start, @function
|
||||
_port_thread_start:
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
wrteei 1
|
||||
mr %r3, %r31
|
||||
mtctr %r30
|
||||
bctrl
|
||||
#if defined(_CHIBIOS_RT_CONF_)
|
||||
li %r0, 0
|
||||
bl chThdExit
|
||||
#endif
|
||||
#if defined(_CHIBIOS_NIL_CONF_)
|
||||
se_li %r0, 0
|
||||
e_bl chSysHalt
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
/** @} */
|
|
@ -18,15 +18,15 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file e200/compilers/GCC/niltypes.h
|
||||
* @file e200/compilers/GCC/chtypes.h
|
||||
* @brief Power e200 port system types.
|
||||
*
|
||||
* @addtogroup PPC_GCC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILTYPES_H_
|
||||
#define _NILTYPES_H_
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -46,26 +46,29 @@
|
|||
* @brief Generic 'true' boolean constant.
|
||||
*/
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE (!FALSE)
|
||||
#define TRUE 1
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
|
||||
/**
|
||||
* @brief Type of system time.
|
||||
*/
|
||||
#if (NIL_CFG_ST_RESOLUTION == 32) || defined(__DOXYGEN__)
|
||||
typedef uint32_t systime_t;
|
||||
#else
|
||||
typedef uint16_t systime_t;
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
|
@ -83,14 +86,8 @@ typedef uint16_t systime_t;
|
|||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) \
|
||||
__attribute__((noreturn)) void tname(void *arg)
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __attribute__((packed))
|
||||
|
||||
#endif /* _NILTYPES_H_ */
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -21,7 +21,7 @@
|
|||
* @file ivor.s
|
||||
* @brief Kernel ISRs.
|
||||
*
|
||||
* @addtogroup PPC_GCC_CORE
|
||||
* @addtogroup PPC_CORE
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
@ -37,8 +37,8 @@
|
|||
* Imports the PPC configuration headers.
|
||||
*/
|
||||
#define _FROM_ASM_
|
||||
#include "nilconf.h"
|
||||
#include "nilcore.h"
|
||||
#include "chconf.h"
|
||||
#include "chcore.h"
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
|
||||
|
@ -101,8 +101,16 @@ _IVOR10:
|
|||
#endif
|
||||
mtMSR %r0
|
||||
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_enter_isr
|
||||
bl _dbg_check_lock_from_isr
|
||||
#endif
|
||||
/* System tick handler invocation.*/
|
||||
bl chSysTimerHandlerI
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock_from_isr
|
||||
bl _dbg_check_leave_isr
|
||||
#endif
|
||||
|
||||
#if PPC_USE_IRQ_PREEMPTION
|
||||
/* Prevents preemption again.*/
|
||||
|
@ -159,7 +167,7 @@ _IVOR4:
|
|||
|
||||
/* Software vector address from the INTC register.*/
|
||||
lis %r3, INTC_IACKR_ADDR@h
|
||||
ori %r3, %r3, INTC_IACKR_ADDR@l
|
||||
ori %r3, %r3, INTC_IACKR_ADDR@l /* IACKR register address. */
|
||||
lwz %r3, 0(%r3) /* IACKR register value. */
|
||||
lwz %r3, 0(%r3)
|
||||
mtCTR %r3 /* Software handler address. */
|
||||
|
@ -194,7 +202,23 @@ _ivor_exit:
|
|||
eaddi %r0, %r0, -1
|
||||
mtspr 272, %r0
|
||||
|
||||
bl chSchRescheduleS
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_start_measure_crit_thd
|
||||
#endif
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_lock
|
||||
#endif
|
||||
bl chSchIsPreemptionRequired
|
||||
cmpli cr0, %r3, 0
|
||||
beq cr0, .noresch
|
||||
bl chSchDoReschedule
|
||||
.noresch:
|
||||
#if CH_DBG_SYSTEM_STATE_CHECK
|
||||
bl _dbg_check_unlock
|
||||
#endif
|
||||
#if CH_DBG_STATISTICS
|
||||
bl _stats_stop_measure_crit_thd
|
||||
#endif
|
||||
|
||||
/* Restoring the external context.*/
|
||||
#if PPC_USE_VLE && PPC_SUPPORTS_VLE_MULTI
|
|
@ -0,0 +1,8 @@
|
|||
# List of the ChibiOS/RT e200 generic port files.
|
||||
PORTSRC = $(CHIBIOS)/os/common/ports/e200/chcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/compilers/GCC/ivor.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/chcoreasm.s
|
||||
|
||||
PORTINC = $(CHIBIOS)/os/common/ports/e200 \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC
|
|
@ -0,0 +1,3 @@
|
|||
All the code contained under ./os/common/ports are RTOS ports compatible
|
||||
with both RT and NIL. The code is placed under ./os/common in order to
|
||||
prevent code duplication and disalignments.
|
|
@ -18,14 +18,19 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file templates/nilcore.c
|
||||
* @brief Port code.
|
||||
* @file templates/chcore.c
|
||||
* @brief Port related template code.
|
||||
* @details This file is a template of the system driver functions provided by
|
||||
* a port. Some of the following functions may be implemented as
|
||||
* macros in chcore.h if the implementer decides that there is an
|
||||
* advantage in doing so, for example because performance concerns.
|
||||
*
|
||||
* @addtogroup NIL_CORE
|
||||
* @addtogroup core
|
||||
* @details Non portable code templates.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "nil.h"
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
|
@ -51,57 +56,24 @@
|
|||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Port-related initialization code.
|
||||
* @note This function is usually empty.
|
||||
*/
|
||||
void _port_init(void) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs a context switch between two threads.
|
||||
* @details This is the most critical code in any port, this function
|
||||
* is responsible for the context switch between 2 threads.
|
||||
* @note The implementation of this code affects <b>directly</b> the context
|
||||
* switch performance so optimize here as much as you can.
|
||||
*
|
||||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#if !defined(__DOXYGEN__)
|
||||
__attribute__((naked))
|
||||
#endif
|
||||
void port_dummy1(void) {
|
||||
|
||||
asm (".global _port_switch");
|
||||
asm ("_port_switch:");
|
||||
asm ("subi %sp, %sp, 80"); /* Size of the intctx structure. */
|
||||
asm ("mflr %r0");
|
||||
asm ("stw %r0, 84(%sp)"); /* LR into the caller frame. */
|
||||
asm ("mfcr %r0");
|
||||
asm ("stw %r0, 0(%sp)"); /* CR. */
|
||||
asm ("stmw %r14, 4(%sp)"); /* GPR14...GPR31. */
|
||||
|
||||
asm ("stw %sp, 0(%r4)"); /* Store swapped-out stack. */
|
||||
asm ("lwz %sp, 0(%r3)"); /* Load swapped-in stack. */
|
||||
|
||||
asm ("lmw %r14, 4(%sp)"); /* GPR14...GPR31. */
|
||||
asm ("lwz %r0, 0(%sp)"); /* CR. */
|
||||
asm ("mtcr %r0");
|
||||
asm ("lwz %r0, 84(%sp)"); /* LR from the caller frame. */
|
||||
asm ("mtlr %r0");
|
||||
asm ("addi %sp, %sp, 80"); /* Size of the intctx structure. */
|
||||
asm ("blr");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a thread by invoking its work function.
|
||||
* @details If the work function returns @p chThdExit() is automatically
|
||||
* invoked.
|
||||
*/
|
||||
#if !defined(__DOXYGEN__)
|
||||
__attribute__((naked))
|
||||
#endif
|
||||
void port_dummy2(void) {
|
||||
|
||||
asm (".global _port_thread_start");
|
||||
asm ("_port_thread_start:");
|
||||
chSysUnlock();
|
||||
asm ("mr %r3, %r31"); /* Thread parameter. */
|
||||
asm ("mtctr %r30");
|
||||
asm ("bctrl"); /* Invoke thread function. */
|
||||
asm ("li %r0, 0");
|
||||
asm ("bl chSysHalt"); /* Thread termination on exit. */
|
||||
void _port_switch(thread_t *ntp, thread_t *otp) {
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -18,38 +18,68 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file templates/nilcore.h
|
||||
* @brief Port macros and structures.
|
||||
* @file templates/chcore.h
|
||||
* @brief Port related template macros and structures.
|
||||
* @details This file is a template of the system driver macros provided by
|
||||
* a port.
|
||||
*
|
||||
* @addtogroup NIL_CORE
|
||||
* @addtogroup core
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCORE_H_
|
||||
#define _NILCORE_H_
|
||||
#ifndef _CHCORE_H_
|
||||
#define _CHCORE_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Port Capabilities and Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
|
||||
/**
|
||||
* @brief Natural alignment constant.
|
||||
* @note It is the minimum alignment for pointer-size variables.
|
||||
*/
|
||||
#define PORT_NATURAL_ALIGN sizeof (void *)
|
||||
|
||||
/**
|
||||
* @brief Stack alignment constant.
|
||||
* @note It is the alignement required for the stack pointer.
|
||||
*/
|
||||
#define PORT_STACK_ALIGN sizeof (stkalign_t)
|
||||
|
||||
/**
|
||||
* @brief Working Areas alignment constant.
|
||||
* @note It is the alignment to be enforced for thread working areas.
|
||||
*/
|
||||
#define PORT_WORKING_AREA_ALIGN sizeof (stkalign_t)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Architecture and Compiler
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Macro defining the port architecture.
|
||||
* @brief Macro defining an XXX architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_XXX
|
||||
|
||||
/**
|
||||
* @brief Name of the implemented architecture.
|
||||
* @brief Macro defining the specific XXX architecture.
|
||||
*/
|
||||
#define PORT_ARCHITECTURE_NAME "XXX"
|
||||
#define PORT_ARCHITECTURE_XXX_YYY
|
||||
|
||||
/**
|
||||
* @brief Name of the architecture variant.
|
||||
* @brief Name of the implemented architecture.
|
||||
*/
|
||||
#define PORT_CORE_VARIANT_NAME "XXXX-Y"
|
||||
#define PORT_ARCHITECTURE_NAME "XXX Architecture"
|
||||
|
||||
/**
|
||||
* @brief Compiler name and version.
|
||||
|
@ -64,37 +94,49 @@
|
|||
/**
|
||||
* @brief Port-specific information string.
|
||||
*/
|
||||
#define PORT_INFO "port description"
|
||||
|
||||
/**
|
||||
* @brief This port supports a realtime counter.
|
||||
*/
|
||||
#define PORT_SUPPORTS_RT FALSE
|
||||
#define PORT_INFO "no info"
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Stack size for the system idle thread.
|
||||
* @details This size depends on the idle thread implementation, usually
|
||||
* the idle thread should take no more space than those reserved
|
||||
* by @p PORT_INT_REQUIRED_STACK.
|
||||
*/
|
||||
#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
|
||||
#define PORT_IDLE_THREAD_STACK_SIZE 32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Per-thread stack overhead for interrupts servicing.
|
||||
* @details This constant is used in the calculation of the correct working
|
||||
* area size.
|
||||
*/
|
||||
#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
|
||||
#define PORT_INT_REQUIRED_STACK 32
|
||||
#define PORT_INT_REQUIRED_STACK 256
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables an alternative timer implementation.
|
||||
* @details Usually the port uses a timer interface defined in the file
|
||||
* @p nilcore_timer.h, if this option is enabled then the file
|
||||
* @p nilcore_timer_alt.h is included instead.
|
||||
* @p chcore_timer.h, if this option is enabled then the file
|
||||
* @p chcore_timer_alt.h is included instead.
|
||||
*/
|
||||
#if !defined(PORT_USE_ALT_TIMER)
|
||||
#if !defined(PORT_USE_ALT_TIMER) || defined(__DOXYGEN__)
|
||||
#define PORT_USE_ALT_TIMER FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables a "wait for interrupt" instruction in the idle loop.
|
||||
*/
|
||||
#if !defined(PORT_XXX_WFI_SLEEP_IDLE) || defined(__DOXYGEN__)
|
||||
#define PORT_XXX_ENABLE_WFI_IDLE FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
@ -109,6 +151,7 @@
|
|||
|
||||
/**
|
||||
* @brief Type of stack and memory alignment enforcement.
|
||||
* @note In this architecture the stack alignment is enforced to 64 bits.
|
||||
*/
|
||||
typedef uint64_t stkalign_t;
|
||||
|
||||
|
@ -116,20 +159,31 @@ typedef uint64_t stkalign_t;
|
|||
* @brief Interrupt saved context.
|
||||
* @details This structure represents the stack frame saved during a
|
||||
* preemption-capable interrupt handler.
|
||||
* @note R2 and R13 are not saved because those are assumed to be immutable
|
||||
* during the system life cycle.
|
||||
*/
|
||||
struct port_extctx {
|
||||
uint32_t reg1;
|
||||
uint32_t reg2;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief System saved context.
|
||||
* @details This structure represents the inner stack frame during a context
|
||||
* switch.
|
||||
* switching.
|
||||
* @note R2 and R13 are not saved because those are assumed to be immutable
|
||||
* during the system life cycle.
|
||||
* @note LR is stored in the caller context so it is not present in this
|
||||
* structure.
|
||||
*/
|
||||
struct port_intctx {
|
||||
uint32_t reg3;
|
||||
uint32_t reg4;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Platform dependent part of the @p thread_t structure.
|
||||
* @details This structure usually contains just the saved stack pointer
|
||||
* defined as a pointer to a @p port_intctx structure.
|
||||
*/
|
||||
struct port_context {
|
||||
struct port_intctx *sp;
|
||||
};
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
@ -139,16 +193,12 @@ struct port_intctx {
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Platform dependent thread stack setup.
|
||||
* @brief Platform dependent part of the @p chThdCreateI() API.
|
||||
* @details This code usually setup the context switching frame represented
|
||||
* by an @p port_intctx structure.
|
||||
*/
|
||||
#define PORT_SETUP_CONTEXT(tp, wend, pf, arg) do { \
|
||||
(void)(tp); \
|
||||
(void)(wend); \
|
||||
(void)(pf); \
|
||||
(void)(arg); \
|
||||
} while (false)
|
||||
#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes the thread working area global size.
|
||||
|
@ -156,8 +206,18 @@ struct port_intctx {
|
|||
*/
|
||||
#define PORT_WA_SIZE(n) (sizeof(struct port_intctx) + \
|
||||
sizeof(struct port_extctx) + \
|
||||
(size_t)(n) + \
|
||||
(size_t)(PORT_INT_REQUIRED_STACK))
|
||||
((size_t)(n)) + ((size_t)(PORT_INT_REQUIRED_STACK)))
|
||||
|
||||
/**
|
||||
* @brief Static working area allocation.
|
||||
* @details This macro is used to allocate a static thread working area
|
||||
* aligned as both position and size.
|
||||
*
|
||||
* @param[in] s the name to be assigned to the stack array
|
||||
* @param[in] n the stack size to be assigned to the thread
|
||||
*/
|
||||
#define PORT_WORKING_AREA(s, n) \
|
||||
stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
|
||||
|
||||
/**
|
||||
* @brief Priority level verification macro.
|
||||
|
@ -181,7 +241,7 @@ struct port_intctx {
|
|||
* @details This macro must be inserted at the end of all IRQ handlers
|
||||
* enabled to invoke system APIs.
|
||||
*/
|
||||
#define PORT_IRQ_EPILOGUE() _port_irq_epilogue()
|
||||
#define PORT_IRQ_EPILOGUE()
|
||||
|
||||
/**
|
||||
* @brief IRQ handler function declaration.
|
||||
|
@ -207,11 +267,16 @@ struct port_intctx {
|
|||
* @param[in] ntp the thread to be switched in
|
||||
* @param[in] otp the thread to be switched out
|
||||
*/
|
||||
#define port_switch(ntp, otp) do { \
|
||||
(void)ntp; \
|
||||
(void)otp; \
|
||||
/*_port_switch(ntp, otp)*/ \
|
||||
} while (false)
|
||||
#if !CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__)
|
||||
#define port_switch(ntp, otp) _port_switch(ntp, otp)
|
||||
#else
|
||||
#define port_switch(ntp, otp) { \
|
||||
register struct port_intctx *sp asm ("%r1"); \
|
||||
if ((stkalign_t *)(sp - 1) < otp->stklimit) \
|
||||
chSysHalt("stack overflow"); \
|
||||
_port_switch(ntp, otp); \
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
|
@ -224,9 +289,8 @@ struct port_intctx {
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _port_irq_epilogue(void);
|
||||
void _port_init(void);
|
||||
void _port_switch(thread_t *ntp, thread_t *otp);
|
||||
void _port_thread_start(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -241,13 +305,6 @@ extern "C" {
|
|||
asm module.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
/**
|
||||
* @brief Port-related initialization code.
|
||||
*/
|
||||
static inline void port_init(void) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a word encoding the current interrupts status.
|
||||
*
|
||||
|
@ -255,7 +312,7 @@ static inline void port_init(void) {
|
|||
*/
|
||||
static inline syssts_t port_get_irq_status(void) {
|
||||
|
||||
return (syssts_t)0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -288,6 +345,8 @@ static inline bool port_is_isr_context(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-lock action.
|
||||
* @details Usually this function just disables interrupts but may perform more
|
||||
* actions.
|
||||
*/
|
||||
static inline void port_lock(void) {
|
||||
|
||||
|
@ -295,6 +354,8 @@ static inline void port_lock(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-unlock action.
|
||||
* @details Usually this function just enables interrupts but may perform more
|
||||
* actions.
|
||||
*/
|
||||
static inline void port_unlock(void) {
|
||||
|
||||
|
@ -302,6 +363,9 @@ static inline void port_unlock(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-lock action from an interrupt handler.
|
||||
* @details This function is invoked before invoking I-class APIs from
|
||||
* interrupt handlers. The implementation is architecture dependent,
|
||||
* in its simplest form it is void.
|
||||
*/
|
||||
static inline void port_lock_from_isr(void) {
|
||||
|
||||
|
@ -309,6 +373,9 @@ static inline void port_lock_from_isr(void) {
|
|||
|
||||
/**
|
||||
* @brief Kernel-unlock action from an interrupt handler.
|
||||
* @details This function is invoked after invoking I-class APIs from interrupt
|
||||
* handlers. The implementation is architecture dependent, in its
|
||||
* simplest form it is void.
|
||||
*/
|
||||
static inline void port_unlock_from_isr(void) {
|
||||
|
||||
|
@ -316,6 +383,7 @@ static inline void port_unlock_from_isr(void) {
|
|||
|
||||
/**
|
||||
* @brief Disables all the interrupt sources.
|
||||
* @note Of course non-maskable interrupt sources are not included.
|
||||
*/
|
||||
static inline void port_disable(void) {
|
||||
|
||||
|
@ -323,6 +391,7 @@ static inline void port_disable(void) {
|
|||
|
||||
/**
|
||||
* @brief Disables the interrupt sources below kernel-level priority.
|
||||
* @note Interrupt sources above kernel level remains enabled.
|
||||
*/
|
||||
static inline void port_suspend(void) {
|
||||
|
||||
|
@ -344,6 +413,8 @@ static inline void port_enable(void) {
|
|||
*/
|
||||
static inline void port_wait_for_interrupt(void) {
|
||||
|
||||
#if PORT_XXX_ENABLE_WFI_IDLE
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -353,7 +424,7 @@ static inline void port_wait_for_interrupt(void) {
|
|||
*/
|
||||
static inline rtcnt_t port_rt_get_counter_value(void) {
|
||||
|
||||
return (rtcnt_t)0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
@ -362,18 +433,20 @@ static inline rtcnt_t port_rt_get_counter_value(void) {
|
|||
/* Module late inclusions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/* The following code is not processed when the file is included from an
|
||||
asm module.*/
|
||||
#if !defined(_FROM_ASM_)
|
||||
|
||||
#if NIL_CFG_ST_TIMEDELTA > 0
|
||||
#if PORT_USE_ALT_TIMER == FALSE
|
||||
#include "nilcore_timer.h"
|
||||
#else
|
||||
#include "nilcore_timer_alt.h"
|
||||
#endif
|
||||
#endif /* NIL_CFG_ST_TIMEDELTA > 0 */
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
#if !PORT_USE_ALT_TIMER
|
||||
#include "chcore_timer.h"
|
||||
#else /* PORT_USE_ALT_TIMER */
|
||||
#include "chcore_timer_alt.h"
|
||||
#endif /* PORT_USE_ALT_TIMER */
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
|
||||
#endif /* !defined(_FROM_ASM_) */
|
||||
|
||||
#endif /* _NILCORE_H_ */
|
||||
#endif /* _CHCORE_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file templates/chtypes.h
|
||||
* @brief System types template.
|
||||
* @details The types defined in this file may change depending on the target
|
||||
* architecture. You may also try to optimize the size of the various
|
||||
* types in order to privilege size or performance, be careful in
|
||||
* doing so.
|
||||
*
|
||||
* @addtogroup types
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _CHTYPES_H_
|
||||
#define _CHTYPES_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @name Common constants
|
||||
*/
|
||||
/**
|
||||
* @brief Generic 'false' boolean constant.
|
||||
*/
|
||||
#if !defined(FALSE) || defined(__DOXYGEN__)
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Generic 'true' boolean constant.
|
||||
*/
|
||||
#if !defined(TRUE) || defined(__DOXYGEN__)
|
||||
#define TRUE (!FALSE)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Kernel types
|
||||
* @{
|
||||
*/
|
||||
typedef uint32_t rtcnt_t; /**< Realtime counter. */
|
||||
typedef uint64_t rttime_t; /**< Realtime accumulator. */
|
||||
typedef uint32_t syssts_t; /**< System status word. */
|
||||
typedef uint8_t tmode_t; /**< Thread flags. */
|
||||
typedef uint8_t tstate_t; /**< Thread state. */
|
||||
typedef uint8_t trefs_t; /**< Thread references counter. */
|
||||
typedef uint8_t tslices_t; /**< Thread time slices counter.*/
|
||||
typedef uint32_t tprio_t; /**< Thread priority. */
|
||||
typedef int32_t msg_t; /**< Inter-thread message. */
|
||||
typedef int32_t eventid_t; /**< Numeric event identifier. */
|
||||
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
|
||||
typedef uint32_t eventflags_t; /**< Mask of event flags. */
|
||||
typedef int32_t cnt_t; /**< Generic signed counter. */
|
||||
typedef uint32_t ucnt_t; /**< Generic unsigned counter. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief ROM constant modifier.
|
||||
* @note It is set to use the "const" keyword in this port.
|
||||
*/
|
||||
#define ROMCONST const
|
||||
|
||||
/**
|
||||
* @brief Makes functions not inlineable.
|
||||
* @note If the compiler does not support such attribute then the
|
||||
* realtime counter precision could be degraded.
|
||||
*/
|
||||
#define NOINLINE __attribute__((noinline))
|
||||
|
||||
/**
|
||||
* @brief Optimized thread function declaration macro.
|
||||
*/
|
||||
#define PORT_THD_FUNCTION(tname, arg) void tname(void *arg)
|
||||
|
||||
/**
|
||||
* @brief Packed variable specifier.
|
||||
*/
|
||||
#define PACKED_VAR __attribute__((packed))
|
||||
|
||||
/**
|
||||
* @brief Memory alignment enforcement for variables.
|
||||
*/
|
||||
#define ALIGNED_VAR(n) __attribute__((aligned(n)))
|
||||
|
||||
#endif /* _CHTYPES_H_ */
|
||||
|
||||
/** @} */
|
|
@ -1,9 +1,9 @@
|
|||
# List of the ChibiOS generic LPC214x file.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARM/compilers/GCC/crt1.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARM/compilers/GCC/crt1.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARM/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/ARM/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARM/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/ARM/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/ARM/devices/LPC214x
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/ARM/devices/LPC214x
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/ARM/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/ARM/compilers/GCC/ld
|
||||
|
|
|
@ -117,6 +117,7 @@ SECTIONS
|
|||
{
|
||||
. = ALIGN(8);
|
||||
__stacks_base__ = .;
|
||||
__main_thread_stack_base__ = .;
|
||||
. += __stacks_total_size__;
|
||||
. = ALIGN(8);
|
||||
__stacks_end__ = .;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic K20x startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/K20x \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/KINETIS
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/K20x \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/KINETIS
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic KL2x startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/KL2x \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/KINETIS
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/KL2x \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/KINETIS
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32F0xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F0xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32F0xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F0xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F0xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32F1xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F1xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32F1xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F1xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F1xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32F2xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F2xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32F2xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F2xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F2xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32F3xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F3xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32F3xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F3xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F3xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32F4xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F4xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32F4xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F4xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F4xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32F7xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32F7xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32F7xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32F7xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32F7xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32L0xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v6m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32L0xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32L0xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32L0xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32L0xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32L1xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32L1xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32L1xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32L1xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32L1xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# List of the ChibiOS generic STM32L4xx startup and CMSIS files.
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/vectors.c
|
||||
STARTUPSRC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt1.c \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/vectors.c
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/crt0_v7m.s
|
||||
|
||||
STARTUPINC = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/ports/ARMCMx/devices/STM32L4xx \
|
||||
$(CHIBIOS)/os/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/ext/CMSIS/ST/STM32L4xx
|
||||
STARTUPINC = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC \
|
||||
$(CHIBIOS)/os/common/startup/ARMCMx/devices/STM32L4xx \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/include \
|
||||
$(CHIBIOS)/os/common/ext/CMSIS/ST/STM32L4xx
|
||||
|
||||
STARTUPLD = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/ld
|
||||
STARTUPLD = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z0 SPC560BCxx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560BCxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560BCxx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560BCxx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC560BCxx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z0 SPC560Bxx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Bxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560Bxx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560Bxx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC560Bxx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z0 SPC560Dxx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Dxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560Dxx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560Dxx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC560Dxx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z0 SPC560Pxx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Pxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC560Pxx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560Pxx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC560Pxx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z3 SPC563Mxx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC563Mxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC563Mxx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC563Mxx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC563Mxx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z4 SPC564Axx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC564Axx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC564Axx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC564Axx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC564Axx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z4 SPC56ECxx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ECxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC56ECxx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC56ECxx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC56ECxx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# List of the ChibiOS e200z4 SPC56ELxx startup files.
|
||||
STARTUPSRC =
|
||||
|
||||
STARTUPASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ELxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s
|
||||
STARTUPASM = $(CHIBIOS)/os/common/startup/e200/devices/SPC56ELxx/boot.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/startup/e200/compilers/GCC/crt0.s
|
||||
|
||||
STARTUPINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC56ELxx
|
||||
STARTUPINC = ${CHIBIOS}/os/common/startup/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/startup/e200/devices/SPC56ELxx
|
||||
|
||||
STARTUPLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
||||
STARTUPLD = ${CHIBIOS}/os/common/startup/e200/compilers/GCC/ld
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
# List of the ChibiOS/NIL ARMv6M generic port files.
|
||||
PORTSRC = $(CHIBIOS)/os/nil/ports/ARMCMx/nilcore.c \
|
||||
$(CHIBIOS)/os/nil/ports/ARMCMx/nilcore_v6m.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v6m.s
|
||||
|
||||
PORTINC = $(CHIBIOS)/os/nil/ports/ARMCMx \
|
||||
$(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC
|
|
@ -1,8 +0,0 @@
|
|||
# List of the ChibiOS/NIL ARMv7M generic port files.
|
||||
PORTSRC = $(CHIBIOS)/os/nil/ports/ARMCMx/nilcore.c \
|
||||
$(CHIBIOS)/os/nil/ports/ARMCMx/nilcore_v7m.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC/nilcoreasm_v7m.s
|
||||
|
||||
PORTINC = $(CHIBIOS)/os/nil/ports/ARMCMx \
|
||||
$(CHIBIOS)/os/nil/ports/ARMCMx/compilers/GCC
|
|
@ -1,7 +0,0 @@
|
|||
# List of the ChibiOS/RT AVR port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/AVR/nilcore.c
|
||||
|
||||
PORTASM =
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/nil/ports/AVR \
|
||||
${CHIBIOS}/os/nil/ports/AVR/compilers/GCC
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z0 SPC560BCxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560BCxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560BCxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z0 SPC560Bxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Bxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560Bxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z0 SPC560Dxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Dxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560Dxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z0 SPC560Pxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC560Pxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC560Pxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z3 SPC563Mxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC563Mxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC563Mxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z4 SPC564Axx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC564Axx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC564Axx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z4 SPC56ECxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ECxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC56ECxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z4 SPC56ELxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC56ELxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC56ELxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -1,14 +0,0 @@
|
|||
# List of the ChibiOS/NIL e200z4 SPC57EMxx port files.
|
||||
PORTSRC = ${CHIBIOS}/os/nil/ports/e200/nilcore.c
|
||||
|
||||
PORTASM = $(CHIBIOS)/os/common/ports/e200/devices/SPC57EMxx/boot.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/vectors.s \
|
||||
$(CHIBIOS)/os/common/ports/e200/compilers/GCC/crt0.s \
|
||||
$(CHIBIOS)/os/nil/ports/e200/compilers/GCC/ivor.s
|
||||
|
||||
PORTINC = ${CHIBIOS}/os/common/ports/e200/compilers/GCC \
|
||||
${CHIBIOS}/os/common/ports/e200/devices/SPC57EMxx \
|
||||
${CHIBIOS}/os/nil/ports/e200 \
|
||||
${CHIBIOS}/os/nil/ports/e200/compilers/GCC
|
||||
|
||||
PORTLD = ${CHIBIOS}/os/common/ports/e200/compilers/GCC/ld
|
|
@ -15,18 +15,20 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* @file nilconf.h
|
||||
* @file chconf.h
|
||||
* @brief Configuration file template.
|
||||
* @details A copy of this file must be placed in each project directory, it
|
||||
* contains the application specific kernel settings.
|
||||
*
|
||||
* @addtogroup NIL_CONFIG
|
||||
* @addtogroup config
|
||||
* @details Kernel related settings and hooks.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _NILCONF_H_
|
||||
#define _NILCONF_H_
|
||||
#ifndef _CHCONF_H_
|
||||
#define _CHCONF_H_
|
||||
|
||||
#define _CHIBIOS_NIL_CONF_
|
||||
|
||||
/*===========================================================================*/
|
||||
/**
|
||||
|
@ -40,7 +42,7 @@
|
|||
* @note This number is not inclusive of the idle thread which is
|
||||
* Implicitly handled.
|
||||
*/
|
||||
#define NIL_CFG_NUM_THREADS 1
|
||||
#define CH_CFG_NUM_THREADS 3
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -55,15 +57,15 @@
|
|||
* @brief System time counter resolution.
|
||||
* @note Allowed values are 16 or 32 bits.
|
||||
*/
|
||||
#define NIL_CFG_ST_RESOLUTION 32
|
||||
#define CH_CFG_ST_RESOLUTION 32
|
||||
|
||||
/**
|
||||
* @brief System tick frequency.
|
||||
* @note This value together with the @p NIL_CFG_ST_RESOLUTION
|
||||
* @note This value together with the @p CH_CFG_ST_RESOLUTION
|
||||
* option defines the maximum amount of time allowed for
|
||||
* timeouts.
|
||||
*/
|
||||
#define NIL_CFG_ST_FREQUENCY 50000
|
||||
#define CH_CFG_ST_FREQUENCY 1000
|
||||
|
||||
/**
|
||||
* @brief Time delta constant for the tick-less mode.
|
||||
|
@ -73,7 +75,7 @@
|
|||
* The value one is not valid, timeouts are rounded up to
|
||||
* this value.
|
||||
*/
|
||||
#define NIL_CFG_ST_TIMEDELTA 2
|
||||
#define CH_CFG_ST_TIMEDELTA 0
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -84,13 +86,80 @@
|
|||
*/
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Semaphores APIs.
|
||||
* @details If enabled then the Semaphores APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define CH_CFG_USE_SEMAPHORES TRUE
|
||||
|
||||
/**
|
||||
* @brief Mutexes APIs.
|
||||
* @details If enabled then the mutexes APIs are included in the kernel.
|
||||
*
|
||||
* @note Feature not currently implemented.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#define CH_CFG_USE_MUTEXES FALSE
|
||||
|
||||
/**
|
||||
* @brief Events Flags APIs.
|
||||
* @details If enabled then the event flags APIs are included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define NIL_CFG_USE_EVENTS TRUE
|
||||
#define CH_CFG_USE_EVENTS TRUE
|
||||
|
||||
/**
|
||||
* @brief Mailboxes APIs.
|
||||
* @details If enabled then the asynchronous messages (mailboxes) APIs are
|
||||
* included in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
* @note Requires @p CH_CFG_USE_SEMAPHORES.
|
||||
*/
|
||||
#define CH_CFG_USE_MAILBOXES TRUE
|
||||
|
||||
/**
|
||||
* @brief Core Memory Manager APIs.
|
||||
* @details If enabled then the core memory manager APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define CH_CFG_USE_MEMCORE TRUE
|
||||
|
||||
/**
|
||||
* @brief Heap Allocator APIs.
|
||||
* @details If enabled then the memory heap allocator APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define CH_CFG_USE_HEAP TRUE
|
||||
|
||||
/**
|
||||
* @brief Memory Pools Allocator APIs.
|
||||
* @details If enabled then the memory pools allocator APIs are included
|
||||
* in the kernel.
|
||||
*
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#define CH_CFG_USE_MEMPOOLS TRUE
|
||||
|
||||
/**
|
||||
* @brief Managed RAM size.
|
||||
* @details Size of the RAM area to be managed by the OS. If set to zero
|
||||
* then the whole available RAM is used. The core memory is made
|
||||
* available to the heap allocator and/or can be used directly through
|
||||
* the simplified core memory allocator.
|
||||
*
|
||||
* @note In order to let the OS manage the whole RAM the linker script must
|
||||
* provide the @p __heap_base__ and @p __heap_end__ symbols.
|
||||
* @note Requires @p CH_CFG_USE_MEMCORE.
|
||||
*/
|
||||
#define CH_CFG_MEMCORE_SIZE 0
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -102,14 +171,40 @@
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief System assertions.
|
||||
* @brief Debug option, kernel statistics.
|
||||
*
|
||||
* @note Feature not currently implemented.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#define NIL_CFG_ENABLE_ASSERTS FALSE
|
||||
#define CH_DBG_STATISTICS FALSE
|
||||
|
||||
/**
|
||||
* @brief Debug option, system state check.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#define CH_DBG_SYSTEM_STATE_CHECK TRUE
|
||||
|
||||
/**
|
||||
* @brief Debug option, parameters checks.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#define CH_DBG_ENABLE_CHECKS TRUE
|
||||
|
||||
/**
|
||||
* @brief System assertions.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#define CH_DBG_ENABLE_ASSERTS TRUE
|
||||
|
||||
/**
|
||||
* @brief Stack check.
|
||||
*
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#define NIL_CFG_ENABLE_STACK_CHECK FALSE
|
||||
#define CH_DBG_ENABLE_STACK_CHECK TRUE
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -123,8 +218,8 @@
|
|||
/**
|
||||
* @brief System initialization hook.
|
||||
*/
|
||||
#if !defined(NIL_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__)
|
||||
#define NIL_CFG_SYSTEM_INIT_HOOK() { \
|
||||
#if !defined(CH_CFG_SYSTEM_INIT_HOOK) || defined(__DOXYGEN__)
|
||||
#define CH_CFG_SYSTEM_INIT_HOOK() { \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -132,13 +227,13 @@
|
|||
* @brief Threads descriptor structure extension.
|
||||
* @details User fields added to the end of the @p thread_t structure.
|
||||
*/
|
||||
#define NIL_CFG_THREAD_EXT_FIELDS \
|
||||
#define CH_CFG_THREAD_EXT_FIELDS \
|
||||
/* Add threads custom fields here.*/
|
||||
|
||||
/**
|
||||
* @brief Threads initialization hook.
|
||||
*/
|
||||
#define NIL_CFG_THREAD_EXT_INIT_HOOK(tr) { \
|
||||
#define CH_CFG_THREAD_EXT_INIT_HOOK(tr) { \
|
||||
/* Add custom threads initialization code here.*/ \
|
||||
}
|
||||
|
||||
|
@ -148,7 +243,7 @@
|
|||
* should be invoked from here.
|
||||
* @note This macro can be used to activate a power saving mode.
|
||||
*/
|
||||
#define NIL_CFG_IDLE_ENTER_HOOK() { \
|
||||
#define CH_CFG_IDLE_ENTER_HOOK() { \
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,14 +252,14 @@
|
|||
* should be invoked from here.
|
||||
* @note This macro can be used to deactivate a power saving mode.
|
||||
*/
|
||||
#define NIL_CFG_IDLE_LEAVE_HOOK() { \
|
||||
#define CH_CFG_IDLE_LEAVE_HOOK() { \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System halt hook.
|
||||
*/
|
||||
#if !defined(NIL_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
|
||||
#define NIL_CFG_SYSTEM_HALT_HOOK(reason) { \
|
||||
#if !defined(CH_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__)
|
||||
#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -174,6 +269,6 @@
|
|||
/* Port-specific settings (override port settings defaulted in nilcore.h). */
|
||||
/*===========================================================================*/
|
||||
|
||||
#endif /* _NILCONF_H_ */
|
||||
#endif /* _CHCONF_H_ */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue