Update codebase for CMSIS5/RTX5

Update all of mbed-os to use RTX5.
pull/4294/head
Bartek Szatkowski 2017-05-15 09:55:45 -05:00 committed by Martin Kojtal
parent b97ffe8fdc
commit b793a3fb89
50 changed files with 1684 additions and 1116 deletions

View File

@ -142,7 +142,7 @@ void test_dual_thread_lock_lock_thread(Mutex *mutex)
uint32_t start = us_ticker_read();
osStatus stat = mutex->lock(TEST_HALF_SEC_MS);
TEST_ASSERT_EQUAL(stat, osEventTimeout);
TEST_ASSERT_EQUAL(stat, osErrorTimeout);
TEST_ASSERT_UINT32_WITHIN(TEST_ONE_MS_US, TEST_HALF_SEC_US, us_ticker_read() - start);
}

View File

@ -61,11 +61,13 @@ void self_terminate(Thread *self) {
// Tests that spawn tasks in different configurations
template <void (*F)(counter_t *)>
void test_single_thread() {
const char tname[] = "Single Thread";
counter_t counter(0);
Thread thread(osPriorityNormal, THREAD_STACK_SIZE, NULL);
Thread thread(osPriorityNormal, THREAD_STACK_SIZE, NULL, tname);
thread.start(callback(F, &counter));
thread.join();
TEST_ASSERT_EQUAL(counter, 1);
TEST_ASSERT_EQUAL(strcmp(tname, thread.get_name()), 0);
}
template <int N, void (*F)(counter_t *)>

View File

@ -112,7 +112,7 @@ typedef struct equeue_sema {
bool signal;
} equeue_sema_t;
#elif defined(EQUEUE_PLATFORM_MBED) && defined(MBED_CONF_RTOS_PRESENT)
typedef unsigned equeue_sema_t[8];
typedef unsigned equeue_sema_t[9];
#elif defined(EQUEUE_PLATFORM_MBED)
typedef volatile int equeue_sema_t;
#endif

View File

@ -16,7 +16,7 @@
#ifndef __BLE_IBEACON_H__
#define __BLE_IBEACON_H__
#include "core_cmInstr.h"
#include "cmsis_compiler.h"
#include "ble/BLE.h"
/**

View File

@ -4,22 +4,30 @@
#include "arm_hal_interrupt.h"
#include "arm_hal_interrupt_private.h"
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_rtos_storage.h"
#include <mbed_assert.h>
static uint8_t sys_irq_disable_counter;
static osMutexDef(critical);
static osMutexId critical_mutex_id;
static mbed_rtos_storage_mutex_t critical_mutex;
static const osMutexAttr_t critical_mutex_attr = {
.name = "critical_mutex",
.attr_bits = osMutexRecursive,
.cb_mem = &critical_mutex,
.cb_size = sizeof critical_mutex,
};
static osMutexId_t critical_mutex_id;
void platform_critical_init(void)
{
critical_mutex_id = osMutexCreate(osMutex(critical));
critical_mutex_id = osMutexNew(&critical_mutex_attr);
MBED_ASSERT(critical_mutex_id);
}
void platform_enter_critical(void)
{
osMutexWait(critical_mutex_id, osWaitForever);
osMutexAcquire(critical_mutex_id, osWaitForever);
sys_irq_disable_counter++;
}

View File

@ -4,24 +4,27 @@
// Include before mbed.h to properly get UINT*_C()
#include "ns_types.h"
#include "cmsis_os.h"
#include "mbed.h"
#include "cmsis_os2.h"
#include "rtx_os.h"
#include "platform/arm_hal_timer.h"
#include "platform/arm_hal_interrupt.h"
#include <mbed_assert.h>
static osThreadId timer_thread_id;
static osThreadId_t timer_thread_id;
static uint64_t timer_thread_stk[2048];
static osRtxThread_t timer_thread_tcb;
static Timer timer;
static Timeout timeout;
static uint32_t due;
static void (*arm_hal_callback)(void);
static void timer_thread(const void *)
static void timer_thread(void *arg)
{
(void)arg;
for (;;) {
osSignalWait(1, osWaitForever);
osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever);
// !!! We don't do our own enter/exit critical - we rely on callback
// doing it (ns_timer_interrupt_handler does)
//platform_enter_critical();
@ -33,8 +36,14 @@ static void timer_thread(const void *)
// Called once at boot
void platform_timer_enable(void)
{
static osThreadDef(timer_thread, osPriorityRealtime, /*1,*/ 2*1024);
timer_thread_id = osThreadCreate(osThread(timer_thread), NULL);
static osThreadAttr_t timer_thread_attr = {0};
timer_thread_attr.stack_mem = &timer_thread_stk[0];
timer_thread_attr.cb_mem = &timer_thread_tcb;
timer_thread_attr.stack_size = sizeof(timer_thread_stk);
timer_thread_attr.cb_size = sizeof(timer_thread_tcb);
timer_thread_attr.priority = osPriorityRealtime;
timer_thread_id = osThreadNew(timer_thread, NULL, &timer_thread_attr);
MBED_ASSERT(timer_thread_id != NULL);
timer.start();
}
@ -53,8 +62,7 @@ void platform_timer_set_cb(void (*new_fp)(void))
static void timer_callback(void)
{
due = 0;
osSignalSet(timer_thread_id, 1);
//callback();
osThreadFlagsSet(timer_thread_id, 1);
}
// This is called from inside platform_enter_critical - IRQs can't happen

View File

@ -2,8 +2,10 @@
* Copyright (c) 2016 ARM Limited, All Rights Reserved
*/
#include <mbed_assert.h>
#include "cmsis.h"
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_rtos_storage.h"
#include "ns_trace.h"
#include "eventOS_scheduler.h"
@ -12,21 +14,32 @@
#define TRACE_GROUP "evlp"
static void event_loop_thread(const void *arg);
static void event_loop_thread(void *arg);
// 1K should be enough - it's what the SAM4E port uses...
// What happened to the instances parameter?
static osThreadDef(event_loop_thread, osPriorityNormal, /*1,*/ MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_THREAD_STACK_SIZE);
static osMutexDef(event);
static osThreadId event_thread_id;
static osMutexId event_mutex_id;
static osThreadId event_mutex_owner_id = NULL;
static uint64_t event_thread_stk[MBED_CONF_NANOSTACK_HAL_EVENT_LOOP_THREAD_STACK_SIZE/8];
static mbed_rtos_storage_thread_t event_thread_tcb;
static const osThreadAttr_t event_thread_attr = {
.priority = osPriorityNormal,
.stack_mem = &event_thread_stk[0],
.stack_size = sizeof event_thread_stk,
.cb_mem = &event_thread_tcb,
.cb_size = sizeof event_thread_tcb,
};
static osThreadId_t event_thread_id;
static mbed_rtos_storage_mutex_t event_mutex;
static const osMutexAttr_t event_mutex_attr = {
.name = "event_mutex",
.attr_bits = osMutexRecursive,
.cb_mem = &event_mutex,
.cb_size = sizeof event_mutex,
};
static osMutexId_t event_mutex_id;
static osThreadId_t event_mutex_owner_id = NULL;
static uint32_t owner_count = 0;
void eventOS_scheduler_mutex_wait(void)
{
osMutexWait(event_mutex_id, osWaitForever);
osMutexAcquire(event_mutex_id, osWaitForever);
if (0 == owner_count) {
event_mutex_owner_id = osThreadGetId();
}
@ -52,7 +65,7 @@ void eventOS_scheduler_signal(void)
// XXX why does signal set lock if called with irqs disabled?
//__enable_irq();
//tr_debug("signal %p", (void*)event_thread_id);
osSignalSet(event_thread_id, 1);
osThreadFlagsSet(event_thread_id, 1);
//tr_debug("signalled %p", (void*)event_thread_id);
}
@ -60,29 +73,26 @@ void eventOS_scheduler_idle(void)
{
//tr_debug("idle");
eventOS_scheduler_mutex_release();
osSignalWait(1, osWaitForever);
osThreadFlagsWait(1, 0, osWaitForever);
eventOS_scheduler_mutex_wait();
}
static void event_loop_thread(const void *arg)
static void event_loop_thread(void *arg)
{
//tr_debug("event_loop_thread create");
osSignalWait(2, osWaitForever);
(void)arg;
eventOS_scheduler_mutex_wait();
tr_debug("event_loop_thread");
// Run does not return - it calls eventOS_scheduler_idle when it's, er, idle
eventOS_scheduler_run();
eventOS_scheduler_run(); //Does not return
}
void ns_event_loop_thread_create(void)
{
event_mutex_id = osMutexCreate(osMutex(event));
event_thread_id = osThreadCreate(osThread(event_loop_thread), NULL);
event_mutex_id = osMutexNew(&event_mutex_attr);
MBED_ASSERT(event_mutex_id != NULL);
event_thread_id = osThreadNew(event_loop_thread, NULL, &event_thread_attr);
MBED_ASSERT(event_thread_id != NULL);
}
void ns_event_loop_thread_start(void)
{
osSignalSet(event_thread_id, 2);
}

View File

@ -532,8 +532,8 @@ static err_t k64f_low_level_output(struct netif *netif, struct pbuf *p)
}
/* Check if a descriptor is available for the transfer. */
int32_t count = osSemaphoreWait(k64f_enet->xTXDCountSem.id, 0);
if (count < 1)
osStatus_t stat = osSemaphoreAcquire(k64f_enet->xTXDCountSem.id, 0);
if (stat != osOK)
return ERR_BUF;
/* Get exclusive access */
@ -697,11 +697,10 @@ err_t eth_arch_enetif_init(struct netif *netif)
netif->linkoutput = k64f_low_level_output;
/* CMSIS-RTOS, start tasks */
#ifdef CMSIS_OS_RTX
memset(k64f_enetdata.xTXDCountSem.data, 0, sizeof(k64f_enetdata.xTXDCountSem.data));
k64f_enetdata.xTXDCountSem.def.semaphore = k64f_enetdata.xTXDCountSem.data;
#endif
k64f_enetdata.xTXDCountSem.id = osSemaphoreCreate(&k64f_enetdata.xTXDCountSem.def, ENET_TX_RING_LEN);
memset(&k64f_enetdata.xTXDCountSem.data, 0, sizeof(k64f_enetdata.xTXDCountSem.data));
k64f_enetdata.xTXDCountSem.attr.cb_mem = &k64f_enetdata.xTXDCountSem.data;
k64f_enetdata.xTXDCountSem.attr.cb_size = sizeof(k64f_enetdata.xTXDCountSem.data);
k64f_enetdata.xTXDCountSem.id = osSemaphoreNew(ENET_TX_RING_LEN, ENET_TX_RING_LEN, &k64f_enetdata.xTXDCountSem.attr);
LWIP_ASSERT("xTXDCountSem creation error", (k64f_enetdata.xTXDCountSem.id != NULL));

View File

