Skip to content

Release candidate for mbed-os-5.3.6 #3837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Feb 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TESTS/events/queue/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ SIMPLE_POSTS_TEST(0)


void time_func(Timer *t, int ms) {
TEST_ASSERT_INT_WITHIN(2, ms, t->read_ms());
TEST_ASSERT_INT_WITHIN(5, ms, t->read_ms());
t->reset();
}

Expand Down
122 changes: 122 additions & 0 deletions TESTS/events/timing/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include "mbed_events.h"
#include "mbed.h"
#include "rtos.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include <cstdlib>
#include <cmath>

using namespace utest::v1;


// Test delay
#ifndef TEST_EVENTS_TIMING_TIME
#define TEST_EVENTS_TIMING_TIME 20000
#endif

#ifndef TEST_EVENTS_TIMING_MEAN
#define TEST_EVENTS_TIMING_MEAN 25
#endif

#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif

// Random number generation to skew timing values
float gauss(float mu, float sigma) {
float x = (float)rand() / ((float)RAND_MAX+1);
float y = (float)rand() / ((float)RAND_MAX+1);
float x2pi = x*2.0*M_PI;
float g2rad = sqrt(-2.0 * log(1.0-y));
float z = cos(x2pi) * g2rad;
return mu + z*sigma;
}

float chisq(float sigma) {
return pow(gauss(0, sqrt(sigma)), 2);
}


Timer timer;
DigitalOut led(LED1);

equeue_sema_t sema;

// Timer timing test
void timer_timing_test() {
timer.reset();
timer.start();
int prev = timer.read_us();

while (prev < TEST_EVENTS_TIMING_TIME*1000) {
int next = timer.read_us();
if (next < prev) {
printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
prev, next, prev, next);
}
TEST_ASSERT(next >= prev);
prev = next;
}
}

// equeue tick timing test
void tick_timing_test() {
unsigned start = equeue_tick();
int prev = 0;

while (prev < TEST_EVENTS_TIMING_TIME) {
int next = equeue_tick() - start;
if (next < prev) {
printf("backwards drift %d -> %d (%08x -> %08x)\r\n",
prev, next, prev, next);
}
TEST_ASSERT(next >= prev);
prev = next;
}
}

// equeue semaphore timing test
void semaphore_timing_test() {
srand(0);
timer.reset();
timer.start();

int err = equeue_sema_create(&sema);
TEST_ASSERT_EQUAL(0, err);

while (timer.read_ms() < TEST_EVENTS_TIMING_TIME) {
int delay = chisq(TEST_EVENTS_TIMING_MEAN);

int start = timer.read_us();
equeue_sema_wait(&sema, delay);
int taken = timer.read_us() - start;

printf("delay %dms => error %dus\r\n", delay, abs(1000*delay - taken));
TEST_ASSERT_INT_WITHIN(5000, taken, delay * 1000);

led = !led;
}

equeue_sema_destroy(&sema);
}


// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP((number_of_cases+1)*TEST_EVENTS_TIMING_TIME, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}

const Case cases[] = {
Case("Testing accuracy of timer", timer_timing_test),
Case("Testing accuracy of equeue tick", tick_timing_test),
Case("Testing accuracy of equeue semaphore", semaphore_timing_test),
};

Specification specification(test_setup, cases);

int main() {
return !Harness::run(specification);
}

17 changes: 12 additions & 5 deletions events/equeue/equeue_mbed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@

// Ticker operations
static bool equeue_tick_inited = false;
static unsigned equeue_minutes = 0;
static volatile unsigned equeue_minutes = 0;
static unsigned equeue_timer[
(sizeof(Timer)+sizeof(unsigned)-1)/sizeof(unsigned)];
static unsigned equeue_ticker[
(sizeof(Ticker)+sizeof(unsigned)-1)/sizeof(unsigned)];

static void equeue_tick_update() {
equeue_minutes += reinterpret_cast<Timer*>(equeue_timer)->read_ms();
reinterpret_cast<Timer*>(equeue_timer)->reset();
equeue_minutes += 1;
}

static void equeue_tick_init() {
Expand All @@ -48,7 +48,7 @@ static void equeue_tick_init() {
equeue_minutes = 0;
reinterpret_cast<Timer*>(equeue_timer)->start();
reinterpret_cast<Ticker*>(equeue_ticker)
->attach_us(equeue_tick_update, (1 << 16)*1000);
->attach_us(equeue_tick_update, 1000 << 16);

equeue_tick_inited = true;
}
Expand All @@ -58,8 +58,15 @@ unsigned equeue_tick() {
equeue_tick_init();
}

unsigned equeue_ms = reinterpret_cast<Timer*>(equeue_timer)->read_ms();
return (equeue_minutes << 16) + equeue_ms;
unsigned minutes;
unsigned ms;

do {
minutes = equeue_minutes;
ms = reinterpret_cast<Timer*>(equeue_timer)->read_ms();
} while (minutes != equeue_minutes);

return minutes + ms;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ USBHAL::USBHAL(void) {
/* bulk/int 64 bytes in FS */
HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1);
/* bulk/int bytes in FS */
HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4));
HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1);
HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4));
/* ISOchronous */
HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ USBHAL::USBHAL(void) {
/* bulk/int 64 bytes in FS */
HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1);
/* bulk/int bytes in FS */
HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4));
HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1);
HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4));
/* ISOchronous */
HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ USBHAL::USBHAL(void) {
/* bulk/int 64 bytes in FS */
HAL_PCDEx_SetTxFiFo(&hpcd, 0, (MAX_PACKET_SIZE_EP0/4)+1);
/* bulk/int bytes in FS */
HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4));
HAL_PCDEx_SetTxFiFo(&hpcd, 1, (MAX_PACKET_SIZE_EP1/4)+1);
HAL_PCDEx_SetTxFiFo(&hpcd, 2, (MAX_PACKET_SIZE_EP2/4));
/* ISOchronous */
HAL_PCDEx_SetTxFiFo(&hpcd, 3, (MAX_PACKET_SIZE_EP3/4));
Expand Down
4 changes: 4 additions & 0 deletions features/unsupported/USBDevice/USBDevice/USBHAL.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
//#define __packed __attribute__ ((__packed__))
//#endif

