Skip to content

Commit 16bac10

Browse files
authored
Merge pull request #6364 from ARMmbed/release-candidate
Release candidate for mbed-os-5.7.7
2 parents 91e6db1 + bf8854e commit 16bac10

File tree

191 files changed

+6203
-2334
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

191 files changed

+6203
-2334
lines changed

.github/pull_request_template.md

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
# Description
1+
### Description
22

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

6-
# Pull request type
9+
10+
### Pull request type
11+
12+
<!--
13+
Required
14+
Please tick one of the following types
15+
-->
716

817
- [ ] Fix
918
- [ ] Refactor
10-
- [ ] New Target
19+
- [ ] New target
1120
- [ ] Feature
21+
- [ ] Breaking change
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "mbed.h"
17+
#include "greentea-client/test_env.h"
18+
#include "unity.h"
19+
#include "utest.h"
20+
#include "drivers/TimerEvent.h"
21+
#include "hal/ticker_api.h"
22+
#include "rtos.h"
23+
24+
using namespace utest::v1;
25+
26+
#define TEST_DELAY_US 50000ULL
27+
28+
class TestTimerEvent: public TimerEvent {
29+
private:
30+
Semaphore sem;
31+
virtual void handler() {
32+
sem.release();
33+
}
34+
35+
public:
36+
TestTimerEvent() :
37+
TimerEvent(), sem(0, 1) {
38+
}
39+
40+
TestTimerEvent(const ticker_data_t *data) :
41+
TimerEvent(data), sem(0, 1) {
42+
}
43+
44+
virtual ~TestTimerEvent() {
45+
}
46+
47+
// Make these methods publicly accessible
48+
using TimerEvent::insert;
49+
using TimerEvent::insert_absolute;
50+
using TimerEvent::remove;
51+
52+
int32_t sem_wait(uint32_t millisec) {
53+
return sem.wait(millisec);
54+
}
55+
};
56+
57+
class TestTimerEventRelative: public TestTimerEvent {
58+
public:
59+
static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 0;
60+
TestTimerEventRelative() :
61+
TestTimerEvent() {
62+
}
63+
64+
TestTimerEventRelative(const ticker_data_t *data) :
65+
TestTimerEvent(data) {
66+
}
67+
68+
// Set relative timestamp of internal event to present_time + ts
69+
void set_future_timestamp(timestamp_t ts) {
70+
insert(::ticker_read(_ticker_data) + ts);
71+
}
72+
73+
void set_past_timestamp(void) {
74+
insert(::ticker_read(_ticker_data) - 1UL);
75+
}
76+
};
77+
78+
class TestTimerEventAbsolute: public TestTimerEvent {
79+
public:
80+
static const int32_t SEM_SLOTS_AFTER_PAST_TS_INSERTED = 1;
81+
TestTimerEventAbsolute() :
82+
TestTimerEvent() {
83+
}
84+
85+
TestTimerEventAbsolute(const ticker_data_t *data) :
86+
TestTimerEvent(data) {
87+
}
88+
89+
// Set absolute timestamp of internal event to present_time + ts
90+
void set_future_timestamp(us_timestamp_t ts) {
91+
insert_absolute(::ticker_read_us(_ticker_data) + ts);
92+
}
93+
94+
void set_past_timestamp(void) {
95+
insert_absolute(::ticker_read_us(_ticker_data) - 1ULL);
96+
}
97+
};
98+
99+
/** Template for tests: insert, insert_absolute
100+
*
101+
* Test insert
102+
* Given an instance of @a TimerEvent subclass
103+
* When a tiestamp is set with @a insert()
104+
* and given time elapses
105+
* Then an event handler is called
106+
*
107+
* Test insert_absolute
108+
* Given an instance of @a TimerEvent subclass
109+
* When a tiestamp is set with @a insert_absolute()
110+
* and given time elapses
111+
* Then an event handler is called
112+
*/
113+
template<typename T>
114+
void test_insert(void) {
115+
T tte;
116+
117+
tte.set_future_timestamp(TEST_DELAY_US);
118+
int32_t sem_slots = tte.sem_wait(0);
119+
TEST_ASSERT_EQUAL(0, sem_slots);
120+
121+
sem_slots = tte.sem_wait(TEST_DELAY_US / 1000 + 1);
122+
TEST_ASSERT_EQUAL(1, sem_slots);
123+
124+
tte.remove();
125+
}
126+
127+
/** Template for tests: remove
128+
*
129+
* Test remove after insert
130+
* Given an instance of @a TimerEvent subclass
131+
* When a tiestamp is set with @a insert()
132+
* and timestamp is removed before being reached
133+
* Then the event handler is never called
134+
*
135+
* Test remove after insert_absolute
136+
* Given an instance of @a TimerEvent subclass
137+
* When a tiestamp is set with @a insert_absolute()
138+
* and timestamp is removed before being reached
139+
* Then the event handler is never called
140+
*/
141+
template<typename T>
142+
void test_remove(void) {
143+
T tte;
144+
145+
tte.set_future_timestamp(TEST_DELAY_US * 2);
146+
int32_t sem_slots = tte.sem_wait(TEST_DELAY_US / 1000);
147+
TEST_ASSERT_EQUAL(0, sem_slots);
148+
tte.remove();
149+
150+
sem_slots = tte.sem_wait(TEST_DELAY_US * 2 / 1000 + 1);
151+
TEST_ASSERT_EQUAL(0, sem_slots);
152+
}
153+
154+
/** Test insert_absolute zero
155+
* Given an instance of @a TimerEvent subclass
156+
* When a timestamp of 0 us is set with @a insert_absolute()
157+
* Then an event handler is called instantly
158+
*/
159+
void test_insert_zero(void) {
160+
TestTimerEvent tte;
161+
162+
tte.insert_absolute(0ULL);
163+
int32_t sem_slots = tte.sem_wait(0);
164+
TEST_ASSERT_EQUAL(1, sem_slots);
165+
166+
tte.remove();
167+
}
168+
169+
/** Template for tests: insert, insert_absolute past timestamp
170+
*
171+
* Test insert timestamp from the past
172+
* Given an instance of @a TimerEvent subclass
173+
* When a timestamp of X us is set with @a insert()
174+
* and X is less than present_time
175+
* Then an event handler is **not** called instantly
176+
* (the event is scheduled after the ticker's overflow)
177+
*
178+
* Test insert_absolute timestamp from the past
179+
* Given an instance of @a TimerEvent subclass
180+
* When a timestamp of X us is set with @a insert_absolute()
181+
* and X is less than present_time
182+
* Then an event handler is called instantly
183+
*/
184+
template<typename T>
185+
void test_insert_past(void) {
186+
T tte;
187+
188+
tte.set_past_timestamp();
189+
int32_t sem_slots = tte.sem_wait(0);
190+
TEST_ASSERT_EQUAL(tte.SEM_SLOTS_AFTER_PAST_TS_INSERTED, sem_slots);
191+
192+
tte.remove();
193+
}
194+
195+
utest::v1::status_t test_setup(const size_t number_of_cases)
196+
{
197+
GREENTEA_SETUP(5, "default_auto");
198+
return verbose_test_setup_handler(number_of_cases);
199+
}
200+
201+
Case cases[] = {
202+
Case("Test insert", test_insert<TestTimerEventRelative>),
203+
Case("Test insert_absolute", test_insert<TestTimerEventAbsolute>),
204+
205+
Case("Test remove after insert", test_remove<TestTimerEventRelative>),
206+
Case("Test remove after insert_absolute", test_remove<TestTimerEventAbsolute>),
207+
208+
Case("Test insert_absolute zero", test_insert_zero),
209+
210+
Case("Test insert timestamp from the past", test_insert_past<TestTimerEventRelative>),
211+
Case("Test insert_absolute timestamp from the past", test_insert_past<TestTimerEventAbsolute>),
212+
};
213+
214+
Specification specification(test_setup, cases);
215+
216+
int main()
217+
{
218+
return !Harness::run(specification);
219+
}