@ -70,6 +70,7 @@
* the same. */
#define RX_PRIORITY (osPriorityNormal)
#define TX_PRIORITY (osPriorityNormal)
#define PHY_PRIORITY (osPriorityNormal)
/** \brief Debug output formatter lock define
*
@ -603,7 +604,7 @@ static err_t lpc_low_level_output(struct netif *netif, struct pbuf *p)
/* THIS WILL BLOCK UNTIL THERE ARE ENOUGH DESCRIPTORS AVAILABLE */
while (dn > lpc_tx_ready(netif))
#if NO_SYS == 0
osSemaphoreWait(lpc_enetif->xTXDCountSem.id, osWaitForever);
osSemaphoreAcquire(lpc_enetif->xTXDCountSem.id, osWaitForever);
#else
osDelay(1);
#endif
@ -685,7 +686,7 @@ void LPC17xxEthernetHandler(void)
if (ints & RXINTGROUP) {
/* RX group interrupt(s): Give signal to wakeup RX receive task.*/
osSignalSet(lpc_enetdata.RxThread->id, RX_SIGNAL);
osThreadFlagsSet(lpc_enetdata.RxThread->id, RX_SIGNAL);
}
if (ints & TXINTGROUP) {
@ -711,7 +712,7 @@ static void packet_rx(void* pvParameters) {
while (1) {
/* Wait for receive task to wakeup */
osSignalWait(RX_SIGNAL, osWaitForever);
osThreadFlagsWait(RX_SIGNAL, 0, osWaitForever);
/* Process packets until all empty */
while (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex)
@ -942,10 +943,13 @@ err_t lpc_etharp_output_ipv6(struct netif *netif, struct pbuf *q,
#if NO_SYS == 0
/* periodic PHY status update */
void phy_update(void const *nif) {
lpc_phy_sts_sm((struct netif*)nif);
void phy_update(void *nif) {
while (true) {
lpc_phy_sts_sm((struct netif*)nif);
osDelay(250);
}
}
osTimerDef(phy_update, phy_update);
#endif
/**
@ -1017,11 +1021,10 @@ err_t eth_arch_enetif_init(struct netif *netif)
/* CMSIS-RTOS, start tasks */
#if NO_SYS == 0
#ifdef CMSIS_OS_RTX
memset(lpc_enetdata.xTXDCountSem.data, 0, sizeof(lpc_enetdata.xTXDCountSem.data));
lpc_enetdata.xTXDCountSem.def.semaphore = lpc_enetdata.xTXDCountSem.data;
#endif
lpc_enetdata.xTXDCountSem.id = osSemaphoreCreate(&lpc_enetdata.xTXDCountSem.def, LPC_NUM_BUFF_TXDESCS);
memset(&lpc_enetdata.xTXDCountSem.data, 0, sizeof(lpc_enetdata.xTXDCountSem.data));
lpc_enetdata.xTXDCountSem.attr.cb_mem = &lpc_enetdata.xTXDCountSem.data;
lpc_enetdata.xTXDCountSem.attr.cb_size = sizeof(lpc_enetdata.xTXDCountSem.data);
lpc_enetdata.xTXDCountSem.id = osSemaphoreNew(LPC_NUM_BUFF_TXDESCS, LPC_NUM_BUFF_TXDESCS, &lpc_enetdata.xTXDCountSem.attr);
LWIP_ASSERT("xTXDCountSem creation error", (lpc_enetdata.xTXDCountSem.id != NULL));
err = sys_mutex_new(&lpc_enetdata.TXLockMutex);
@ -1037,8 +1040,7 @@ err_t eth_arch_enetif_init(struct netif *netif)
sys_thread_new("txclean_thread", packet_tx, netif->state, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY);
/* periodic PHY status update */
osTimerId phy_timer = osTimerCreate(osTimer(phy_update), osTimerPeriodic, (void *)netif);
osTimerStart(phy_timer, 250);
sys_thread_new("phy_thread", phy_update, netif, DEFAULT_THREAD_STACKSIZE, TX_PRIORITY);
#endif
return ERR_OK;

View File

@ -4,7 +4,7 @@
#include "lwip/tcpip.h"
#include "lwip/ethip6.h"
#include <string.h>
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_interface.h"
#define RECV_TASK_PRI (osPriorityHigh)

View File

@ -21,6 +21,7 @@
#include "mbed_error.h"
#include "mbed_interface.h"
#include "us_ticker_api.h"
#include "mbed_rtos_storage.h"
/* lwIP includes. */
#include "lwip/opt.h"
@ -124,14 +125,21 @@ u32_t sys_now(void) {
err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) {
if (queue_sz > MB_SIZE)
error("sys_mbox_new size error\n");
#ifdef CMSIS_OS_RTX
mbox->post_idx = 0;
mbox->fetch_idx = 0;
memset(mbox->queue, 0, sizeof(mbox->queue));
mbox->def.pool = mbox->queue;
mbox->def.queue_sz = queue_sz;
#endif
mbox->id = osMessageCreate(&mbox->def, NULL);
return (mbox->id == NULL) ? (ERR_MEM) : (ERR_OK);
memset(&mbox->data, 0, sizeof(mbox->data));
mbox->attr.cb_mem = &mbox->data;
mbox->attr.cb_size = sizeof(mbox->data);
mbox->id = osEventFlagsNew(&mbox->attr);
if (mbox->id == NULL)
error("sys_mbox_new create error\n");
osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT);
return ERR_OK;
}
/*---------------------------------------------------------------------------*
@ -145,8 +153,7 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int queue_sz) {
* sys_mbox_t *mbox -- Handle of mailbox
*---------------------------------------------------------------------------*/
void sys_mbox_free(sys_mbox_t *mbox) {
osEvent event = osMessageGet(mbox->id, 0);
if (event.status == osEventMessage)
if (mbox->post_idx != mbox->fetch_idx)
error("sys_mbox_free error\n");
}
@ -160,8 +167,19 @@ void sys_mbox_free(sys_mbox_t *mbox) {
* void *msg -- Pointer to data to post
*---------------------------------------------------------------------------*/
void sys_mbox_post(sys_mbox_t *mbox, void *msg) {
if (osMessagePut(mbox->id, (uint32_t)msg, osWaitForever) != osOK)
error("sys_mbox_post error\n");
osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT,
osFlagsWaitAny | osFlagsNoClear, osWaitForever);
int state = osKernelLock();
mbox->queue[mbox->post_idx % MB_SIZE] = msg;
mbox->post_idx += 1;
osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT);
if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1)
osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT);
osKernelRestoreLock(state);
}
/*---------------------------------------------------------------------------*
@ -178,8 +196,22 @@ void sys_mbox_post(sys_mbox_t *mbox, void *msg) {
* if not.
*---------------------------------------------------------------------------*/
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) {
osStatus status = osMessagePut(mbox->id, (uint32_t)msg, 0);
return (status == osOK) ? (ERR_OK) : (ERR_MEM);
uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_POST_EVENT,
osFlagsWaitAny | osFlagsNoClear, 0);
if ((flags & osFlagsError) || !(flags & SYS_MBOX_POST_EVENT))
return ERR_MEM;
int state = osKernelLock();
mbox->queue[mbox->post_idx % MB_SIZE] = msg;
mbox->post_idx += 1;
osEventFlagsSet(mbox->id, SYS_MBOX_FETCH_EVENT);
if (mbox->post_idx - mbox->fetch_idx == MB_SIZE-1)
osEventFlagsClear(mbox->id, SYS_MBOX_POST_EVENT);
osKernelRestoreLock(state);
return ERR_OK;
}
/*---------------------------------------------------------------------------*
@ -208,14 +240,23 @@ err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) {
* of milliseconds until received.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) {
u32_t start = us_ticker_read();
osEvent event = osMessageGet(mbox->id, (timeout != 0)?(timeout):(osWaitForever));
if (event.status != osEventMessage)
uint32_t start = us_ticker_read();
uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT,
osFlagsWaitAny | osFlagsNoClear, (timeout ? timeout : osWaitForever));
if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT))
return SYS_ARCH_TIMEOUT;
*msg = (void *)event.value.v;
int state = osKernelLock();
if (msg)
*msg = mbox->queue[mbox->fetch_idx % MB_SIZE];
mbox->fetch_idx += 1;
osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT);
if (mbox->post_idx == mbox->fetch_idx)
osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT);
osKernelRestoreLock(state);
return (us_ticker_read() - start) / 1000;
}
@ -234,12 +275,22 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) {
* return ERR_OK.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) {
osEvent event = osMessageGet(mbox->id, 0);
if (event.status != osEventMessage)
uint32_t flags = osEventFlagsWait(mbox->id, SYS_MBOX_FETCH_EVENT,
osFlagsWaitAny | osFlagsNoClear, 0);
if ((flags & osFlagsError) || !(flags & SYS_MBOX_FETCH_EVENT))
return SYS_MBOX_EMPTY;
*msg = (void *)event.value.v;
int state = osKernelLock();
if (msg)
*msg = mbox->queue[mbox->fetch_idx % MB_SIZE];
mbox->fetch_idx += 1;
osEventFlagsSet(mbox->id, SYS_MBOX_POST_EVENT);
if (mbox->post_idx == mbox->fetch_idx)
osEventFlagsClear(mbox->id, SYS_MBOX_FETCH_EVENT);
osKernelRestoreLock(state);
return ERR_OK;
}
@ -257,11 +308,10 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) {
* err_t -- ERR_OK if semaphore created
*---------------------------------------------------------------------------*/
err_t sys_sem_new(sys_sem_t *sem, u8_t count) {
#ifdef CMSIS_OS_RTX
memset(sem->data, 0, sizeof(uint32_t)*2);
sem->def.semaphore = sem->data;
#endif
sem->id = osSemaphoreCreate(&sem->def, count);
memset(&sem->data, 0, sizeof(sem->data));
sem->attr.cb_mem = &sem->data;
sem->attr.cb_size = sizeof(sem->data);
sem->id = osSemaphoreNew(UINT16_MAX, count, &sem->attr);
if (sem->id == NULL)
error("sys_sem_new create error\n");
@ -294,7 +344,7 @@ err_t sys_sem_new(sys_sem_t *sem, u8_t count) {
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) {
u32_t start = us_ticker_read();
if (osSemaphoreWait(sem->id, (timeout != 0)?(timeout):(osWaitForever)) < 1)
if (osSemaphoreAcquire(sem->id, (timeout != 0)?(timeout):(osWaitForever)) != osOK)
return SYS_ARCH_TIMEOUT;
return (us_ticker_read() - start) / 1000;
@ -327,15 +377,10 @@ void sys_sem_free(sys_sem_t *sem) {}
* @param mutex pointer to the mutex to create
* @return a new mutex */
err_t sys_mutex_new(sys_mutex_t *mutex) {
#ifdef CMSIS_OS_RTX
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
memset(mutex->data, 0, sizeof(int32_t)*4);
#else
memset(mutex->data, 0, sizeof(int32_t)*3);
#endif
mutex->def.mutex = mutex->data;
#endif
mutex->id = osMutexCreate(&mutex->def);
memset(&mutex->data, 0, sizeof(mutex->data));
mutex->attr.cb_mem = &mutex->data;
mutex->attr.cb_size = sizeof(mutex->data);
mutex->id = osMutexNew(&mutex->attr);
if (mutex->id == NULL)
return ERR_MEM;
@ -345,7 +390,7 @@ err_t sys_mutex_new(sys_mutex_t *mutex) {
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock(sys_mutex_t *mutex) {
if (osMutexWait(mutex->id, osWaitForever) != osOK)
if (osMutexAcquire(mutex->id, osWaitForever) != osOK)
error("sys_mutex_lock error\n");
}
@ -366,12 +411,15 @@ void sys_mutex_free(sys_mutex_t *mutex) {}
* Description:
* Initialize sys arch
*---------------------------------------------------------------------------*/
osMutexId lwip_sys_mutex;
osMutexDef(lwip_sys_mutex);
osMutexId_t lwip_sys_mutex;
osMutexAttr_t lwip_sys_mutex_attr;
mbed_rtos_storage_mutex_t lwip_sys_mutex_data;
void sys_init(void) {
us_ticker_read(); // Init sys tick
lwip_sys_mutex = osMutexCreate(osMutex(lwip_sys_mutex));
lwip_sys_mutex_attr.cb_mem = &lwip_sys_mutex_data;
lwip_sys_mutex_attr.cb_size = sizeof(lwip_sys_mutex_data);
lwip_sys_mutex = osMutexNew(&lwip_sys_mutex_attr);
if (lwip_sys_mutex == NULL)
error("sys_init error\n");
}
@ -408,7 +456,7 @@ u32_t sys_jiffies(void) {
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
sys_prot_t sys_arch_protect(void) {
if (osMutexWait(lwip_sys_mutex, osWaitForever) != osOK)
if (osMutexAcquire(lwip_sys_mutex, osWaitForever) != osOK)
error("sys_arch_protect error\n");
return (sys_prot_t) 1;
}
@ -469,16 +517,16 @@ sys_thread_t sys_thread_new(const char *pcName,
sys_thread_t t = (sys_thread_t)&thread_pool[thread_pool_index];
thread_pool_index++;
#ifdef CMSIS_OS_RTX
t->def.pthread = (os_pthread)thread;
t->def.tpriority = (osPriority)priority;
t->def.stacksize = stacksize;
t->def.stack_pointer = (uint32_t*)malloc(stacksize);
if (t->def.stack_pointer == NULL) {
t->attr.name = pcName;
t->attr.priority = (osPriority_t)priority;
t->attr.cb_size = sizeof(t->data);
t->attr.cb_mem = &t->data;
t->attr.stack_size = stacksize;
t->attr.stack_mem = malloc(stacksize);
if (t->attr.stack_mem == NULL) {
error("Error allocating the stack memory");
}
#endif
t->id = osThreadCreate(&t->def, arg);
t->id = osThreadNew((osThreadFunc_t)thread, arg, &t->attr);
if (t->id == NULL)
error("sys_thread_new create error\n");

View File

@ -19,19 +19,18 @@
#define __ARCH_SYS_ARCH_H__
#include "lwip/opt.h"
#include "mbed_rtos_storage.h"
extern u8_t lwip_ram_heap[];
#if NO_SYS == 0
#include "cmsis_os.h"
#include "cmsis_os2.h"
// === SEMAPHORE ===
typedef struct {
osSemaphoreId id;
osSemaphoreDef_t def;
#ifdef CMSIS_OS_RTX
uint32_t data[2];
#endif
osSemaphoreId_t id;
osSemaphoreAttr_t attr;
mbed_rtos_storage_semaphore_t data;
} sys_sem_t;
#define sys_sem_valid(x) (((*x).id == NULL) ? 0 : 1)
@ -39,31 +38,30 @@ typedef struct {
// === MUTEX ===
typedef struct {
osMutexId id;
osMutexDef_t def;
#ifdef CMSIS_OS_RTX
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
int32_t data[4];
#else
int32_t data[3];
#endif
#endif
osMutexId_t id;
osMutexAttr_t attr;
mbed_rtos_storage_mutex_t data;
} sys_mutex_t;
// === MAIL BOX ===
#define MB_SIZE 8
typedef struct {
osMessageQId id;
osMessageQDef_t def;
#ifdef CMSIS_OS_RTX
uint32_t queue[4+MB_SIZE]; /* The +4 is required for RTX OS_MCB overhead. */
#endif
osEventFlagsId_t id;
osEventFlagsAttr_t attr;
mbed_rtos_storage_event_flags_t data;
uint8_t post_idx;
uint8_t fetch_idx;
void* queue[MB_SIZE];
} sys_mbox_t;
#define SYS_MBOX_FETCH_EVENT 0x1
#define SYS_MBOX_POST_EVENT 0x2
#define SYS_MBOX_NULL ((uint32_t) NULL)
#define sys_mbox_valid(x) (((*x).id == NULL) ? 0 : 1 )
#define sys_mbox_set_invalid(x) ( (*x).id = NULL )
#define sys_mbox_valid(x) (((*x).id == NULL) ? 0 : 1)
#define sys_mbox_set_invalid(x) ( (*x).id = NULL)
#if ((DEFAULT_RAW_RECVMBOX_SIZE) > (MB_SIZE)) || \
((DEFAULT_UDP_RECVMBOX_SIZE) > (MB_SIZE)) || \
@ -75,13 +73,14 @@ typedef struct {
// === THREAD ===
typedef struct {
osThreadId id;
osThreadDef_t def;
osThreadId_t id;
osThreadAttr_t attr;
mbed_rtos_storage_thread_t data;
} sys_thread_data_t;
typedef sys_thread_data_t* sys_thread_t;
#define SYS_THREAD_POOL_N 6
#define SYS_DEFAULT_THREAD_STACK_DEPTH DEFAULT_STACK_SIZE
#define SYS_DEFAULT_THREAD_STACK_DEPTH OS_STACK_SIZE
// === PROTECTION ===
typedef int sys_prot_t;

View File

@ -68,7 +68,7 @@
//#define LWIP_DEBUG
#if NO_SYS == 0
#include "cmsis_os.h"
#include "cmsis_os2.h"
#define SYS_LIGHTWEIGHT_PROT 1

View File

@ -18,7 +18,7 @@
#include "mbed.h"
#include "rtos.h"
#include "mbed_stats.h"
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "greentea-client/test_env.h"
#include "greentea-client/greentea_metrics.h"
#include "SingletonPtr.h"
@ -28,7 +28,6 @@
typedef struct {
uint32_t entry;
uint32_t arg;
uint32_t stack_size;
uint32_t max_stack;
} thread_info_t;
@ -43,8 +42,8 @@ static SingletonPtr<CircularBuffer<thread_info_t, THREAD_BUF_COUNT> > queue;
static void send_heap_info(void);
#if defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED
static void send_stack_info(void);
static void on_thread_terminate(osThreadId id);
static void enqeue_thread_info(osThreadId id);
static void on_thread_terminate(osThreadId_t id);
static void enqeue_thread_info(osThreadId_t id);
static void deque_and_print_thread_info(void);
// sprintf uses a lot of stack so use these instead
@ -86,22 +85,21 @@ MBED_UNUSED static void send_stack_info()
}
// Print info for all other threads
osThreadEnumId enum_id = _osThreadsEnumStart();
while (true) {
osThreadId thread_id = _osThreadEnumNext(enum_id);
if (NULL == thread_id) {
// End of enumeration
break;
}
enqeue_thread_info(thread_id);
uint32_t thread_n = osThreadGetCount();
osThreadId_t *threads = new osThreadId_t[thread_n];
thread_n = osThreadEnumerate(threads, thread_n);
for(size_t i = 0; i < thread_n; i++) {
enqeue_thread_info(threads[i]);
deque_and_print_thread_info();
}
_osThreadEnumFree(enum_id);
delete[] threads;
mutex->unlock();
}
MBED_UNUSED static void on_thread_terminate(osThreadId id)
MBED_UNUSED static void on_thread_terminate(osThreadId_t id)
{
mutex->lock();
@ -116,30 +114,13 @@ MBED_UNUSED static void on_thread_terminate(osThreadId id)
mutex->unlock();
}
static void enqeue_thread_info(osThreadId id)
static void enqeue_thread_info(osThreadId_t id)
{
osEvent info;
thread_info_t thread_info = {};
info = _osThreadGetInfo(id, osThreadInfoEntry);
if (info.status != osOK) {
return;
}
thread_info.entry = (uint32_t)info.value.p;
info = _osThreadGetInfo(id, osThreadInfoArg);
if (info.status != osOK) {
return;
}
thread_info.arg = (uint32_t)info.value.p;
info = _osThreadGetInfo(id, osThreadInfoStackSize);
if (info.status != osOK) {
return;
}
thread_info.stack_size = (uint32_t)info.value.v;
info = _osThreadGetInfo(id, osThreadInfoStackMax);
if (info.status != osOK) {
return;
}
thread_info.max_stack = (uint32_t)info.value.v;
thread_info.entry = (uint32_t)id;
thread_info.stack_size = osThreadGetStackSize(id);
thread_info.max_stack = thread_info.stack_size - osThreadGetStackSpace(id);
queue->push(thread_info);
}
@ -151,8 +132,6 @@ static void deque_and_print_thread_info()
uint32_t pos = 0;
buf[pos++] = '\"';
pos += print_hex(buf + pos, thread_info.entry);
buf[pos++] = '-';
pos += print_hex(buf + pos, thread_info.arg);
buf[pos++] = '\"';
buf[pos++] = ',';
pos += print_dec(buf + pos, thread_info.max_stack);

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h"
#include "ns_types.h"
#include <string.h>
#include "common_functions.h"
@ -29,24 +29,12 @@ extern "C" {
#include "TARGET_NCS36510/rfAna.h"
}
#include "cmsis_os.h"
#ifdef MBED_CONF_RTOS_PRESENT
#include "cmsis.h"
#include "cmsis_os.h"
#define RF_THREAD_STACK_SIZE 1024
#define SIGNAL_COUNT_RADIO 1
static void rf_thread_loop(const void *arg);
static osThreadDef(rf_thread_loop, osPriorityRealtime, /*1,*/ RF_THREAD_STACK_SIZE);
static osThreadId rf_thread_id;
#endif
static void rf_thread_loop();
Thread rf_thread(osPriorityRealtime, RF_THREAD_STACK_SIZE);
#define PHY_MTU_SIZE 127
#define CRC_LENGTH 0
@ -166,16 +154,13 @@ static phy_device_driver_s device_driver = {
NULL
};
#ifdef MBED_CONF_RTOS_PRESENT
static void rf_thread_loop(const void *arg)
static void rf_thread_loop()
{
for (;;) {
osEvent event = osSignalWait(0, osWaitForever);
if (event.status != osEventSignal) {
continue;
}
int32_t event = rf_thread.signal_wait(0);
platform_enter_critical();
if (event.value.signals & SIGNAL_COUNT_RADIO) {
if (event & SIGNAL_COUNT_RADIO) {
handle_IRQ_events();
}
platform_exit_critical();
@ -183,7 +168,6 @@ static void rf_thread_loop(const void *arg)
NVIC_EnableIRQ(MacHw_IRQn);
}
}
#endif
static int8_t rf_device_register(void)
{
@ -467,9 +451,8 @@ static void rf_mac_hw_init(void) {
for (lutIndex=0;lutIndex<96;lutIndex++) {
*(pMatchReg + lutIndex) = 0xFF;
}
#ifdef MBED_CONF_RTOS_PRESENT
rf_thread_id = osThreadCreate(osThread(rf_thread_loop), NULL);
#endif
osStatus_t status = rf_thread.start(mbed::callback(rf_thread_loop));
MBED_ASSERT(status == osOK);
/** Clear and enable MAC IRQ at task level, when scheduler is on. */
NVIC_ClearPendingIRQ(MacHw_IRQn);
@ -819,12 +802,8 @@ static void rf_mac_tx_interrupt(void)
*/
extern "C" void fIrqMacHwHandler(void)
{
#ifdef MBED_CONF_RTOS_PRESENT
NVIC_DisableIRQ(MacHw_IRQn);
osSignalSet(rf_thread_id, SIGNAL_COUNT_RADIO);
#else
handle_IRQ_events();
#endif
rf_thread.signal_set(SIGNAL_COUNT_RADIO);
}
static void handle_IRQ_events(void)

View File

@ -188,14 +188,8 @@ nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size)
void TCPSocket::event()
{
int32_t wcount = _write_sem.wait(0);
if (wcount <= 1) {
_write_sem.release();
}
int32_t rcount = _read_sem.wait(0);
if (rcount <= 1) {
_read_sem.release();
}
_write_sem.release();
_read_sem.release();
_pending += 1;
if (_callback && _pending == 1) {

View File

@ -123,14 +123,8 @@ nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer,
void UDPSocket::event()
{
int32_t wcount = _write_sem.wait(0);
if (wcount <= 1) {
_write_sem.release();
}
int32_t rcount = _read_sem.wait(0);
if (rcount <= 1) {
_read_sem.release();
}
_write_sem.release();
_read_sem.release();
_pending += 1;
if (_callback && _pending == 1) {

View File

@ -23,11 +23,11 @@
#include <new>
#include "platform/mbed_assert.h"
#ifdef MBED_CONF_RTOS_PRESENT
#include "cmsis_os.h"
#include "cmsis_os2.h"
#endif
#ifdef MBED_CONF_RTOS_PRESENT
extern osMutexId singleton_mutex_id;
extern osMutexId_t singleton_mutex_id;
#endif
/** Lock the singleton mutex
@ -39,7 +39,7 @@ extern osMutexId singleton_mutex_id;
inline static void singleton_lock(void)
{
#ifdef MBED_CONF_RTOS_PRESENT
osMutexWait(singleton_mutex_id, osWaitForever);
osMutexAcquire(singleton_mutex_id, osWaitForever);
#endif
}

View File

@ -36,7 +36,6 @@
#include <errno.h>
#include "platform/mbed_retarget.h"
#if defined(__ARMCC_VERSION)
# include <rt_sys.h>
# define PREFIX(x) _sys##x
@ -76,7 +75,6 @@ extern const char __stdout_name[] = "/stdout";
extern const char __stderr_name[] = "/stderr";
#endif
// Heap limits - only used if set
unsigned char *mbed_heap_start = 0;
uint32_t mbed_heap_size = 0;
@ -157,10 +155,6 @@ static inline int openmode_to_posix(int openmode) {
}
#endif
extern "C" WEAK void mbed_sdk_init(void);
extern "C" WEAK void mbed_sdk_init(void) {
}
#if MBED_CONF_FILESYSTEM_PRESENT
// Internally used file objects with managed memory on close
class ManagedFile : public File {
@ -198,11 +192,6 @@ extern "C" FILEHANDLE PREFIX(_open)(const char* name, int openmode) {
// Before version 5.03, we were using a patched version of microlib with proper names
// This is the workaround that the microlib author suggested us
static int n = 0;
static int mbed_sdk_inited = 0;
if (!mbed_sdk_inited) {
mbed_sdk_inited = 1;
mbed_sdk_init();
}
if (!std::strcmp(name, ":tt")) return n++;
#else
/* Use the posix convention that stdin,out,err are filehandles 0,1,2.
@ -684,79 +673,10 @@ extern "C" WEAK void __cxa_pure_virtual(void) {
#endif
#if defined(TOOLCHAIN_GCC)
#ifdef FEATURE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif/* FEATURE_UVISOR */
extern "C" WEAK void software_init_hook_rtos(void)
{
// Do nothing by default.
}
extern "C" void software_init_hook(void)
{
#ifdef FEATURE_UVISOR
int return_code;
return_code = uvisor_lib_init();
if (return_code) {
mbed_die();
}
#endif/* FEATURE_UVISOR */
mbed_sdk_init();
software_init_hook_rtos();
}
#endif
// ****************************************************************************
// mbed_main is a function that is called before main()
// mbed_sdk_init() is also a function that is called before main(), but unlike
// mbed_main(), it is not meant for user code, but for the SDK itself to perform
// initializations before main() is called.
extern "C" WEAK void mbed_main(void);
extern "C" WEAK void mbed_main(void) {
}
#if defined(TOOLCHAIN_ARM)
extern "C" int $Super$$main(void);
extern "C" int $Sub$$main(void) {
mbed_main();
return $Super$$main();
}
extern "C" void _platform_post_stackheap_init (void) {
mbed_sdk_init();
}
#elif defined(TOOLCHAIN_GCC)
extern "C" int __real_main(void);
extern "C" int __wrap_main(void) {
mbed_main();
return __real_main();
}
#elif defined(TOOLCHAIN_IAR)
// IAR doesn't have the $Super/$Sub mechanism of armcc, nor something equivalent
// to ld's --wrap. It does have a --redirect, but that doesn't help, since redirecting
// 'main' to another symbol looses the original 'main' symbol. However, its startup
// code will call a function to setup argc and argv (__iar_argc_argv) if it is defined.
// Since mbed doesn't use argc/argv, we use this function to call our mbed_main.
extern "C" void __iar_argc_argv() {
mbed_main();
}
#endif
// Provide implementation of _sbrk (low-level dynamic memory allocation
// routine) for GCC_ARM which compares new heap pointer with MSP instead of
// SP. This make it compatible with RTX RTOS thread stacks.
#if defined(TOOLCHAIN_GCC_ARM) || defined(TOOLCHAIN_GCC_CR)
// Linker defined symbol used by _sbrk to indicate where heap should start.
extern "C" int __end__;
#if defined(TARGET_CORTEX_A)
extern "C" uint32_t __HeapLimit;
@ -777,6 +697,8 @@ extern "C" caddr_t _sbrk(int incr) {
return (caddr_t) __wrap__sbrk(incr);
}
#else
// Linker defined symbol used by _sbrk to indicate where heap should start.
extern "C" uint32_t __end__;
extern "C" caddr_t _sbrk(int incr) {
static unsigned char* heap = (unsigned char*)&__end__;
unsigned char* prev_heap = heap;
@ -897,7 +819,7 @@ namespace mbed {
void mbed_set_unbuffered_stream(FILE *_file) {
#if defined (__ICCARM__)
char buf[2];
std::setvbuf(_file,buf,_IONBF,NULL);
std::setvbuf(_file,buf,_IONBF,NULL);
#else
setbuf(_file, NULL);
#endif
@ -911,11 +833,11 @@ int mbed_getc(FILE *_file){
_file->_Mode = (unsigned short)(_file->_Mode & ~ 0x1000);/* Unset read mode */
_file->_Rend = _file->_Wend;
_file->_Next = _file->_Wend;
}
}
return res;
#else
#else
return std::fgetc(_file);
#endif
#endif
}
char* mbed_gets(char*s, int size, FILE *_file){
@ -928,7 +850,7 @@ char* mbed_gets(char*s, int size, FILE *_file){
_file->_Next = _file->_Wend;
}
return str;
#else
#else
return std::fgets(s,size,_file);
#endif
}

89
platform/mbed_sdk_boot.c Normal file
View File

@ -0,0 +1,89 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* 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.
*/
#include "mbed_toolchain.h"
#include <stdlib.h>
#include <stdint.h>
/* This startup is for mbed 2 baremetal. There is no config for RTOS for mbed 2,
* therefore we protect this file with MBED_CONF_RTOS_PRESENT
* Note: The new consolidated started for mbed OS is in rtos/mbed_boot code file.
*/
#if !defined(MBED_CONF_RTOS_PRESENT)
/* mbed_main is a function that is called before main()
* mbed_sdk_init() is also a function that is called before main(), but unlike
* mbed_main(), it is not meant for user code, but for the SDK itself to perform
* initializations before main() is called.
*/
MBED_WEAK void mbed_main(void)
{
}
/* This function can be implemented by the target to perform higher level target initialization
*/
MBED_WEAK void mbed_sdk_init(void)
{
}
MBED_WEAK void software_init_hook_rtos()
{
// Nothing by default
}
/* Toolchain specific main code */
#if defined (__CC_ARM)
int $Super$$main(void);
int $Sub$$main(void)
{
mbed_main();
return $Super$$main();
}
void _platform_post_stackheap_init(void)
{
mbed_sdk_init();
}
#elif defined (__GNUC__)
extern int __real_main(void);
__attribute__((naked)) void software_init_hook(void)
{
mbed_sdk_init();
software_init_hook_rtos();
}
int __wrap_main(void)
{
mbed_main();
return __real_main();
}
#elif defined (__ICCARM__)
// cmsis.S file implements the mbed SDK boot for IAR
#endif
#endif

View File

@ -1,8 +1,10 @@
#include "mbed_stats.h"
#include <string.h>
#include <stdlib.h>
#include "mbed_assert.h"
#if MBED_CONF_RTOS_PRESENT
#include "cmsis_os.h"
#include "cmsis_os2.h"
#endif
// note: mbed_stats_heap_get defined in mbed_alloc_wrappers.cpp
@ -12,24 +14,25 @@ void mbed_stats_stack_get(mbed_stats_stack_t *stats)
memset(stats, 0, sizeof(mbed_stats_stack_t));
#if MBED_STACK_STATS_ENABLED && MBED_CONF_RTOS_PRESENT
osThreadEnumId enumid = _osThreadsEnumStart();
osThreadId threadid;
uint32_t thread_n = osThreadGetCount();
unsigned i;
osThreadId_t *threads;
while ((threadid = _osThreadEnumNext(enumid))) {
osEvent e;
threads = malloc(sizeof(osThreadId_t) * thread_n);
MBED_ASSERT(threads != NULL);
e = _osThreadGetInfo(threadid, osThreadInfoStackMax);
if (e.status == osOK) {
stats->max_size += (uint32_t)e.value.p;
}
osKernelLock();
thread_n = osThreadEnumerate(threads, thread_n);
e = _osThreadGetInfo(threadid, osThreadInfoStackSize);
if (e.status == osOK) {
stats->reserved_size += (uint32_t)e.value.p;
}
stats->stack_cnt += 1;
for(i = 0; i < thread_n; i++) {
uint32_t stack_size = osThreadGetStackSize(threads[i]);
stats->max_size += stack_size - osThreadGetStackSpace(threads[i]);
stats->reserved_size += stack_size;
stats->stack_cnt++;
}
osKernelUnlock();
free(threads);
#endif
}
@ -39,26 +42,24 @@ size_t mbed_stats_stack_get_each(mbed_stats_stack_t *stats, size_t count)
size_t i = 0;
#if MBED_STACK_STATS_ENABLED && MBED_CONF_RTOS_PRESENT
osThreadEnumId enumid = _osThreadsEnumStart();
osThreadId threadid;
osThreadId_t *threads;
while ((threadid = _osThreadEnumNext(enumid)) && i < count) {
osEvent e;
threads = malloc(sizeof(osThreadId_t) * count);
MBED_ASSERT(threads != NULL);
e = _osThreadGetInfo(threadid, osThreadInfoStackMax);
if (e.status == osOK) {
stats[i].max_size = (uint32_t)e.value.p;
}
osKernelLock();
count = osThreadEnumerate(threads, count);
e = _osThreadGetInfo(threadid, osThreadInfoStackSize);
if (e.status == osOK) {
stats[i].reserved_size = (uint32_t)e.value.p;
}
stats[i].thread_id = (uint32_t)threadid;
for(i = 0; i < count; i++) {
uint32_t stack_size = osThreadGetStackSize(threads[i]);
stats[i].max_size = stack_size - osThreadGetStackSpace(threads[i]);
stats[i].reserved_size = stack_size;
stats[i].thread_id = (uint32_t)threads[i];
stats[i].stack_cnt = 1;
i += 1;
}
osKernelUnlock();
free(threads);
#endif
return i;

View File

@ -1,5 +1,5 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
* Copyright (c) 2006-2017 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@ -25,7 +25,13 @@
#include <stdint.h>
#include <string.h>
#include "cmsis_os.h"
#include "Queue.h"
#include "MemoryPool.h"
#include "cmsis_os2.h"
#include "rtx_lib.h"
#include "mbed_rtos1_types.h"
using namespace rtos;
namespace rtos {
/** \addtogroup rtos */
@ -35,32 +41,23 @@ namespace rtos {
A mail is a memory block that is send to a thread or interrupt service routine.
@tparam T data type of a single message element.
@tparam queue_sz maximum number of messages in queue.
@note
Memory considerations: The mail data store and control structures will be created on current thread's stack,
both for the mbed OS and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
*/
template<typename T, uint32_t queue_sz>
class Mail {
public:
/** Create and Initialise Mail queue. */
Mail() {
#ifdef CMSIS_OS_RTX
memset(_mail_q, 0, sizeof(_mail_q));
_mail_p[0] = _mail_q;
memset(_mail_m, 0, sizeof(_mail_m));
_mail_p[1] = _mail_m;
_mail_def.pool = _mail_p;
_mail_def.queue_sz = queue_sz;
_mail_def.item_sz = sizeof(T);
#endif
_mail_id = osMailCreate(&_mail_def, NULL);
}
Mail() { };
/** Allocate a memory block of type T
@param millisec timeout value or 0 in case of no time-out. (default: 0).
@return pointer to memory block that can be filled with mail or NULL in case error.
*/
T* alloc(uint32_t millisec=0) {
return (T*)osMailAlloc(_mail_id, millisec);
return _pool.alloc();
}
/** Allocate a memory block of type T and set memory block to zero.
@ -68,7 +65,7 @@ public:
@return pointer to memory block that can be filled with mail or NULL in case error.
*/
T* calloc(uint32_t millisec=0) {
return (T*)osMailCAlloc(_mail_id, millisec);
return _pool.calloc();
}
/** Put a mail in the queue.
@ -76,7 +73,7 @@ public:
@return status code that indicates the execution status of the function.
*/
osStatus put(T *mptr) {
return osMailPut(_mail_id, (void*)mptr);
return _queue.put(mptr);
}
/** Get a mail from a queue.
@ -84,7 +81,11 @@ public:
@return event that contains mail information or error code.
*/
osEvent get(uint32_t millisec=osWaitForever) {
return osMailGet(_mail_id, millisec);
osEvent evt = _queue.get(millisec);
if (evt.status == osEventMessage) {
evt.status = osEventMail;
}
return evt;
}
/** Free a memory block from a mail.
@ -92,17 +93,12 @@ public:
@return status code that indicates the execution status of the function.
*/
osStatus free(T *mptr) {
return osMailFree(_mail_id, (void*)mptr);
return _pool.free(mptr);
}
private:
osMailQId _mail_id;
osMailQDef_t _mail_def;
#ifdef CMSIS_OS_RTX
uint32_t _mail_q[4+(queue_sz)];
uint32_t _mail_m[3+((sizeof(T)+3)/4)*(queue_sz)];
void *_mail_p[2];
#endif
Queue<T, queue_sz> _queue;
MemoryPool<T, queue_sz> _pool;
};
}

View File

@ -25,7 +25,9 @@
#include <stdint.h>
#include <string.h>
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_rtos1_types.h"
#include "mbed_rtos_storage.h"
namespace rtos {
/** \addtogroup rtos */
@ -34,50 +36,57 @@ namespace rtos {
/** Define and manage fixed-size memory pools of objects of a given type.
@tparam T data type of a single object (element).
@tparam queue_sz maximum number of objects (elements) in the memory pool.
@note
Memory considerations: The memory pool data store and control structures will be created on current thread's stack,
both for the mbed OS and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
*/
template<typename T, uint32_t pool_sz>
class MemoryPool {
public:
/** Create and Initialize a memory pool. */
MemoryPool() {
#ifdef CMSIS_OS_RTX
memset(_pool_m, 0, sizeof(_pool_m));
_pool_def.pool = _pool_m;
_pool_def.pool_sz = pool_sz;
_pool_def.item_sz = sizeof(T);
#endif
_pool_id = osPoolCreate(&_pool_def);
memset(_pool_mem, 0, sizeof(_pool_mem));
memset(&_obj_mem, 0, sizeof(_obj_mem));
_attr.mp_mem = _pool_mem;
_attr.mp_size = sizeof(_pool_mem);
_attr.cb_mem = &_obj_mem;
_attr.cb_size = sizeof(_obj_mem);
_id = osMemoryPoolNew(pool_sz, sizeof(T), &_attr);
MBED_ASSERT(_id);
}
/** Allocate a memory block of type T from a memory pool.
@return address of the allocated memory block or NULL in case of no memory available.
*/
T* alloc(void) {
return (T*)osPoolAlloc(_pool_id);
return (T*)osMemoryPoolAlloc(_id, 0);
}
/** Allocate a memory block of type T from a memory pool and set memory block to zero.
@return address of the allocated memory block or NULL in case of no memory available.
*/
T* calloc(void) {
return (T*)osPoolCAlloc(_pool_id);
T *item = (T*)osMemoryPoolAlloc(_id, 0);
if (item != NULL) {
memset(item, 0, sizeof(T));
}
return item;
}
/** Return an allocated memory block back to a specific memory pool.
@param address of the allocated memory block that is returned to the memory pool.
/** Free a memory block.
@param address of the allocated memory block to be freed.
@return status code that indicates the execution status of the function.
*/
osStatus free(T *block) {
return osPoolFree(_pool_id, (void*)block);
return osMemoryPoolFree(_id, (void*)block);
}
private:
osPoolId _pool_id;
osPoolDef_t _pool_def;
#ifdef CMSIS_OS_RTX
uint32_t _pool_m[3+((sizeof(T)+3)/4)*(pool_sz)];
#endif
osMemoryPoolId_t _id;
osMemoryPoolAttr_t _attr;
char _pool_mem[sizeof(T) * pool_sz];
mbed_rtos_storage_mem_pool_t _obj_mem;
};
}

View File

@ -22,35 +22,35 @@
#include "rtos/Mutex.h"
#include <string.h>
#include "platform/mbed_error.h"
#include "mbed_error.h"
#include "mbed_assert.h"
namespace rtos {
Mutex::Mutex() {
#ifdef CMSIS_OS_RTX
memset(_mutex_data, 0, sizeof(_mutex_data));
_osMutexDef.mutex = _mutex_data;
#endif
_osMutexId = osMutexCreate(&_osMutexDef);
if (_osMutexId == NULL) {
error("Error initializing the mutex object\n");
}
memset(&_obj_mem, 0, sizeof(_obj_mem));
memset(&_attr, 0, sizeof(_attr));
_attr.cb_mem = &_obj_mem;
_attr.cb_size = sizeof(_obj_mem);
_attr.attr_bits = osMutexRecursive;
_id = osMutexNew(&_attr);
MBED_ASSERT(_id);
}
osStatus Mutex::lock(uint32_t millisec) {
return osMutexWait(_osMutexId, millisec);
return osMutexAcquire(_id, millisec);
}
bool Mutex::trylock() {
return (osMutexWait(_osMutexId, 0) == osOK);
return (osMutexAcquire(_id, 0) == osOK);
}
osStatus Mutex::unlock() {
return osMutexRelease(_osMutexId);
return osMutexRelease(_id);
}
Mutex::~Mutex() {
osMutexDelete(_osMutexId);
osMutexDelete(_id);
}
}

View File

@ -23,14 +23,20 @@
#define MUTEX_H
#include <stdint.h>
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_rtos1_types.h"
#include "mbed_rtos_storage.h"
namespace rtos {
/** \addtogroup rtos */
/** @{*/
/** The Mutex class is used to synchronise the execution of threads.
/** The Mutex class is used to synchronize the execution of threads.
This is for example used to protect access to a shared resource.
@note
Memory considerations: The mutex control structures will be created on current thread's stack, both for the mbed OS
and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
*/
class Mutex {
public:
@ -56,15 +62,9 @@ public:
~Mutex();
private:
osMutexId _osMutexId;
osMutexDef_t _osMutexDef;
#ifdef CMSIS_OS_RTX
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
int32_t _mutex_data[4];
#else
int32_t _mutex_data[3];
#endif
#endif
osMutexId_t _id;
osMutexAttr_t _attr;
mbed_rtos_storage_mutex_t _obj_mem;
};
}

View File

@ -25,8 +25,10 @@
#include <stdint.h>
#include <string.h>
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_rtos_storage.h"
#include "platform/mbed_error.h"
#include "mbed_rtos1_types.h"
namespace rtos {
/** \addtogroup rtos */
@ -37,30 +39,34 @@ namespace rtos {
to a thread or interrupt service routine.
@tparam T data type of a single message element.
@tparam queue_sz maximum number of messages in queue.
@note
Memory considerations: The queue control structures will be created on current thread's stack, both for the mbed OS
and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
*/
template<typename T, uint32_t queue_sz>
class Queue {
public:
/** Create and initialise a message Queue. */
/** Create and initialize a message Queue. */
Queue() {
#ifdef CMSIS_OS_RTX
memset(_queue_q, 0, sizeof(_queue_q));
_queue_def.pool = _queue_q;
_queue_def.queue_sz = queue_sz;
#endif
_queue_id = osMessageCreate(&_queue_def, NULL);
if (_queue_id == NULL) {
error("Error initialising the queue object\n");
}
memset(&_obj_mem, 0, sizeof(_obj_mem));
memset(&_attr, 0, sizeof(_attr));
_attr.mq_mem = _queue_mem;
_attr.mq_size = sizeof(_queue_mem);
_attr.cb_mem = &_obj_mem;
_attr.cb_size = sizeof(_obj_mem);
_id = osMessageQueueNew(queue_sz, sizeof(T*), &_attr);
MBED_ASSERT(_id);
}
/** Put a message in a Queue.
@param data message pointer.
@param millisec timeout value or 0 in case of no time-out. (default: 0)
@param prio priority value or 0 in case of default. (default: 0)
@return status code that indicates the execution status of the function.
*/
osStatus put(T* data, uint32_t millisec=0) {
return osMessagePut(_queue_id, (uint32_t)data, millisec);
osStatus put(T* data, uint32_t millisec=0, uint8_t prio=0) {
return osMessageQueuePut(_id, &data, prio, millisec);
}
/** Get a message or Wait for a message from a Queue.
@ -68,15 +74,36 @@ public:
@return event information that includes the message and the status code.
*/
osEvent get(uint32_t millisec=osWaitForever) {
return osMessageGet(_queue_id, millisec);
osEvent event;
T *data = NULL;
osStatus_t res = osMessageQueueGet(_id, &data, NULL, millisec);
switch (res) {
case osOK:
event.status = (osStatus)osEventMessage;
event.value.p = data;
break;
case osErrorResource:
event.status = osOK;
break;
case osErrorTimeout:
event.status = (osStatus)osEventTimeout;
break;
case osErrorParameter:
default:
event.status = osErrorParameter;
break;
}
event.def.message_id = _id;
return event;
}
private:
osMessageQId _queue_id;
osMessageQDef_t _queue_def;
#ifdef CMSIS_OS_RTX
uint32_t _queue_q[4+(queue_sz)];
#endif
osMessageQueueId_t _id;
osMessageQueueAttr_t _attr;
char _queue_mem[queue_sz * (sizeof(T*) + sizeof(mbed_rtos_storage_message_t))];
mbed_rtos_storage_msg_queue_t _obj_mem;
};
}

View File

@ -24,32 +24,30 @@
#include <string.h>
#include "mbed.h"
#include "cmsis_os.h"
#include "platform/mbed_error.h"
namespace rtos {
void RtosTimer::constructor(mbed::Callback<void()> func, os_timer_type type) {
#ifdef CMSIS_OS_RTX
_timer.ptimer = (void (*)(const void *))Callback<void()>::thunk;
memset(_timer_data, 0, sizeof(_timer_data));
_timer.timer = _timer_data;
#endif
_function = func;
_timer_id = osTimerCreate(&_timer, type, &_function);
memset(&_obj_mem, 0, sizeof(_obj_mem));
memset(&_attr, 0, sizeof(_attr));
_attr.cb_mem = &_obj_mem;
_attr.cb_size = sizeof(_obj_mem);
_id = osTimerNew((void (*)(void *))Callback<void()>::thunk, type, &_function, &_attr);
MBED_ASSERT(_id);
}
osStatus RtosTimer::start(uint32_t millisec) {
return osTimerStart(_timer_id, millisec);
return osTimerStart(_id, millisec);
}
osStatus RtosTimer::stop(void) {
return osTimerStop(_timer_id);
return osTimerStop(_id);
}
RtosTimer::~RtosTimer() {
osTimerDelete(_timer_id);
osTimerDelete(_id);
}
}

View File

@ -23,9 +23,11 @@
#define RTOS_TIMER_H
#include <stdint.h>
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "rtx_lib.h"
#include "platform/Callback.h"
#include "platform/mbed_toolchain.h"
#include "mbed_rtos1_types.h"
namespace rtos {
/** \addtogroup rtos */
@ -72,6 +74,10 @@ namespace rtos {
queue.cancel(blink_id); // stop after 5s
}
@endcode
@note
Memory considerations: The timer control structures will be created on current thread's stack, both for the mbed OS
and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
*/
class RtosTimer {
public:
@ -140,13 +146,11 @@ private:
// Required to share definitions without
// delegated constructors
void constructor(mbed::Callback<void()> func, os_timer_type type);
osTimerId_t _id;
osTimerAttr_t _attr;
os_timer_t _obj_mem;
mbed::Callback<void()> _function;
osTimerId _timer_id;
osTimerDef_t _timer;
#ifdef CMSIS_OS_RTX
uint32_t _timer_data[6];
#endif
};
}

View File

@ -20,29 +20,49 @@
* SOFTWARE.
*/
#include "rtos/Semaphore.h"
#include "platform/mbed_assert.h"
#include <string.h>
namespace rtos {
Semaphore::Semaphore(int32_t count) {
#ifdef CMSIS_OS_RTX
memset(_semaphore_data, 0, sizeof(_semaphore_data));
_osSemaphoreDef.semaphore = _semaphore_data;
#endif
_osSemaphoreId = osSemaphoreCreate(&_osSemaphoreDef, count);
constructor(count, 1024);
}
Semaphore::Semaphore(int32_t count, uint16_t max_count) {
constructor(count, max_count);
}
void Semaphore::constructor(int32_t count, uint16_t max_count) {
memset(&_obj_mem, 0, sizeof(_obj_mem));
memset(&_attr, 0, sizeof(_attr));
_attr.cb_mem = &_obj_mem;
_attr.cb_size = sizeof(_obj_mem);
_id = osSemaphoreNew(max_count, count, &_attr);
MBED_ASSERT(_id != NULL);
}
int32_t Semaphore::wait(uint32_t millisec) {
return osSemaphoreWait(_osSemaphoreId, millisec);
osStatus_t stat = osSemaphoreAcquire(_id, millisec);
switch (stat) {
case osOK:
return osSemaphoreGetCount(_id) + 1;
case osErrorTimeout:
case osErrorResource:
return 0;
case osErrorParameter:
default:
return -1;
}
}
osStatus Semaphore::release(void) {
return osSemaphoreRelease(_osSemaphoreId);
return osSemaphoreRelease(_id);
}
Semaphore::~Semaphore() {
osSemaphoreDelete(_osSemaphoreId);
osSemaphoreDelete(_id);
}
}

View File

@ -23,13 +23,20 @@
#define SEMAPHORE_H
#include <stdint.h>
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_rtos1_types.h"
#include "mbed_rtos_storage.h"
namespace rtos {
/** \addtogroup rtos */
/** @{*/
/** The Semaphore class is used to manage and protect access to a set of shared resources. */
/** The Semaphore class is used to manage and protect access to a set of shared resources.
*
* @note
* Memory considerations: The semaphore control structures will be created on current thread's stack, both for the mbed OS
* and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
*/
class Semaphore {
public:
/** Create and Initialize a Semaphore object used for managing resources.
@ -37,6 +44,12 @@ public:
*/
Semaphore(int32_t count=0);
/** Create and Initialize a Semaphore object used for managing resources.
@param count number of available resources
@param max_count maximum number of available resources
*/
Semaphore(int32_t count, uint16_t max_count);
/** Wait until a Semaphore resource becomes available.
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
@return number of available tokens, or -1 in case of incorrect parameters
@ -51,11 +64,11 @@ public:
~Semaphore();
private:
osSemaphoreId _osSemaphoreId;
osSemaphoreDef_t _osSemaphoreDef;
#ifdef CMSIS_OS_RTX
uint32_t _semaphore_data[2];
#endif
void constructor(int32_t count, uint16_t max_count);
osSemaphoreId_t _id;
osSemaphoreAttr_t _attr;
mbed_rtos_storage_semaphore_t _obj_mem;
};
}

View File

@ -24,17 +24,10 @@
#include "mbed.h"
#include "rtos/rtos_idle.h"
// rt_tid2ptcb is an internal function which we exposed to get TCB for thread id
#undef NULL //Workaround for conflicting macros in rt_TypeDef.h and stdio.h
#include "rt_TypeDef.h"
extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id);
static void (*terminate_hook)(osThreadId id) = 0;
extern "C" void thread_terminate_hook(osThreadId id)
static void (*terminate_hook)(osThreadId_t id) = 0;
extern "C" void thread_terminate_hook(osThreadId_t id)
{
if (terminate_hook != (void (*)(osThreadId))NULL) {
if (terminate_hook != (void (*)(osThreadId_t))NULL) {
terminate_hook(id);
}
}
@ -42,21 +35,21 @@ extern "C" void thread_terminate_hook(osThreadId id)
namespace rtos {
void Thread::constructor(osPriority priority,
uint32_t stack_size, unsigned char *stack_pointer) {
uint32_t stack_size, unsigned char *stack_mem, const char *name) {
_tid = 0;
_dynamic_stack = (stack_mem == NULL);
_finished = false;
_dynamic_stack = (stack_pointer == NULL);
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
_thread_def.tpriority = priority;
_thread_def.stacksize = stack_size;
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
#endif
memset(&_obj_mem, 0, sizeof(_obj_mem));
memset(&_attr, 0, sizeof(_attr));
_attr.priority = priority;
_attr.stack_size = stack_size;
_attr.name = name;
_attr.stack_mem = (uint32_t*)stack_mem;
}
void Thread::constructor(Callback<void()> task,
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
constructor(priority, stack_size, stack_pointer);
osPriority priority, uint32_t stack_size, unsigned char *stack_mem, const char *name) {
constructor(priority, stack_size, stack_mem, name);
switch (start(task)) {
case osErrorResource:
@ -80,24 +73,25 @@ osStatus Thread::start(Callback<void()> task) {
return osErrorParameter;
}
#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM)
_thread_def.pthread = Thread::_thunk;
if (_thread_def.stack_pointer == NULL) {
_thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
MBED_ASSERT(_thread_def.stack_pointer != NULL);
if (_attr.stack_mem == NULL) {
_attr.stack_mem = new uint32_t[_attr.stack_size/sizeof(uint32_t)];
MBED_ASSERT(_attr.stack_mem != NULL);
}
//Fill the stack with a magic word for maximum usage checking
for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) {
_thread_def.stack_pointer[i] = 0xE25A2EA5;
for (uint32_t i = 0; i < (_attr.stack_size / sizeof(uint32_t)); i++) {
((uint32_t *)_attr.stack_mem)[i] = 0xE25A2EA5;
}
#endif
memset(&_obj_mem, 0, sizeof(_obj_mem));
_attr.cb_size = sizeof(_obj_mem);
_attr.cb_mem = &_obj_mem;
_task = task;
_tid = osThreadCreate(&_thread_def, this);
_tid = osThreadNew(Thread::_thunk, this, &_attr);
if (_tid == NULL) {
if (_dynamic_stack) {
delete[] (_thread_def.stack_pointer);
_thread_def.stack_pointer = (uint32_t*)NULL;
delete[] (uint32_t *)(_attr.stack_mem);
_attr.stack_mem = (uint32_t*)NULL;
}
_mutex.unlock();
_join_sem.release();
@ -109,27 +103,27 @@ osStatus Thread::start(Callback<void()> task) {
}
osStatus Thread::terminate() {
osStatus ret;
osStatus_t ret;
_mutex.lock();
// Set the Thread's tid to NULL and
// release the semaphore before terminating
// since this thread could be terminating itself
osThreadId local_id = _tid;
osThreadId_t local_id = _tid;
_join_sem.release();
_tid = (osThreadId)NULL;
_tid = (osThreadId_t)NULL;
_finished = true;
_mutex.unlock();
ret = osThreadTerminate(local_id);
_mutex.unlock();
return ret;
}
osStatus Thread::join() {
int32_t ret = _join_sem.wait();
if (ret < 0) {
return osErrorOS;
return osError;
}
// The semaphore has been released so this thread is being
@ -145,7 +139,7 @@ osStatus Thread::join() {
}
osStatus Thread::set_priority(osPriority priority) {
osStatus ret;
osStatus_t ret;
_mutex.lock();
ret = osThreadSetPriority(_tid, priority);
@ -155,7 +149,7 @@ osStatus Thread::set_priority(osPriority priority) {
}
osPriority Thread::get_priority() {
osPriority ret;
osPriority_t ret;
_mutex.lock();
ret = osThreadGetPriority(_tid);
@ -164,176 +158,162 @@ osPriority Thread::get_priority() {
return ret;
}
int32_t Thread::signal_set(int32_t signals) {
// osSignalSet is thread safe as long as the underlying
// thread does not get terminated or return from main
return osSignalSet(_tid, signals);
int32_t Thread::signal_set(int32_t flags) {
return osThreadFlagsSet(_tid, flags);
}
int32_t Thread::signal_clr(int32_t signals) {
// osSignalClear is thread safe as long as the underlying
// thread does not get terminated or return from main
return osSignalClear(_tid, signals);
int32_t Thread::signal_clr(int32_t flags) {
return osThreadFlagsClear(flags);
}
Thread::State Thread::get_state() {
#if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM)
#ifdef CMSIS_OS_RTX
State status;
uint8_t state = osThreadTerminated;
_mutex.lock();
if (_tid != NULL) {
status = (State)_thread_def.tcb.state;
} else if (_finished) {
status = Deleted;
} else {
status = Inactive;
state = _obj_mem.state;
}
_mutex.unlock();
return status;
#endif
#else
State status = Deleted;
_mutex.lock();
if (_tid != NULL) {
status = (State)osThreadGetState(_tid);
State user_state;
switch(state) {
case osThreadInactive:
user_state = Inactive;
break;
case osThreadReady:
user_state = Ready;
break;
case osThreadRunning:
user_state = Running;
break;
case osRtxThreadWaitingDelay:
user_state = WaitingDelay;
break;
case osRtxThreadWaitingJoin:
user_state = WaitingJoin;
break;
case osRtxThreadWaitingThreadFlags:
user_state = WaitingThreadFlag;
break;
case osRtxThreadWaitingEventFlags:
user_state = WaitingEventFlag;
break;
case osRtxThreadWaitingMutex:
user_state = WaitingMutex;
break;
case osRtxThreadWaitingSemaphore:
user_state = WaitingSemaphore;
break;
case osRtxThreadWaitingMemoryPool:
user_state = WaitingMemoryPool;
break;
case osRtxThreadWaitingMessageGet:
user_state = WaitingMessageGet;
break;
case osRtxThreadWaitingMessagePut:
user_state = WaitingMessagePut;
break;
case osThreadTerminated:
default:
user_state = Deleted;
break;
}
_mutex.unlock();
return status;
#endif
return user_state;
}
uint32_t Thread::stack_size() {
#ifndef __MBED_CMSIS_RTOS_CA9
#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
uint32_t size = 0;
_mutex.lock();
if (_tid != NULL) {
size = _thread_def.tcb.priv_stack;
os_thread_t *thread = (os_thread_t *)_tid;
size = thread->stack_size;
}
_mutex.unlock();
return size;
#else
uint32_t size = 0;
_mutex.lock();
if (_tid != NULL) {
P_TCB tcb = rt_tid2ptcb(_tid);
size = tcb->priv_stack;
}
_mutex.unlock();
return size;
#endif
#else
return 0;
#endif
}
uint32_t Thread::free_stack() {
#ifndef __MBED_CMSIS_RTOS_CA9
#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
uint32_t size = 0;
_mutex.lock();
if (_tid != NULL) {
uint32_t bottom = (uint32_t)_thread_def.tcb.stack;
size = _thread_def.tcb.tsk_stack - bottom;
os_thread_t *thread = (os_thread_t *)_tid;
size = (uint32_t)thread->stack_mem - thread->sp;
}
_mutex.unlock();
return size;
#else
uint32_t size = 0;
_mutex.lock();
if (_tid != NULL) {
P_TCB tcb = rt_tid2ptcb(_tid);
uint32_t bottom = (uint32_t)tcb->stack;
size = tcb->tsk_stack - bottom;
}
_mutex.unlock();
return size;
#endif
#else
return 0;
#endif
}
uint32_t Thread::used_stack() {
#ifndef __MBED_CMSIS_RTOS_CA9
#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
uint32_t size = 0;
_mutex.lock();
if (_tid != NULL) {
uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack;
size = top - _thread_def.tcb.tsk_stack;
os_thread_t *thread = (os_thread_t *)_tid;
size = ((uint32_t)thread->stack_mem + thread->stack_size) - thread->sp;
}
_mutex.unlock();
return size;
#else
uint32_t size = 0;
_mutex.lock();
if (_tid != NULL) {
P_TCB tcb = rt_tid2ptcb(_tid);
uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack;
size = top - tcb->tsk_stack;
}
_mutex.unlock();
return size;
#endif
#else
return 0;
#endif
}
uint32_t Thread::max_stack() {
#ifndef __MBED_CMSIS_RTOS_CA9
#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM)
uint32_t size = 0;
_mutex.lock();
if (_tid != NULL) {
os_thread_t *thread = (os_thread_t *)_tid;
uint32_t high_mark = 0;
while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5)
while (((uint32_t *)(thread->stack_mem))[high_mark] == 0xE25A2EA5)
high_mark++;
size = _thread_def.tcb.priv_stack - (high_mark * 4);
size = thread->stack_size - (high_mark * sizeof(uint32_t));
}
_mutex.unlock();
return size;
#else
uint32_t size = 0;
_mutex.lock();
}
if (_tid != NULL) {
P_TCB tcb = rt_tid2ptcb(_tid);
uint32_t high_mark = 0;
while (tcb->stack[high_mark] == 0xE25A2EA5)
high_mark++;
size = tcb->priv_stack - (high_mark * 4);
}
_mutex.unlock();
return size;
#endif
#else
return 0;
#endif
const char *Thread::get_name() {
return _attr.name;
}
osEvent Thread::signal_wait(int32_t signals, uint32_t millisec) {
return osSignalWait(signals, millisec);
uint32_t res;
osEvent evt;
uint32_t options = osFlagsWaitAll;
if (signals == 0) {
options = osFlagsWaitAny;
signals = 0x7FFFFFFF;
}
res = osThreadFlagsWait(signals, options, millisec);
if (res & osFlagsError) {
switch (res) {
case osFlagsErrorISR:
evt.status = osErrorISR;
break;
case osFlagsErrorResource:
evt.status = osOK;
break;
case osFlagsErrorTimeout:
evt.status = (osStatus)osEventTimeout;
break;
case osFlagsErrorParameter:
default:
evt.status = (osStatus)osErrorValue;
break;
}
}
evt.status = (osStatus)osEventSignal;
evt.value.signals = res;
return evt;
}
osStatus Thread::wait(uint32_t millisec) {
@ -352,30 +332,28 @@ void Thread::attach_idle_hook(void (*fptr)(void)) {
rtos_attach_idle_hook(fptr);
}
void Thread::attach_terminate_hook(void (*fptr)(osThreadId id)) {
void Thread::attach_terminate_hook(void (*fptr)(osThreadId_t id)) {
terminate_hook = fptr;
}
Thread::~Thread() {
// terminate is thread safe
terminate();
#ifdef __MBED_CMSIS_RTOS_CM
if (_dynamic_stack) {
delete[] (_thread_def.stack_pointer);
_thread_def.stack_pointer = (uint32_t*)NULL;
delete[] (uint32_t*)(_attr.stack_mem);
_attr.stack_mem = (uint32_t*)NULL;
}
#endif
}
void Thread::_thunk(const void * thread_ptr)
void Thread::_thunk(void * thread_ptr)
{
Thread *t = (Thread*)thread_ptr;
t->_task();
t->_mutex.lock();
t->_tid = (osThreadId)NULL;
t->_finished = true;
t->_mutex.unlock();
t->_join_sem.release();
// rtos will release the mutex automatically
}
}

View File

@ -23,7 +23,10 @@
#define THREAD_H
#include <stdint.h>
#include "cmsis_os.h"
#include "cmsis_os2.h"
#include "mbed_rtos1_types.h"
#include "mbed_rtos_storage.h"
#include "mbed_rtx_conf.h"
#include "platform/Callback.h"
#include "platform/mbed_toolchain.h"
#include "rtos/Semaphore.h"
@ -60,31 +63,37 @@ namespace rtos {
* thread.join();
* }
* @endcode
*
* @note
* Memory considerations: The thread control structures will be created on current thread's stack, both for the mbed OS
* and underlying RTOS objects (static or dynamic RTOS memory pools are not being used).
* Additionally the stack memory for this thread will be allocated on the heap, if it wasn't supplied to the constructor.
*/
class Thread {
public:
/** Allocate a new thread without starting execution
@param priority initial priority of the thread function. (default: osPriorityNormal).
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
@param name name to be used for this thread. It has to stay allocated for the lifetime of the thread (default: NULL)
*/
Thread(osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
constructor(priority, stack_size, stack_pointer);
uint32_t stack_size=OS_STACK_SIZE,
unsigned char *stack_mem=NULL, const char *name=NULL) {
constructor(priority, stack_size, stack_mem, name);
}
/** Create a new thread, and start it executing the specified function.
@param task function to be executed by this thread.
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
@param priority initial priority of the thread function. (default: osPriorityNormal).
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
@deprecated
Thread-spawning constructors hide errors. Replaced by thread.start(task).
@code
Thread thread(priority, stack_size, stack_pointer);
Thread thread(priority, stack_size, stack_mem);
osStatus status = thread.start(task);
if (status != osOK) {
@ -97,9 +106,9 @@ public:
"Replaced by thread.start(task).")
Thread(mbed::Callback<void()> task,
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
constructor(task, priority, stack_size, stack_pointer);
uint32_t stack_size=OS_STACK_SIZE,
unsigned char *stack_mem=NULL) {
constructor(task, priority, stack_size, stack_mem);
}
/** Create a new thread, and start it executing the specified function.
@ -107,13 +116,13 @@ public:
@param method function to be executed by this thread.
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
@param priority initial priority of the thread function. (default: osPriorityNormal).
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
@deprecated
Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
@code
Thread thread(priority, stack_size, stack_pointer);
Thread thread(priority, stack_size, stack_mem);
osStatus status = thread.start(callback(task, argument));
if (status != osOK) {
@ -127,10 +136,10 @@ public:
"Replaced by thread.start(callback(task, argument)).")
Thread(T *argument, void (T::*task)(),
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
uint32_t stack_size=OS_STACK_SIZE,
unsigned char *stack_mem=NULL) {
constructor(mbed::callback(task, argument),
priority, stack_size, stack_pointer);
priority, stack_size, stack_mem);
}
/** Create a new thread, and start it executing the specified function.
@ -138,13 +147,13 @@ public:
@param method function to be executed by this thread.
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
@param priority initial priority of the thread function. (default: osPriorityNormal).
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
@deprecated
Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
@code
Thread thread(priority, stack_size, stack_pointer);
Thread thread(priority, stack_size, stack_mem);
osStatus status = thread.start(callback(task, argument));
if (status != osOK) {
@ -158,10 +167,10 @@ public:
"Replaced by thread.start(callback(task, argument)).")
Thread(T *argument, void (*task)(T *),
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
uint32_t stack_size=OS_STACK_SIZE,
unsigned char *stack_mem=NULL) {
constructor(mbed::callback(task, argument),
priority, stack_size, stack_pointer);
priority, stack_size, stack_mem);
}
/** Create a new thread, and start it executing the specified function.
@ -169,13 +178,13 @@ public:
@param task function to be executed by this thread.
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
@param priority initial priority of the thread function. (default: osPriorityNormal).
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
@param stack_size stack size (in bytes) requirements for the thread function. (default: OS_STACK_SIZE).
@param stack_mem pointer to the stack area to be used by this thread (default: NULL).
@deprecated
Thread-spawning constructors hide errors. Replaced by thread.start(callback(task, argument)).
@code
Thread thread(priority, stack_size, stack_pointer);
Thread thread(priority, stack_size, stack_mem);
osStatus status = thread.start(callback(task, argument));
if (status != osOK) {
@ -188,10 +197,10 @@ public:
"Replaced by thread.start(callback(task, argument)).")
Thread(void (*task)(void const *argument), void *argument=NULL,
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL) {
uint32_t stack_size=OS_STACK_SIZE,
unsigned char *stack_mem=NULL) {
constructor(mbed::callback((void (*)(void *))task, argument),
priority, stack_size, stack_pointer);
priority, stack_size, stack_mem);
}
/** Starts a thread executing the specified function.
@ -240,13 +249,13 @@ public:
/** Set the specified Signal Flags of an active thread.
@param signals specifies the signal flags of the thread that should be set.
@return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
@return previous signal flags of the specified thread or osFlagsError in case of incorrect parameters.
*/
int32_t signal_set(int32_t signals);
/** Clears the specified Signal Flags of an active thread.
@param signals specifies the signal flags of the thread that should be cleared.
@return resultant signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
@return resultant signal flags of the specified thread or osFlagsError in case of incorrect parameters.
*/
int32_t signal_clr(int32_t signals);
@ -256,12 +265,18 @@ public:
Ready, /**< Ready to run */
Running, /**< Running */
WaitingDelay, /**< Waiting for a delay to occur */
WaitingJoin, /**< Waiting for thread to join */
WaitingThreadFlag, /**< Waiting for a thread flag to be set */
WaitingEventFlag, /**< Waiting for a event flag to be set */
WaitingMutex, /**< Waiting for a mutex event to occur */
WaitingSemaphore, /**< Waiting for a semaphore event to occur */
WaitingMemoryPool, /**< Waiting for a memory pool */
WaitingMessageGet, /**< Waiting for message to arrive */
WaitingMessagePut, /**< Waiting for message to be send */
WaitingInterval, /**< Waiting for an interval to occur */
WaitingOr, /**< Waiting for one event in a set to occur */
WaitingAnd, /**< Waiting for multiple events in a set to occur */
WaitingSemaphore, /**< Waiting for a semaphore event to occur */
WaitingMailbox, /**< Waiting for a mailbox event to occur */
WaitingMutex, /**< Waiting for a mutex event to occur */
/* Not in sync with RTX below here */
Deleted, /**< The task has been deleted */
@ -292,8 +307,13 @@ public:
*/
uint32_t max_stack();
/** Get thread name
@return thread name or NULL if the name was not set.
*/
const char *get_name();
/** Wait for one or more Signal Flags to become signaled for the current RUNNING thread.
@param signals wait until all specified signal flags set or 0 for any single signal flag.
@param signals wait until all specified signal flags are set or 0 for any single signal flag.
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
@return event flag information or error code.
@note not callable from interrupt
@ -317,7 +337,7 @@ public:
@return thread ID for reference by other functions or NULL in case of error.
*/
static osThreadId gettid();
/** Attach a function to be called by the RTOS idle task
@param fptr pointer to the function to be called
*/
@ -338,21 +358,24 @@ private:
// Required to share definitions without
// delegated constructors
void constructor(osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL);
uint32_t stack_size=OS_STACK_SIZE,
unsigned char *stack_mem=NULL,
const char *name=NULL);
void constructor(mbed::Callback<void()> task,
osPriority priority=osPriorityNormal,
uint32_t stack_size=DEFAULT_STACK_SIZE,
unsigned char *stack_pointer=NULL);
static void _thunk(const void * thread_ptr);
uint32_t stack_size=OS_STACK_SIZE,
unsigned char *stack_mem=NULL,
const char *name=NULL);
static void _thunk(void * thread_ptr);
mbed::Callback<void()> _task;
osThreadId _tid;
osThreadDef_t _thread_def;
Semaphore _join_sem;
Mutex _mutex;
bool _dynamic_stack;
bool _finished;
mbed::Callback<void()> _task;
osThreadId_t _tid;
osThreadAttr_t _attr;
bool _dynamic_stack;
Semaphore _join_sem;
Mutex _mutex;
mbed_rtos_storage_thread_t _obj_mem;
bool _finished;
};
}

637
rtos/mbed_boot.c Normal file
View File

@ -0,0 +1,637 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2016 ARM Limited
*
* 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.
*/
/* mbed OS boot sequence
*
* Most of mbed supported targets use default ARM Cortex M boot approach, where the core starts executing reset vector
* after power up. Reset ISR is defined for each target by the vendor (basing on CMSIS template). Reset vector is
* responsible for low level platform init and then calling in libc (__main). Depending on compiler and version of C
* library, predefined function will be called which is implemented by mbed OS.
*
* There's number of functions, vendor and users can provide to setup the platform and/or inject a code to be executed
* before main():
* * Reset vector and SystemInit: Reset vector should do low level core and board initialization.
* * mbed_sdk_init: Higher level board init and making sure the board is ready for the mbed OS.
* * mbed_main: User's code to be executed before main().
* * main: Standard application code.
*
* Detailed boot procedures:
*
* For ARMCC:
* ==========
*
* Reset (TARGET)
* -> SystemInit (TARGET)
* -> __main (LIBC)
* -> __rt_entry (MBED: rtos/mbed_boot.c)
* -> __user_setup_stackheap (LIBC)
* -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
* -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
* -> mbed_sdk_init (TARGET)
* -> _platform_post_stackheap_init (RTX)
* -> osKernelInitialize (RTX)
* -> mbed_start_main (MBED: rtos/mbed_boot.c)
* -> osThreadNew (RTX)
* -> pre_main(MBED: rtos/mbed_boot.c)
* -> __rt_lib_init (LIBC)
* -> $Sub$$main (MBED: rtos/mbed_boot.c)
* -> mbed_main (MBED: rtos/mbed_boot.c)
* -> main (APP)
* -> osKernelStart (RTX)
*
* In addition to the above, libc will use functions defined by RTX: __user_perthread_libspace, _mutex_initialize,
* _mutex_acquire, _mutex_release, _mutex_free for details consult: ARM C and C++ Libraries and Floating-Point
* Support User Guide.
*
* For MICROLIB:
* ==========
*
* Reset (TARGET)
* -> SystemInit (TARGET)
* -> __main (LIBC)
* -> _main_init (MBED: rtos/mbed_boot.c)
* -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
* -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
* -> mbed_sdk_init (TARGET)
* -> osKernelInitialize (RTX)
* -> mbed_start_main (MBED: rtos/mbed_boot.c)
* -> osThreadNew (RTX)
* -> pre_main(MBED: rtos/mbed_boot.c)
* -> __cpp_initialize__aeabi_ (LIBC)
* -> $Sub$$main (MBED: rtos/mbed_boot.c)
* -> mbed_main (MBED: rtos/mbed_boot.c)
* -> main (APP)
* -> osKernelStart (RTX)
*
* For GCC:
* ========
*
* Reset (TARGET)
* -> SystemInit (TARGET)
* -> __main (LIBC)
* -> software_init_hook (MBED: rtos/mbed_boot.c)
* -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
* -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
* -> mbed_sdk_init (TARGET)
* -> osKernelInitialize (RTX)
* -> mbed_start_main (MBED: rtos/mbed_boot.c)
* -> osThreadNew (RTX)
* -> pre_main(MBED: rtos/mbed_boot.c)
* -> __libc_init_array (LIBC)
* -> __wrap_main (MBED: rtos/mbed_boot.c)
* -> mbed_main (MBED: rtos/mbed_boot.c)
* -> __real_main (APP)
* -> osKernelStart (RTX)
*
* For IAR:
* ========
*
* Reset (TARGET)
* -> SystemInit (TARGET)
* -> __iar_program_start
* -> __iar_init_core
* -> __iar_init_core
* -> __iar_init_vfp
* -> __low_level_init
* -> __iar_data_init3
* -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
* -> mbed_sdk_init (TARGET)
* -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
* -> osKernelInitialize (RTX)
* -> mbed_start_main (MBED: rtos/mbed_boot.c)
* -> osThreadNew (RTX)
* -> pre_main(MBED: rtos/mbed_boot.c)
* -> __iar_dynamic_initialization
* -> main
* -> osKernelStart (RTX)
*
* Other notes:
*
* * In addition to the above, libc will use functions defined in mbed_boot.c: __rtos_malloc_lock/unlock,
* __rtos_env_lock/unlock.
*
* * First step after the execution is passed to mbed, software_init_hook for GCC and __rt_entry for ARMC is to
* initialize heap.
*
* Memory layout notes:
* ====================
*
* IAR Default Memory layout notes:
* -Heap defined by "HEAP" region in .icf file
* -Interrupt stack defined by "CSTACK" region in .icf file
* -Value INITIAL_SP is ignored
*
* IAR Custom Memory layout notes:
* -There is no custom layout available for IAR - everything must be defined in
* the .icf file and use the default layout
*
*
* GCC Default Memory layout notes:
* -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt
* stack and heap in the function set_stack_heap()
* -ISR_STACK_SIZE can be overridden to be larger or smaller
*
* GCC Custom Memory layout notes:
* -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
* -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
*
*
* ARM Memory layout
* -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt
* stack and heap in the function set_stack_heap()
* -ISR_STACK_SIZE can be overridden to be larger or smaller
*
* ARM Custom Memory layout notes:
* -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
* -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
*
*/
#include "cmsis.h"
#include "mbed_rtx.h"
#include "mbed_rtos_storage.h"
#include "cmsis_os2.h"
#include "mbed_toolchain.h"
#include "mbed_error.h"
/* Heap limits - only used if set */
extern unsigned char *mbed_heap_start;
extern uint32_t mbed_heap_size;
unsigned char *mbed_stack_isr_start = 0;
uint32_t mbed_stack_isr_size = 0;
WEAK void mbed_main(void);
void pre_main (void);
osThreadAttr_t _main_thread_attr;
/* The main stack size is hardcoded on purpose, so it's less tempting to change it per platform. As usually it's not
* the correct solution to the problem and it makes mbed OS behave differently on different targets.
*/
MBED_ALIGN(8) char _main_stack[4096];
mbed_rtos_storage_thread_t _main_obj;
osMutexId_t singleton_mutex_id;
mbed_rtos_storage_mutex_t singleton_mutex_obj;
osMutexAttr_t singleton_mutex_attr;
/*
* Sanity check values
*/
#if defined(__ICCARM__) && \
(defined(HEAP_START) || defined(HEAP_SIZE) || \
defined(ISR_STACK_START) && defined(ISR_STACK_SIZE))
#error "No custom layout allowed for IAR. Use .icf file instead"
#endif
#if defined(HEAP_START) && !defined(HEAP_SIZE)
#error "HEAP_SIZE must be defined if HEAP_START is defined"
#endif
#if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE)
#error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined"
#endif
#if defined(HEAP_SIZE) && !defined(HEAP_START)
#error "HEAP_START must be defined if HEAP_SIZE is defined"
#endif
/* IAR - INITIAL_SP and HEAP_START ignored as described in Memory layout notes above
*/
#if !defined(__ICCARM__) && !defined(INITIAL_SP) && !defined(HEAP_START)
#error "no target defined"
#endif
/* Interrupt stack and heap always defined for IAR
* Main thread defined here
*/
#if defined(__ICCARM__)
#pragma section="CSTACK"
#pragma section="HEAP"
#define HEAP_START ((unsigned char*)__section_begin("HEAP"))
#define HEAP_SIZE ((uint32_t)__section_size("HEAP"))
#define ISR_STACK_START ((unsigned char*)__section_begin("CSTACK"))
#define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK"))
#endif
/* Define heap region if it has not been defined already */
#if !defined(HEAP_START)
#if defined(__ICCARM__)
#error "Heap should already be defined for IAR"
#elif defined(__CC_ARM)
extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
#define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit)
#define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
#elif defined(__GNUC__)
extern uint32_t __end__[];
#define HEAP_START ((unsigned char*)__end__)
#define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
#endif
#endif
/* Define stack sizes if they haven't been set already */
#if !defined(ISR_STACK_SIZE)
#define ISR_STACK_SIZE ((uint32_t)1024)
#endif
/*
* mbed_set_stack_heap purpose is to set the following variables:
* -mbed_heap_start
* -mbed_heap_size
* -mbed_stack_isr_start
* -mbed_stack_isr_size
*/
void mbed_set_stack_heap(void) {
unsigned char *free_start = HEAP_START;
uint32_t free_size = HEAP_SIZE;
#ifdef ISR_STACK_START
/* Interrupt stack explicitly specified */
mbed_stack_isr_size = ISR_STACK_SIZE;
mbed_stack_isr_start = ISR_STACK_START;
#else
/* Interrupt stack - reserve space at the end of the free block */
mbed_stack_isr_size = ISR_STACK_SIZE < free_size ? ISR_STACK_SIZE : free_size;
mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size;
free_size -= mbed_stack_isr_size;
#endif
/* Heap - everything else */
mbed_heap_size = free_size;
mbed_heap_start = free_start;
}
static void mbed_cpy_nvic(void)
{
/* If vector address in RAM is defined, copy and switch to dynamic vectors. Exceptions for M0 which doesn't have
VTOR register and for A9 for which CMSIS doesn't define NVIC_SetVector; in both cases target code is
responsible for correctly handling the vectors.
*/
#if !defined(__CORTEX_M0) && !defined(__CORTEX_A9)
#ifdef NVIC_RAM_VECTOR_ADDRESS
uint32_t *old_vectors = (uint32_t *)SCB->VTOR;
uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
for (int i = 0; i < NVIC_NUM_VECTORS; i++) {
vectors[i] = old_vectors[i];
}
SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS;
#endif /* NVIC_RAM_VECTOR_ADDRESS */
#endif /* !defined(__CORTEX_M0) && !defined(__CORTEX_A9) */
}
/* mbed_main is a function that is called before main()
* mbed_sdk_init() is also a function that is called before main(), but unlike
* mbed_main(), it is not meant for user code, but for the SDK itself to perform
* initializations before main() is called.
*/
WEAK void mbed_main(void) {
}
/* This function can be implemented by the target to perform higher level target initialization, before the mbed OS or
* RTX is started.
*/
void mbed_sdk_init(void);
WEAK void mbed_sdk_init(void) {
}
void mbed_start_main(void)
{
_main_thread_attr.stack_mem = _main_stack;
_main_thread_attr.stack_size = sizeof(_main_stack);
_main_thread_attr.cb_size = sizeof(_main_obj);
_main_thread_attr.cb_mem = &_main_obj;
_main_thread_attr.priority = osPriorityNormal;
_main_thread_attr.name = "MAIN";
osThreadId_t result = osThreadNew((osThreadFunc_t)pre_main, NULL, &_main_thread_attr);
if ((void *)result == NULL) {
error("Pre main thread not created");
}
osKernelStart();
}
/******************** Toolchain specific code ********************/
#if defined (__CC_ARM)
/* Common for both ARMC and MICROLIB */
int $Super$$main(void);
int $Sub$$main(void) {
mbed_main();
return $Super$$main();
}
#if defined (__MICROLIB) /******************** MICROLIB ********************/
int main(void);
void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
void $Super$$__cpp_initialize__aeabi_(void);
void _main_init (void) {
mbed_set_stack_heap();
/* Copy the vector table to RAM only if uVisor is not in use. */
#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
mbed_cpy_nvic();
#endif
mbed_sdk_init();
osKernelInitialize();
mbed_start_main();
for (;;);
}
void $Sub$$__cpp_initialize__aeabi_(void)
{
/* This should invoke C++ initializers prior _main_init, we keep this empty and
* invoke them after _main_init, when the RTX is already initilized.
*/
}
void pre_main()
{
singleton_mutex_attr.attr_bits = osMutexRecursive;
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
$Super$$__cpp_initialize__aeabi_();
main();
}
#else /******************** ARMC ********************/
#include <rt_misc.h>
extern __value_in_regs struct __argc_argv __rt_lib_init(unsigned heapbase, unsigned heaptop);
extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(void);
extern void _platform_post_stackheap_init (void);
extern int main(int argc, char* argv[]);
void pre_main (void)
{
singleton_mutex_attr.attr_bits = osMutexRecursive;
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
__rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size));
main(0, NULL);
}
/* The single memory model is checking for stack collision at run time, verifing
that the heap pointer is underneath the stack pointer.
With the RTOS there is not only one stack above the heap, there are multiple
stacks and some of them are underneath the heap pointer.
*/
#pragma import(__use_two_region_memory)
/* Called by the C library */
void __rt_entry (void) {
__user_setup_stackheap();
mbed_set_stack_heap();
/* Copy the vector table to RAM only if uVisor is not in use. */
#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
mbed_cpy_nvic();
#endif
mbed_sdk_init();
_platform_post_stackheap_init();
mbed_start_main();
}
#endif /* ARMC */
#elif defined (__GNUC__) /******************** GCC ********************/
extern int main(int argc, char* argv[]);
extern void __libc_init_array (void);
extern int __real_main(void);
osMutexId_t malloc_mutex_id;
mbed_rtos_storage_mutex_t malloc_mutex_obj;
osMutexAttr_t malloc_mutex_attr;
osMutexId_t env_mutex_id;
mbed_rtos_storage_mutex_t env_mutex_obj;
osMutexAttr_t env_mutex_attr;
#ifdef FEATURE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif/* FEATURE_UVISOR */
int __wrap_main(void) {
mbed_main();
return __real_main();
}
void pre_main(void)
{
singleton_mutex_attr.attr_bits = osMutexRecursive;
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
malloc_mutex_attr.attr_bits = osMutexRecursive;
malloc_mutex_attr.cb_size = sizeof(malloc_mutex_obj);
malloc_mutex_attr.cb_mem = &malloc_mutex_obj;
malloc_mutex_id = osMutexNew(&malloc_mutex_attr);
env_mutex_attr.attr_bits = osMutexRecursive;
env_mutex_attr.cb_size = sizeof(env_mutex_obj);
env_mutex_attr.cb_mem = &env_mutex_obj;
env_mutex_id = osMutexNew(&env_mutex_attr);
__libc_init_array();
main(0, NULL);
}
void software_init_hook(void)
{
mbed_set_stack_heap();
/* Copy the vector table to RAM only if uVisor is not in use. */
#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
mbed_cpy_nvic();
#endif
mbed_sdk_init();
osKernelInitialize();
/* uvisor_lib_init calls RTOS functions, so must be called after the RTOS has
* been initialized. */
#ifdef FEATURE_UVISOR
int return_code;
return_code = uvisor_lib_init();
if (return_code) {
mbed_die();
}
#endif/* FEATURE_UVISOR */
mbed_start_main();
}
/* Opaque declaration of _reent structure */
struct _reent;
void __rtos_malloc_lock( struct _reent *_r )
{
osMutexAcquire(malloc_mutex_id, osWaitForever);
}
void __rtos_malloc_unlock( struct _reent *_r )
{
osMutexRelease(malloc_mutex_id);
}
void __rtos_env_lock( struct _reent *_r )
{
osMutexAcquire(env_mutex_id, osWaitForever);
}
void __rtos_env_unlock( struct _reent *_r )
{
osMutexRelease(env_mutex_id);
}
#endif
#if defined(TOOLCHAIN_IAR) /******************** IAR ********************/
extern void* __vector_table;
extern int __low_level_init(void);
extern void __iar_data_init3(void);
extern __weak void __iar_init_core( void );
extern __weak void __iar_init_vfp( void );
extern void __iar_dynamic_initialization(void);
extern void mbed_sdk_init(void);
extern int main(void);
extern void exit(int arg);
static uint8_t low_level_init_needed;
void pre_main(void)
{
singleton_mutex_attr.attr_bits = osMutexRecursive;
singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
if (low_level_init_needed) {
__iar_dynamic_initialization();
}
mbed_main();
main();
}
#pragma required=__vector_table
void __iar_program_start( void )
{
__iar_init_core();
__iar_init_vfp();
uint8_t low_level_init_needed_local;
low_level_init_needed_local = __low_level_init();
if (low_level_init_needed_local) {
__iar_data_init3();
/* Copy the vector table to RAM only if uVisor is not in use. */
#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
mbed_cpy_nvic();
#endif
mbed_sdk_init();
}
mbed_set_stack_heap();
/* Store in a global variable after RAM has been initialized */
low_level_init_needed = low_level_init_needed_local;
osKernelInitialize();
mbed_start_main();
}
/* Thread safety */
static osMutexId_t std_mutex_id_sys[_MAX_LOCK] = {0};
static mbed_rtos_storage_mutex_t std_mutex_sys[_MAX_LOCK] = {0};
#define _FOPEN_MAX 10
static osMutexId_t std_mutex_id_file[_FOPEN_MAX] = {0};
static mbed_rtos_storage_mutex_t std_mutex_file[_FOPEN_MAX] = {0};
void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */
{
osMutexAttr_t attr;
uint32_t index;
for (index = 0; index < _MAX_LOCK; index++) {
if (0 == std_mutex_id_sys[index]) {
attr.cb_mem = &std_mutex_sys[index];
attr.cb_size = sizeof(std_mutex_sys[index]);
attr.attr_bits = osMutexRecursive;
std_mutex_id_sys[index] = osMutexNew(&attr);
*mutex = (__iar_Rmtx*)&std_mutex_id_sys[index];
return;
}
}
/* This should never happen */
error("Not enough mutexes\n");
}
void __iar_system_Mtxdst(__iar_Rmtx *mutex) /* Destroy a system lock */
{
osMutexDelete(*(osMutexId_t*)*mutex);
*mutex = 0;
}
void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */
{
osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever);
}
void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */
{
osMutexRelease(*(osMutexId_t*)*mutex);
}
void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */
{
osMutexAttr_t attr;
uint32_t index;
for (index = 0; index < _FOPEN_MAX; index++) {
if (0 == std_mutex_id_file[index]) {
attr.cb_mem = &std_mutex_file[index];
attr.cb_size = sizeof(std_mutex_file[index]);
attr.attr_bits = osMutexRecursive;
std_mutex_id_file[index] = osMutexNew(&attr);
*mutex = (__iar_Rmtx*)&std_mutex_id_file[index];
return;
}
}
/* The variable _FOPEN_MAX needs to be increased */
error("Not enough mutexes\n");
}
void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */
{
osMutexDelete(*(osMutexId_t*)*mutex);
*mutex = 0;
}
void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */
{
osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever);
}
void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */
{
osMutexRelease(*(osMutexId_t*)*mutex);
}
#endif

27
rtos/mbed_rtos1_types.h Normal file
View File

@ -0,0 +1,27 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2017 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MBED_RTOS_RTX1_TYPES_H
#define MBED_RTOS_RTX1_TYPES_H
#include "rtx/cmsis_os.h"
#endif

52
rtos/mbed_rtos_storage.h Normal file
View File

@ -0,0 +1,52 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2017 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MBED_RTOS_STORAGE_H
#define MBED_RTOS_STORAGE_H
/** \addtogroup rtos */
/** @{*/
/** @brief RTOS primitives storage types for RTX
Types defined in this file should be utilized, when the direct RTOS C API usage is required, to provide backing memory
for internal RTX data. Allocated object should be wrapped in attribute struct and passed to os*New call, for details
see CMSIS-RTOS2 documentation.
@note
This file breaks abstraction layers and uses RTX internal types, but it limits the contamination to single, RTOS
implementation specific, header file, therefore limiting scope of possible changes.
*/
#include "rtx_lib.h"
typedef os_mutex_t mbed_rtos_storage_mutex_t;
typedef os_semaphore_t mbed_rtos_storage_semaphore_t;
typedef os_thread_t mbed_rtos_storage_thread_t;
typedef os_memory_pool_t mbed_rtos_storage_mem_pool_t;
typedef os_message_queue_t mbed_rtos_storage_msg_queue_t;
typedef os_event_flags_t mbed_rtos_storage_event_flags_t;
typedef os_message_t mbed_rtos_storage_message_t;
typedef os_timer_t mbed_rtos_storage_timer_t;
#endif
/** @}*/

View File

@ -25,6 +25,9 @@
#ifndef RTOS_H
#define RTOS_H
#include "mbed_rtx.h"
#include "mbed_rtx_conf.h"
#include "mbed_rtos_storage.h"
#include "rtos/Thread.h"
#include "rtos/Mutex.h"
#include "rtos/RtosTimer.h"

54
rtos/rtx2/mbed_rtx_conf.h Normal file
View File

@ -0,0 +1,54 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2012 ARM Limited
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef MBED_RTX_CONF_H
#define MBED_RTX_CONF_H
#include "mbed_rtx.h"
#ifndef OS_STACK_SIZE
#ifndef MBED_SMALL_TARGET
#define OS_STACK_SIZE 4096
#else
#define OS_STACK_SIZE 2048
#endif
#endif
#define OS_TIMER_THREAD_STACK_SIZE 768
#define OS_IDLE_THREAD_STACK_SIZE 256
#define OS_DYNAMIC_MEM_SIZE 0
#if defined(__CC_ARM)
#define OS_MUTEX_OBJ_MEM 1
#define OS_MUTEX_NUM 6
#endif
#if !defined(OS_STACK_WATERMARK) && (defined(MBED_STACK_STATS_ENABLED) && MBED_STACK_STATS_ENABLED)
#define OS_STACK_WATERMARK 1
#endif
/* Run threads unprivileged when uVisor is enabled. */
#if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)
# define OS_PRIVILEGE_MODE 0
#endif
#endif /* MBED_RTX_CONF_H */

View File

@ -0,0 +1,38 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2016 ARM Limited
*
* 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.
*/
#include "cmsis_compiler.h"
#include "rtx_os.h"
#include "mbed_rtx.h"
#include "mbed_error.h"
extern void rtos_idle_loop(void);
__NO_RETURN void osRtxIdleThread (void *argument)
{
for (;;) {
rtos_idle_loop();
}
}
__NO_RETURN uint32_t osRtxErrorNotify (uint32_t code, void *object_id)
{
osThreadId_t tid = osThreadGetId();
error("CMSIS-RTOS error status: 0x%X, task ID: 0x%X\n\r", code, tid);
/* That shouldn't be reached */
for (;;) {}
}

View File

@ -22,9 +22,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 7
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif

View File

@ -22,9 +22,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -37,9 +34,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -52,9 +46,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20010000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -67,9 +58,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20030000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -82,9 +70,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20003000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -97,9 +82,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20006000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -112,9 +94,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20000C00UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -127,9 +106,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20003000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -142,9 +118,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20003000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -157,9 +130,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20006000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -172,9 +142,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20012000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -192,9 +159,6 @@
#define ISR_STACK_SIZE (0x1000)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -207,9 +171,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -237,9 +198,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20030000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif

View File

@ -22,9 +22,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -37,9 +34,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -52,12 +46,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20040000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
#ifndef OS_CLOCK
#define OS_CLOCK 48000000
#endif
@ -67,12 +55,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20028000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
#ifndef OS_CLOCK
#define OS_CLOCK 96000000
#endif

View File

@ -103,9 +103,6 @@ __STATIC_INLINE void errata_20(void)
#endif
}
#if (defined (__ICCARM__)) && defined(TARGET_MCU_NRF51822)//IAR
__stackless __task
#endif
void RTC1_IRQHandler(void);
void common_rtc_init(void)
@ -299,169 +296,70 @@ void us_ticker_clear_interrupt(void)
*/
static uint32_t previous_tick_cc_value = 0;
/* The Period of RTC oscillator, unit [1/RTC1_CONFIG_FREQUENCY] */
static uint32_t os_rtc_period;
/* Variable for frozen RTC1 counter value. It is used when system timer is disabled. */
static uint32_t frozen_sub_tick = 0;
/*
RTX provide the following definitions which are used by the tick code:
* os_trv: The number (minus 1) of clock cycle between two tick.
* os_clockrate: Time duration between two ticks (in us).
* OS_Tick_Handler: The function which handle a tick event.
* osRtxConfig.tick_freq: The RTX tick frequency.
* osRtxInfo.kernel.tick: Count of RTX ticks.
* SysTick_Handler: The function which handle a tick event.
This function is special because it never returns.
Those definitions are used by the code which handle the os tick.
To allow compilation of us_ticker programs without RTOS, those symbols are
exported from this module as weak ones.
*/
MBED_WEAK uint32_t const os_trv;
MBED_WEAK uint32_t const os_clockrate;
MBED_WEAK void OS_Tick_Handler(void)
MBED_WEAK void SysTick_Handler(void)
{
}
#if defined (__CC_ARM) /* ARMCC Compiler */
__asm void COMMON_RTC_IRQ_HANDLER(void)
{
IMPORT OS_Tick_Handler
IMPORT common_rtc_irq_handler
/**
* Chanel 1 of RTC1 is used by RTX as a systick.
* If the compare event on channel 1 is set, then branch to OS_Tick_Handler.
* Otherwise, just execute common_rtc_irq_handler.
* This function has to be written in assembly and tagged as naked because OS_Tick_Handler
* will never return.
* A c function would put lr on the stack before calling OS_Tick_Handler and this value
* would never been dequeued.
*
* \code
* void COMMON_RTC_IRQ_HANDLER(void) {
if(NRF_RTC1->EVENTS_COMPARE[1]) {
// never return...
OS_Tick_Handler();
} else {
common_rtc_irq_handler();
}
}
* \endcode
*/
ldr r0,=0x40011144
ldr r1, [r0, #0]
cmp r1, #0
beq US_TICKER_HANDLER
bl OS_Tick_Handler
US_TICKER_HANDLER
push {r3, lr}
bl common_rtc_irq_handler
pop {r3, pc}
; ALIGN ;
}
#elif defined (__GNUC__) /* GNU Compiler */
__attribute__((naked)) void COMMON_RTC_IRQ_HANDLER(void)
{
/**
* Chanel 1 of RTC1 is used by RTX as a systick.
* If the compare event on channel 1 is set, then branch to OS_Tick_Handler.
* Otherwise, just execute common_rtc_irq_handler.
* This function has to be written in assembly and tagged as naked because OS_Tick_Handler
* will never return.
* A c function would put lr on the stack before calling OS_Tick_Handler and this value
* would never been dequeued.
*
* \code
* void COMMON_RTC_IRQ_HANDLER(void) {
if(NRF_RTC1->EVENTS_COMPARE[1]) {
// never return...
OS_Tick_Handler();
} else {
common_rtc_irq_handler();
}
}
* \endcode
*/
__asm__ (
"ldr r0,=0x40011144\n"
"ldr r1, [r0, #0]\n"
"cmp r1, #0\n"
"beq US_TICKER_HANDLER\n"
"bl OS_Tick_Handler\n"
"US_TICKER_HANDLER:\n"
"push {r3, lr}\n"
"bl common_rtc_irq_handler\n"
"pop {r3, pc}\n"
"nop"
);
}
#elif defined (__ICCARM__)//IAR
void common_rtc_irq_handler(void);
__stackless __task void COMMON_RTC_IRQ_HANDLER(void)
{
uint32_t temp;
__asm volatile(
" ldr %[temp], [%[reg2check]] \n"
" cmp %[temp], #0 \n"
" beq 1f \n"
" bl.w OS_Tick_Handler \n"
"1: \n"
" push {r3, lr}\n"
" blx %[rtc_irq] \n"
" pop {r3, pc}\n"
: /* Outputs */
[temp] "=&r"(temp)
: /* Inputs */
[reg2check] "r"(0x40011144),
[rtc_irq] "r"(common_rtc_irq_handler)
: /* Clobbers */
"cc"
);
(void)temp;
}
#else
#error Compiler not supported.
#error Provide a definition of COMMON_RTC_IRQ_HANDLER.
/*
* Chanel 1 of RTC1 is used by RTX as a systick.
* If the compare event on channel 1 is set, then branch to OS_Tick_Handler.
* Otherwise, just execute common_rtc_irq_handler.
* This function has to be written in assembly and tagged as naked because OS_Tick_Handler
* will never return.
* A c function would put lr on the stack before calling OS_Tick_Handler and this value
* will never been dequeued. After a certain time a stack overflow will happen.
*
* \code
* void COMMON_RTC_IRQ_HANDLER(void) {
if(NRF_RTC1->EVENTS_COMPARE[1]) {
// never return...
OS_Tick_Handler();
} else {
common_rtc_irq_handler();
}
}
* \endcode
*/
#ifdef MBED_CONF_RTOS_PRESENT
#include "rtx_os.h" //import osRtxInfo, SysTick_Handler()
static inline void clear_tick_interrupt();
#endif
#ifndef RTC1_CONFIG_FREQUENCY
#define RTC1_CONFIG_FREQUENCY 32678 // [Hz]
#endif
void COMMON_RTC_IRQ_HANDLER(void)
{
if(nrf_rtc_event_pending(COMMON_RTC_INSTANCE, OS_TICK_EVENT)) {
#ifdef MBED_CONF_RTOS_PRESENT
clear_tick_interrupt();
// Trigger the SysTick_Handler just after exit form RTC Handler.
NVIC_SetPendingIRQ(SWI3_IRQn);
nrf_gpio_pin_set(11);
#endif
} else {
common_rtc_irq_handler();
}
}
#ifdef MBED_CONF_RTOS_PRESENT
/**
* Return the next number of clock cycle needed for the next tick.
* @note This function has been carrefuly optimized for a systick occuring every 1000us.
* @note This function has been carefully optimized for a systick occurring every 1000us.
*/
static uint32_t get_next_tick_cc_delta()
{
uint32_t delta = 0;
if (os_clockrate != 1000) {
if (osRtxConfig.tick_freq != 1000) {
// In RTX, by default SYSTICK is is used.
// A tick event is generated every os_trv + 1 clock cycles of the system timer.
delta = os_trv + 1;
delta = os_rtc_period;
} else {
// If the clockrate is set to 1000us then 1000 tick should happen every second.
// Unfortunatelly, when clockrate is set to 1000, os_trv is equal to 31.
@ -556,82 +454,89 @@ static void register_next_tick()
__enable_irq();
}
/**
* Initialize alternative hardware timer as RTX kernel timer
* This function is directly called by RTX.
* @note this function shouldn't be called directly.
* @return IRQ number of the alternative hardware timer
*/
int os_tick_init (void)
int32_t osRtxSysTimerSetup(void)
{
common_rtc_init();
nrf_rtc_int_enable(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK);
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL, 0);
register_next_tick();
os_rtc_period = (RTC1_CONFIG_FREQUENCY) / osRtxConfig.tick_freq;
return nrf_drv_get_IRQn(COMMON_RTC_INSTANCE);
}
// Start SysTickt timer emulation
void osRtxSysTimerEnable(void)
{
nrf_rtc_int_enable(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK);
uint32_t current_cnt = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL, current_cnt);
register_next_tick();
NVIC_SetVector(SWI3_IRQn, (uint32_t)SysTick_Handler);
NVIC_SetPriority(SWI3_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Emulated Systick Interrupt */
NVIC_EnableIRQ(SWI3_IRQn);
}
// Stop SysTickt timer emulation
void osRtxSysTimerDisable(void)
{
nrf_rtc_int_disable(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK);
// RTC1 is free runing. osRtxSysTimerGetCount will return proper frozen value
// thanks to geting frozen value instead of RTC1 counter value
frozen_sub_tick = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
}
/**
* Acknowledge the tick interrupt.
* This function is called by the function OS_Tick_Handler of RTX.
* @note this function shouldn't be called directly.
*/
void os_tick_irqack(void)
void osRtxSysTimerAckIRQ(void)
{
clear_tick_interrupt();
register_next_tick();
}
/**
* Returns the overflow flag of the alternative hardware timer.
* @note This function is exposed by RTX kernel.
* @return 1 if the timer has overflowed and 0 otherwise.
*/
uint32_t os_tick_ovf(void)
// provide a free running incremental value over the entire 32-bit range
uint32_t osRtxSysTimerGetCount(void)
{
uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
uint32_t next_tick_cc_value = nrf_rtc_cc_get(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL);
uint32_t current_cnt;
uint32_t sub_tick;
return is_in_wrapped_range(previous_tick_cc_value, next_tick_cc_value, current_counter) ? 0 : 1;
}
/**
* Return the value of the alternative hardware timer.
* @note The documentation is not very clear about what is expected as a result,
* is it an ascending counter, a descending one ?
* None of this is specified.
* The default systick is a descending counter and this function return values in
* descending order, even if the internal counter used is an ascending one.
* @return the value of the alternative hardware timer.
*/
uint32_t os_tick_val(void)
{
uint32_t current_counter = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
uint32_t next_tick_cc_value = nrf_rtc_cc_get(COMMON_RTC_INSTANCE, OS_TICK_CC_CHANNEL);
// do not use os_tick_ovf because its counter value can be different
if(is_in_wrapped_range(previous_tick_cc_value, next_tick_cc_value, current_counter)) {
if (next_tick_cc_value > previous_tick_cc_value) {
return next_tick_cc_value - current_counter;
} else if(current_counter <= next_tick_cc_value) {
return next_tick_cc_value - current_counter;
if (nrf_rtc_int_is_enabled(COMMON_RTC_INSTANCE, OS_TICK_INT_MASK)) {
// system timer is enabled
current_cnt = nrf_rtc_counter_get(COMMON_RTC_INSTANCE);
if (current_cnt >= previous_tick_cc_value) {
//0 prev current MAX
//|------|---------|------------|---->
sub_tick = current_cnt - previous_tick_cc_value;
} else {
return next_tick_cc_value + (MAX_RTC_COUNTER_VAL - current_counter);
//0 current prev MAX
//|------|---------|------------|---->
sub_tick = MAX_RTC_COUNTER_VAL - previous_tick_cc_value + current_cnt;
}
} else {
// use (os_trv + 1) has the base step, can be totally inacurate ...
uint32_t clock_cycles_by_tick = os_trv + 1;
// if current counter has wrap arround, add the limit to it.
if (current_counter < next_tick_cc_value) {
current_counter = current_counter + MAX_RTC_COUNTER_VAL;
}
return clock_cycles_by_tick - ((current_counter - next_tick_cc_value) % clock_cycles_by_tick);
} else { // system timer is disabled
sub_tick = frozen_sub_tick;
}
return (os_rtc_period * osRtxInfo.kernel.tick) + sub_tick;
}
// Timer Tick frequency
uint32_t osRtxSysTimerGetFreq (void) {
return RTC1_CONFIG_FREQUENCY;
}
#endif // #ifdef MBED_CONF_RTOS_PRESENT
#endif // defined(TARGET_MCU_NRF51822)

View File

@ -27,9 +27,6 @@
# endif
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 7
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 512
#endif
@ -45,9 +42,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20010000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 7
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 512
#endif

View File

@ -17,11 +17,10 @@
#ifndef MBED_MBED_RTX_H
#define MBED_MBED_RTX_H
#include <stdint.h>
#if defined(TARGET_NUMAKER_PFM_NUC472)
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -55,9 +54,6 @@
#elif defined(TARGET_NUMAKER_PFM_M453)
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif

View File

@ -22,9 +22,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -40,9 +37,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -55,9 +49,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10001000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -70,9 +61,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -85,9 +73,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x02009000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -100,9 +85,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -115,9 +97,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10010000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -130,7 +109,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10008000UL)
#endif
#define OS_TASKCNT 14
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -143,9 +121,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10001000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -158,9 +133,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x10002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif

View File

@ -22,9 +22,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x40000000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif

View File

@ -22,9 +22,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -37,9 +34,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -52,9 +46,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20004000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -67,9 +58,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20004000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -82,9 +70,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -97,9 +82,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -112,9 +94,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20005000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -127,9 +106,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -142,9 +118,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x2000A000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -157,9 +130,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20003000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -172,9 +142,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20004000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -187,9 +154,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20003000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -202,9 +166,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20010000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -217,9 +178,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20010000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -232,9 +190,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20003000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -247,9 +202,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -262,9 +214,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20010000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -277,9 +226,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20030000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -292,9 +238,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20030000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 512
#endif
@ -322,9 +265,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20050000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -337,9 +277,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -352,9 +289,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20018000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -367,9 +301,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -382,9 +313,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 1024
#endif
@ -397,9 +325,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -427,9 +352,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -442,9 +364,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -457,9 +376,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -472,9 +388,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20050000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -487,9 +400,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20050000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -502,9 +412,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20080000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -517,9 +424,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20080000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -532,9 +436,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -547,9 +448,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -562,9 +460,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -592,9 +487,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20005000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -607,9 +499,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -622,9 +511,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20014000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -637,9 +523,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -652,9 +535,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -667,9 +547,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20018000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -682,9 +559,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x2000C000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -697,9 +571,6 @@
#ifndef INITIAL_SP
#define INITIAL_SP (0x20018000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif

View File

@ -17,6 +17,7 @@
#ifndef MBED_MBED_RTX_H
#define MBED_MBED_RTX_H
#include <stdint.h>
#include "clocking.h"
#ifndef OS_CLOCK
@ -43,9 +44,6 @@ extern uint32_t STACK$$Base;
#define INITIAL_SP (0x20020000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 256
#endif
@ -56,9 +54,6 @@ extern uint32_t STACK$$Base;
#define INITIAL_SP (0x20002000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 112
#endif
@ -69,9 +64,6 @@ extern uint32_t STACK$$Base;
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -82,9 +74,6 @@ extern uint32_t STACK$$Base;
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif
@ -95,9 +84,6 @@ extern uint32_t STACK$$Base;
#define INITIAL_SP (0x20008000UL)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 14
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif

View File

@ -23,9 +23,6 @@
#define INITIAL_SP (0x01000000 + 0x05000 - 256)
#endif
#ifndef OS_TASKCNT
#define OS_TASKCNT 6
#endif
#ifndef OS_MAINSTKSIZE
#define OS_MAINSTKSIZE 128
#endif