mirror of https://github.com/ARMmbed/mbed-os.git
parent
b97ffe8fdc
commit
b793a3fb89
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *)>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#ifndef __BLE_IBEACON_H__
|
||||
#define __BLE_IBEACON_H__
|
||||
|
||||
#include "core_cmInstr.h"
|
||||
#include "cmsis_compiler.h"
|
||||
#include "ble/BLE.h"
|
||||
|
||||
/**
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
//#define LWIP_DEBUG
|
||||
|
||||
#if NO_SYS == 0
|
||||
#include "cmsis_os.h"
|
||||
#include "cmsis_os2.h"
|
||||
|
||||
#define SYS_LIGHTWEIGHT_PROT 1
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
52
rtos/Mail.h
52
rtos/Mail.h
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
22
rtos/Mutex.h
22
rtos/Mutex.h
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
65
rtos/Queue.h
65
rtos/Queue.h
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
280
rtos/Thread.cpp
280
rtos/Thread.cpp
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
119
rtos/Thread.h
119
rtos/Thread.h
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
/** @}*/
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
|
@ -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 (;;) {}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue