Skip to content

Commit

Permalink
Merge pull request #6364 from ARMmbed/release-candidate
Browse files Browse the repository at this point in the history
 Release candidate for mbed-os-5.7.7
  • Loading branch information
cmonr committed Mar 15, 2018
2 parents 91e6db1 + bf8854e commit 16bac10
Show file tree
Hide file tree
Showing 191 changed files with 6,203 additions and 2,334 deletions.
20 changes: 15 additions & 5 deletions .github/pull_request_template.md
@@ -1,11 +1,21 @@
# Description
### Description

> Detailed changes summary | testing | dependencies
> Good example: https://os.mbed.com/docs/latest/reference/guidelines.html#workflow (Pull request template)
<!--
Required
Add here detailed changes summary, testing results, dependencies
Good example: https://os.mbed.com/docs/latest/reference/guidelines.html#workflow (Pull request template)
-->

# Pull request type

### Pull request type

<!--
Required
Please tick one of the following types
-->

- [ ] Fix
- [ ] Refactor
- [ ] New Target
- [ ] New target
- [ ] Feature
- [ ] Breaking change
219 changes: 219 additions & 0 deletions TESTS/mbed_drivers/timerevent/main.cpp
@@ -0,0 +1,219 @@
/* 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.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"
#include "drivers/TimerEvent.h"
#include "hal/ticker_api.h"
#include "rtos.h"

using namespace utest::v1;

#define TEST_DELAY_US 50000ULL

class TestTimerEvent: public TimerEvent {
private:
Semaphore sem;
virtual void handler() {
sem.release();
}

public:
TestTimerEvent() :
TimerEvent(), sem(0, 1) {
}

TestTimerEvent(const ticker_data_t *data) :
TimerEvent(data), sem(0, 1) {
}

virtual ~TestTimerEvent() {
}

// Make these methods publicly accessible
using TimerEvent::insert;
using TimerEvent::insert_absolute;
using TimerEvent::remove;

int32_t sem_wait(uint32_t millisec) {
return sem.wait(millisec);
}
};

class TestTimerEventRelative: public TestTimerEvent {
public:
static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 0;
TestTimerEventRelative() :
TestTimerEvent() {
}

TestTimerEventRelative(const ticker_data_t *data) :
TestTimerEvent(data) {
}

// Set relative timestamp of internal event to present_time + ts
void set_future_timestamp(timestamp_t ts) {
insert(::ticker_read(_ticker_data) + ts);
}

void set_past_timestamp(void) {
insert(::ticker_read(_ticker_data) - 1UL);
}
};

class TestTimerEventAbsolute: public TestTimerEvent {
public:
static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 1;
TestTimerEventAbsolute() :
TestTimerEvent() {
}

TestTimerEventAbsolute(const ticker_data_t *data) :
TestTimerEvent(data) {
}

// Set absolute timestamp of internal event to present_time + ts
void set_future_timestamp(us_timestamp_t ts) {
insert_absolute(::ticker_read_us(_ticker_data) + ts);
}

void set_past_timestamp(void) {
insert_absolute(::ticker_read_us(_ticker_data) - 1ULL);
}
};

/** Template for tests: insert, insert_absolute
*
* Test insert
* Given an instance of @a TimerEvent subclass
* When a tiestamp is set with @a insert()
* and given time elapses
* Then an event handler is called
*
* Test insert_absolute
* Given an instance of @a TimerEvent subclass
* When a tiestamp is set with @a insert_absolute()
* and given time elapses
* Then an event handler is called
*/
template<typename T>
void test_insert(void) {
T tte;

tte.set_future_timestamp(TEST_DELAY_US);
int32_t sem_slots = tte.sem_wait(0);
TEST_ASSERT_EQUAL(0, sem_slots);

sem_slots = tte.sem_wait(TEST_DELAY_US / 1000 + 1);
TEST_ASSERT_EQUAL(1, sem_slots);

tte.remove();
}