TESTS/mbed_hal/flash/functional_tests/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727

2828
using namespace utest::v1;
2929

30-
#define TEST_CYCLES 1000000
31-
#define ALLOWED_DRIFT_PPM 5000 //0.5%
30+
#define TEST_CYCLES 10000000
31+
#define ALLOWED_DRIFT_PPM (1000000/5000) //0.5%
3232

3333
/*
3434
return values to be checked are documented at:
@@ -269,7 +269,7 @@ void flash_buffer_alignment_test()
269269
void flash_clock_and_cache_test()
270270
{
271271
const int timer_diff_end = time_cpu_cycles(TEST_CYCLES);
272-
const int acceptable_range = timer_diff_start / (1000000 / ALLOWED_DRIFT_PPM);
272+
const int acceptable_range = timer_diff_start / (ALLOWED_DRIFT_PPM);
273273
TEST_ASSERT_UINT32_WITHIN(acceptable_range, timer_diff_start, timer_diff_end);
274274
}
275275

drivers/TimerEvent.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,31 @@ class TimerEvent : private NonCopyable<TimerEvent> {
4747
// The handler called to service the timer event of the derived class
4848
virtual void handler() = 0;
4949

50-
// insert relative timestamp in to linked list
50+
/** Set relative timestamp of the internal event.
51+
* @param timestamp event's us timestamp
52+
*
53+
* @warning
54+
* Do not insert more than one timestamp.
55+
* The same @a event object is used for every @a insert/insert_absolute call.
56+
*
57+
* @warning
58+
* Ticker's present timestamp is used for reference. For timestamps
59+
* from the past the event is scheduled after ticker's overflow.
60+
* For reference @see convert_timestamp
61+
*/
5162
void insert(timestamp_t timestamp);
5263

