Tree reorganization.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8899 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
Giovanni Di Sirio 2016-02-16 09:59:21 +00:00
parent 5e24a813be
commit 641f2c3726
99 changed files with 7937 additions and 766 deletions

View File

@ -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.

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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.

View File

@ -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 */
/** @} */

View File

@ -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 */
/** @} */

View File

@ -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 */
/** @} */

View File

@ -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 */
/** @} */

View File

@ -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 */
/** @} */

View File

@ -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. */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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__) */
/** @} */

View File

@ -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>
@ -39,33 +39,36 @@
* @brief Generic 'false' boolean constant.
*/
#if !defined(FALSE) || defined(__DOXYGEN__)
#define FALSE 0
#define FALSE 0
#endif
/**
* @brief Generic 'true' boolean constant.
*/
#if !defined(TRUE) || defined(__DOXYGEN__)
#define TRUE 1
#define TRUE 1
#endif
/** @} */
typedef uint32_t syssts_t; /**< System status word. */
typedef uint32_t rtcnt_t; /**< Realtime counter. */
typedef uint8_t tstate_t; /**< Thread state. */
typedef int32_t msg_t; /**< Inter-thread message. */
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
typedef int32_t cnt_t; /**< Generic signed counter. */
typedef uint32_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 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.
@ -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_ */
/** @} */

View File

@ -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

View File

@ -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. */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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_ */
/** @} */

View File

@ -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;
}
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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

View File

@ -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
@ -62,12 +72,12 @@ _port_switch:
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
@ -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

View File

@ -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

View File

@ -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>
@ -39,33 +39,36 @@
* @brief Generic 'false' boolean constant.
*/
#if !defined(FALSE) || defined(__DOXYGEN__)
#define FALSE 0
#define FALSE 0
#endif
/**
* @brief Generic 'true' boolean constant.
*/
#if !defined(TRUE) || defined(__DOXYGEN__)
#define TRUE 1
#define TRUE 1
#endif
/** @} */
typedef uint32_t syssts_t; /**< System status word. */
typedef uint32_t rtcnt_t; /**< Realtime counter. */
typedef uint8_t tstate_t; /**< Thread state. */
typedef int32_t msg_t; /**< Inter-thread message. */
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
typedef int32_t cnt_t; /**< Generic signed counter. */
typedef uint32_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 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.
@ -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_ */
/** @} */

View File

@ -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

View File

@ -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

View File

@ -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__) */
/** @} */

View File

@ -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__) */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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__) */
/** @} */

View File

@ -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__) */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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");
}
/** @} */

View File

@ -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)) - \
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; \
#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->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)) - \
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; \
#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->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))
#define PORT_WA_SIZE(n) ((sizeof(struct port_intctx) - 1) + \
(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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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>
@ -39,33 +39,36 @@
* @brief Generic 'false' boolean constant.
*/
#if !defined(FALSE) || defined(__DOXYGEN__)
#define FALSE 0
#define FALSE 0
#endif
/**
* @brief Generic 'true' boolean constant.
*/
#if !defined(TRUE) || defined(__DOXYGEN__)
#define TRUE (!FALSE)
#define TRUE (!FALSE)
#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_ */
/** @} */

View File

@ -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

View File

@ -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);
}
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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

View File

@ -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. */
/*===========================================================================*/
/** @} */

View File

@ -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");
{
/* The CPU supports IVOR registers, the kernel requires IVOR4 and IVOR10
and the initialization is performed here.*/
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_ */
/** @} */

View File

@ -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__) */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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__) */
/** @} */

View File

@ -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__) */
/** @} */

View File

@ -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>
@ -39,33 +39,36 @@
* @brief Generic 'false' boolean constant.
*/
#if !defined(FALSE) || defined(__DOXYGEN__)
#define FALSE 0
#define FALSE 0
#endif
/**
* @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. */
typedef uint32_t rtcnt_t; /**< Realtime counter. */
typedef uint8_t tstate_t; /**< Thread state. */
typedef int32_t msg_t; /**< Inter-thread message. */
typedef uint32_t eventmask_t; /**< Mask of event identifiers. */
typedef int32_t cnt_t; /**< Generic signed counter. */
typedef uint32_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 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.
@ -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_ */
/** @} */

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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) {
}
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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_ */
/** @} */

View File

@ -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

View File

@ -117,6 +117,7 @@ SECTIONS
{
. = ALIGN(8);
__stacks_base__ = .;
__main_thread_stack_base__ = .;
. += __stacks_total_size__;
. = ALIGN(8);
__stacks_end__ = .;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_ */
/** @} */