/** Template for tests: remove
*
* Test remove after insert
* Given an instance of @a TimerEvent subclass
* When a tiestamp is set with @a insert()
* and timestamp is removed before being reached
* Then the event handler is never called
*
* Test remove after insert_absolute
* Given an instance of @a TimerEvent subclass
* When a tiestamp is set with @a insert_absolute()
* and timestamp is removed before being reached
* Then the event handler is never called
*/
template<typename T>
void test_remove(void) {
T tte;

tte.set_future_timestamp(TEST_DELAY_US * 2);
int32_t sem_slots = tte.sem_wait(TEST_DELAY_US / 1000);
TEST_ASSERT_EQUAL(0, sem_slots);
tte.remove();

sem_slots = tte.sem_wait(TEST_DELAY_US * 2 / 1000 + 1);
TEST_ASSERT_EQUAL(0, sem_slots);
}

/** Test insert_absolute zero
* Given an instance of @a TimerEvent subclass
* When a timestamp of 0 us is set with @a insert_absolute()
* Then an event handler is called instantly
*/
void test_insert_zero(void) {
TestTimerEvent tte;

tte.insert_absolute(0ULL);
int32_t sem_slots = tte.sem_wait(0);
TEST_ASSERT_EQUAL(1, sem_slots);

tte.remove();
}

/** Template for tests: insert, insert_absolute past timestamp
*
* Test insert timestamp from the past
* Given an instance of @a TimerEvent subclass
* When a timestamp of X us is set with @a insert()
* and X is less than present_time
* Then an event handler is **not** called instantly
* (the event is scheduled after the ticker's overflow)
*
* Test insert_absolute timestamp from the past
* Given an instance of @a TimerEvent subclass
* When a timestamp of X us is set with @a insert_absolute()
* and X is less than present_time
* Then an event handler is called instantly
*/
template<typename T>
void test_insert_past(void) {
T tte;

tte.set_past_timestamp();
int32_t sem_slots = tte.sem_wait(0);
TEST_ASSERT_EQUAL(tte.SEM_SLOTS_AFTER_PAST_TS_INSERTED, sem_slots);

tte.remove();
}

utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(5, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}

Case cases[] = {
Case("Test insert", test_insert<TestTimerEventRelative>),
Case("Test insert_absolute", test_insert<TestTimerEventAbsolute>),

Case("Test remove after insert", test_remove<TestTimerEventRelative>),
Case("Test remove after insert_absolute", test_remove<TestTimerEventAbsolute>),

Case("Test insert_absolute zero", test_insert_zero),

Case("Test insert timestamp from the past", test_insert_past<TestTimerEventRelative>),
Case("Test insert_absolute timestamp from the past", test_insert_past<TestTimerEventAbsolute>),
};

Specification specification(test_setup, cases);

int main()
{
return !Harness::run(specification);
}
6 changes: 3 additions & 3 deletions TESTS/mbed_hal/flash/functional_tests/main.cpp
Expand Up @@ -27,8 +27,8 @@

using namespace utest::v1;

#define TEST_CYCLES 1000000
#define ALLOWED_DRIFT_PPM 5000 //0.5%
#define TEST_CYCLES 10000000
#define ALLOWED_DRIFT_PPM (1000000/5000) //0.5%

/*
return values to be checked are documented at:
Expand Down Expand Up @@ -269,7 +269,7 @@ void flash_buffer_alignment_test()
void flash_clock_and_cache_test()
{
const int timer_diff_end = time_cpu_cycles(TEST_CYCLES);
const int acceptable_range = timer_diff_start / (1000000 / ALLOWED_DRIFT_PPM);
const int acceptable_range = timer_diff_start / (ALLOWED_DRIFT_PPM);
TEST_ASSERT_UINT32_WITHIN(acceptable_range, timer_diff_start, timer_diff_end);
}

Expand Down
24 changes: 21 additions & 3 deletions drivers/TimerEvent.h
Expand Up @@ -47,13 +47,31 @@ class TimerEvent : private NonCopyable<TimerEvent> {
// The handler called to service the timer event of the derived class
virtual void handler() = 0;

// insert relative timestamp in to linked list
/** Set relative timestamp of the internal event.
* @param timestamp event's us timestamp
*
* @warning
* Do not insert more than one timestamp.
* The same @a event object is used for every @a insert/insert_absolute call.
*
* @warning
* Ticker's present timestamp is used for reference. For timestamps
* from the past the event is scheduled after ticker's overflow.
* For reference @see convert_timestamp
*/
void insert(timestamp_t timestamp);