#ifdef __GNUC__
#define __packed __attribute__ ((__packed__))
#endif

class USBHAL {
public:
/* Configuration */
Expand Down
4 changes: 2 additions & 2 deletions mbed.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
#ifndef MBED_H
#define MBED_H

#define MBED_LIBRARY_VERSION 136
#define MBED_LIBRARY_VERSION 137

#if MBED_CONF_RTOS_PRESENT
// RTOS present, this is valid only for mbed OS 5
#define MBED_MAJOR_VERSION 5
#define MBED_MINOR_VERSION 3
#define MBED_PATCH_VERSION 5
#define MBED_PATCH_VERSION 6

#else
// mbed 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
spi_master_config_t master_config;
spi_slave_config_t slave_config;

if ((bits != 8) || (bits != 16)) {
if ((bits != 8) && (bits != 16)) {
error("Only 8bits and 16bits SPI supported");
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void spi_format(spi_t *obj, int bits, int mode, int slave)
spi_master_config_t master_config;
spi_slave_config_t slave_config;

if ((bits != 8) || (bits != 16)) {
if ((bits != 8) && (bits != 16)) {
error("Only 8bits and 16bits SPI supported");
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,6 @@ struct pwmout_s {
};

struct sleep_s {
uint32_t start_us;
uint32_t end_us;
uint32_t period_us;
int powerdown;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@

#include "M451Series.h"
#include <errno.h>
#include "nu_miscutil.h"

extern uint32_t __mbed_sbrk_start;
extern uint32_t __mbed_krbs_start;

#define NU_HEAP_ALIGN 32

/**
* The default implementation of _sbrk() (in common/retarget.cpp) for GCC_ARM requires one-region model (heap and stack share one region), which doesn't
* fit two-region model (heap and stack are two distinct regions), for example, NUMAKER-PFM-NUC472 locates heap on external SRAM. Define __wrap__sbrk() to
Expand All @@ -23,8 +26,8 @@ extern uint32_t __mbed_krbs_start;
void *__wrap__sbrk(int incr)
{
static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start;
uint32_t heap_ind_old = heap_ind;
uint32_t heap_ind_new = (heap_ind_old + incr + 7) & ~7;
uint32_t heap_ind_old = NU_ALIGN_UP(heap_ind, NU_HEAP_ALIGN);
uint32_t heap_ind_new = NU_ALIGN_UP(heap_ind_old + incr, NU_HEAP_ALIGN);

if (heap_ind_new > &__mbed_krbs_start) {
errno = ENOMEM;
Expand Down
23 changes: 3 additions & 20 deletions targets/TARGET_NUVOTON/TARGET_M451/sleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
#include "objects.h"
#include "PeripheralPins.h"

void us_ticker_prepare_sleep(struct sleep_s *obj);
void us_ticker_wakeup_from_sleep(struct sleep_s *obj);
static void mbed_enter_sleep(struct sleep_s *obj);
static void mbed_exit_sleep(struct sleep_s *obj);

Expand Down Expand Up @@ -57,8 +55,7 @@ void deepsleep(void)
mbed_exit_sleep(&sleep_obj);
}


void mbed_enter_sleep(struct sleep_s *obj)
static void mbed_enter_sleep(struct sleep_s *obj)
{
// Check if serial allows entering power-down mode
if (obj->powerdown) {
Expand All @@ -77,16 +74,7 @@ void mbed_enter_sleep(struct sleep_s *obj)
obj->powerdown = pwmout_allow_powerdown();
}
// TODO: Check if other peripherals allow entering power-down mode

obj->start_us = lp_ticker_read();
// Let us_ticker prepare for power-down or reject it.
us_ticker_prepare_sleep(obj);

// NOTE(STALE): To pass mbed-drivers test, timer requires to be fine-grained, so its implementation needs HIRC rather than LIRC/LXT as its clock source.
// But as CLK_PowerDown()/CLK_Idle() is called, HIRC will be disabled and timer cannot keep counting and alarm. To overcome the dilemma,
// just make CPU halt and compromise power saving.
// NOTE: As CLK_PowerDown()/CLK_Idle() is called, HIRC/HXT will be disabled in normal mode, but not in ICE mode. This may cause confusion in development.


if (obj->powerdown) { // Power-down mode (HIRC/HXT disabled, LIRC/LXT enabled)
SYS_UnlockReg();
CLK_PowerDown();
Expand All @@ -101,14 +89,9 @@ void mbed_enter_sleep(struct sleep_s *obj)
__NOP();
__NOP();
__NOP();

obj->end_us = lp_ticker_read();
obj->period_us = (obj->end_us > obj->start_us) ? (obj->end_us - obj->start_us) : (uint32_t) ((uint64_t) obj->end_us + 0xFFFFFFFFu - obj->start_us);
// Let us_ticker recover from power-down.
us_ticker_wakeup_from_sleep(obj);
}

void mbed_exit_sleep(struct sleep_s *obj)
static void mbed_exit_sleep(struct sleep_s *obj)
{
// TODO: TO BE CONTINUED

Expand Down
Loading