53-
// insert absolute timestamp into linked list
64+
/** Set absolute timestamp of the internal event.
65+
* @param timestamp event's us timestamp
66+
*
67+
* @warning
68+
* Do not insert more than one timestamp.
69+
* The same @a event object is used for every @a insert/insert_absolute call.
70+
*/
5471
void insert_absolute(us_timestamp_t timestamp);
5572

56-
// remove from linked list, if in it
73+
/** Remove timestamp.
74+
*/
5775
void remove();
5876

5977
ticker_event_t event;

events/equeue/equeue.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static inline int equeue_clampdiff(unsigned a, unsigned b) {
3737
// Increment the unique id in an event, hiding the event from cancel
3838
static inline void equeue_incid(equeue_t *q, struct equeue_event *e) {
3939
e->id += 1;
40-
if (!(e->id << q->npw2)) {
40+
if ((e->id << q->npw2) == 0) {
4141
e->id = 1;
4242
}
4343
}
@@ -469,7 +469,7 @@ void equeue_event_dtor(void *p, void (*dtor)(void *)) {
469469
}
470470

471471

472-
// simple callbacks
472+
// simple callbacks
473473
struct ecallback {
474474
void (*cb)(void*);
475475
void *data;

features/filesystem/littlefs/littlefs/lfs.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,19 @@ static int lfs_dir_find(lfs_t *lfs, lfs_dir_t *dir,
724724
pathname += strspn(pathname, "/");
725725
pathlen = strcspn(pathname, "/");
726726

727+
// special case for root dir
728+
if (pathname[0] == '\0') {
729+
*entry = (lfs_entry_t){
730+
.d.type = LFS_TYPE_DIR,
731+
.d.elen = sizeof(entry->d) - 4,
732+
.d.alen = 0,
733+
.d.nlen = 0,
734+
.d.u.dir[0] = lfs->root[0],
735+
.d.u.dir[1] = lfs->root[1],
736+
};
737+
return 0;
738+
}
739+
727740
// skip '.' and root '..'
728741
if ((pathlen == 1 && memcmp(pathname, ".", 1) == 0) ||
729742
(pathlen == 2 && memcmp(pathname, "..", 2) == 0)) {
@@ -880,15 +893,6 @@ int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path) {
880893
return err;
881894
}
882895

883-
// check for root, can only be something like '/././../.'
884-
if (strspn(path, "/.") == strlen(path)) {
885-
dir->head[0] = dir->pair[0];
886-
dir->head[1] = dir->pair[1];
887-
dir->pos = sizeof(dir->d) - 2;
888-
dir->off = sizeof(dir->d);
889-
return 0;
890-
}
891-
892896
lfs_entry_t entry;
893897
err = lfs_dir_find(lfs, dir, &entry, &path);
894898
if (err) {
@@ -1671,14 +1675,6 @@ lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file) {
16711675

16721676
/// General fs oprations ///
16731677
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
1674-
// check for root, can only be something like '/././../.'
1675-
if (strspn(path, "/.") == strlen(path)) {
1676-
memset(info, 0, sizeof(*info));
1677-
info->type = LFS_TYPE_DIR;
1678-
strcpy(info->name, "/");
1679-
return 0;
1680-
}
1681-
16821678
lfs_dir_t cwd;
16831679
int err = lfs_dir_fetch(lfs, &cwd, lfs->root);
16841680
if (err) {
@@ -1697,11 +1693,15 @@ int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info) {
16971693
info->size = entry.d.u.file.size;
16981694
}
16991695

1700-
err = lfs_bd_read(lfs, cwd.pair[0],
1701-
entry.off + 4+entry.d.elen+entry.d.alen,
1702-
info->name, entry.d.nlen);
1703-
if (err) {
1704-
return err;
1696+
if (lfs_paircmp(entry.d.u.dir, lfs->root) == 0) {
1697+
strcpy(info->name, "/");
1698+
} else {
1699+
err = lfs_bd_read(lfs, cwd.pair[0],
1700+
entry.off + 4+entry.d.elen+entry.d.alen,
1701+
info->name, entry.d.nlen);
1702+
if (err) {
1703+
return err;
1704+
}
17051705
}
17061706

17071707
return 0;

0 commit comments

Comments
 (0)