// insert absolute timestamp into linked list
/** Set absolute timestamp of the internal event.
* @param timestamp event's us timestamp
*
* @warning
* Do not insert more than one timestamp.
* The same @a event object is used for every @a insert/insert_absolute call.
*/
void insert_absolute(us_timestamp_t timestamp);

// remove from linked list, if in it
/** Remove timestamp.
*/
void remove();

ticker_event_t event;
Expand Down
4 changes: 2 additions & 2 deletions events/equeue/equeue.c
Expand Up @@ -37,7 +37,7 @@ static inline int equeue_clampdiff(unsigned a, unsigned b) {
// Increment the unique id in an event, hiding the event from cancel
static inline void equeue_incid(equeue_t *q, struct equeue_event *e) {
e->id += 1;
if (!(e->id << q->npw2)) {
if ((e->id << q->npw2) == 0) {
e->id = 1;
}
}
Expand Down Expand Up @@ -469,7 +469,7 @@ void equeue_event_dtor(void *p, void (*dtor)(void *)) {
}


// simple callbacks
// simple callbacks
struct ecallback {
void (*cb)(void*);
void *data;
Expand Down
44 changes: 22 additions & 22 deletions features/filesystem/littlefs/littlefs/lfs.c
Expand Up @@ -724,6 +724,19 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
pathname += strspn(pathname, "/");
pathlen = strcspn(pathname, "/");

// special case for root dir
if (pathname[0] == '\0') {
*entry = (lfs_entry_t){
.d.type = LFS_TYPE_DIR,
.d.elen = sizeof(entry->d) - 4,
.d.alen = 0,
.d.nlen = 0,
.d.u.dir[0] = lfs->root[0],
.d.u.dir[1] = lfs->root[1],
};
return 0;
}

// skip '.' and root '..'
if ((pathlen == 1 && memcmp(pathname, ".", 1) == 0) ||
(pathlen == 2 && memcmp(pathname, "..", 2) == 0)) {
Expand Down Expand Up @@ -880,15 +893,6 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
return err;
}

// check for root, can only be something like '/././../.'
if (strspn(path, "/.") == strlen(path)) {
dir->head[0] = dir->pair[0];
dir->head[1] = dir->pair[1];
dir->pos = sizeof(dir->d) - 2;
dir->off = sizeof(dir->d);
return 0;
}

lfs_entry_t entry;
err = lfs_dir_find(lfs, dir, &entry, &path);
if (err) {
Expand Down Expand Up @@ -1671,14 +1675,6 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {

/// General fs oprations ///
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
// check for root, can only be something like '/././../.'
if (strspn(path, "/.") == strlen(path)) {
memset(info, 0, sizeof(*info));
info->type = LFS_TYPE_DIR;
strcpy(info->name, "/");
return 0;
}

lfs_dir_t cwd;
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
if (err) {
Expand All @@ -1697,11 +1693,15 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
info->size = entry.d.u.file.size;
}

err = lfs_bd_read(lfs, cwd.pair[0],
entry.off + 4+entry.d.elen+entry.d.alen,
info->name, entry.d.nlen);
if (err) {
return err;
if (lfs_paircmp(entry.d.u.dir, lfs->root) == 0) {
strcpy(info->name, "/");
} else {
err = lfs_bd_read(lfs, cwd.pair[0],
entry.off + 4+entry.d.elen+entry.d.alen,
info->name, entry.d.nlen);
if (err) {
return err;
}
}

return 0;
Expand Down

0 comments on commit 16bac10

Please sign in to comment.