Skip to content

Commit 527f9a1

Browse files
author
Cruz Monrreal
authored
Merge pull request #6983 from SenRamakri/sen_ErrorHandling_Push2
Standardized Error Handling and Error Codes
2 parents 791620c + 92e0cbf commit 527f9a1

File tree

19 files changed

+2241
-211
lines changed

19 files changed

+2241
-211
lines changed
Lines changed: 365 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,365 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 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 "greentea-client/test_env.h"
17+
#include "utest/utest.h"
18+
#include "unity/unity.h"
19+
#include "mbed.h"
20+
#include <LittleFileSystem.h>
21+
#include "HeapBlockDevice.h"
22+
23+
using utest::v1::Case;
24+
25+
/** Test error count and reset functionality
26+
*/
27+
void test_error_count_and_reset()
28+
{
29+
int count = 7;
30+
31+
//Log multiple errors and get the error count and make sure its 15
32+
for(int i=0; i<count; i++) {
33+
MBED_WARNING1(MBED_ERROR_OUT_OF_MEMORY, "Out of memory", i);
34+
}
35+
36+
TEST_ASSERT_EQUAL_INT(count, mbed_get_error_count());
37+
38+
//clear the errors and error count to 0
39+
mbed_clear_all_errors();
40+
41+
//Now the error count should be 0
42+
TEST_ASSERT_EQUAL_INT(0, mbed_get_error_count());
43+
44+
}
45+
46+
/** Test error type encoding and test capturing of system, custom, posix errors
47+
* and ensure the status/error code/type/error value is correct
48+
*/
49+
void test_error_capturing()
50+
{
51+
uint32_t error_value = 0xAA11BB22;
52+
mbed_error_ctx error_ctx = {0};
53+
54+
//first clear all errors and start afresh
55+
56+
MBED_WARNING1(MBED_ERROR_OUT_OF_RESOURCES, "System type error", 0x1100 );
57+
mbed_error_status_t lastError = mbed_get_last_error();
58+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_TYPE_SYSTEM, MBED_GET_ERROR_TYPE(lastError));
59+
TEST_ASSERT_EQUAL_UINT(MBED_MODULE_UNKNOWN, MBED_GET_ERROR_MODULE(lastError));
60+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_CODE_OUT_OF_RESOURCES, MBED_GET_ERROR_CODE(lastError));
61+
62+
mbed_error_status_t error = MBED_MAKE_ERROR(MBED_MODULE_DRIVER_SERIAL, MBED_ERROR_CODE_OUT_OF_RESOURCES);
63+
MBED_WARNING1(error, "Error Serial", 0xAA );
64+
lastError = mbed_get_last_error();
65+
TEST_ASSERT_EQUAL_UINT(error, lastError);
66+
67+
error = MBED_MAKE_CUSTOM_ERROR(MBED_MODULE_APPLICATION, MBED_ERROR_CODE_UNKNOWN);
68+
MBED_WARNING1(error, "Custom Error Unknown", 0x1234 );
69+
lastError = mbed_get_last_error();
70+
TEST_ASSERT_EQUAL_UINT(error, lastError);
71+
72+
MBED_WARNING1(MBED_ERROR_EPERM, "Posix Error Eperm", 0x1234 );
73+
lastError = mbed_get_last_error();
74+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_EPERM, lastError);
75+
76+
error = MBED_MAKE_CUSTOM_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_CREATE_FAILED);
77+
MBED_WARNING1(error, "Custom Error Type", error_value);
78+
lastError = mbed_get_last_error();
79+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_TYPE_CUSTOM, MBED_GET_ERROR_TYPE(lastError));
80+
TEST_ASSERT_EQUAL_UINT(MBED_MODULE_PLATFORM, MBED_GET_ERROR_MODULE(lastError));
81+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_CODE_CREATE_FAILED, MBED_GET_ERROR_CODE(lastError));
82+
mbed_error_status_t status = mbed_get_last_error_info( &error_ctx );
83+
TEST_ASSERT(status == MBED_SUCCESS);
84+
TEST_ASSERT_EQUAL_UINT(error_value, error_ctx.error_value);
85+
86+
error_value = 0xAABBCC;
87+
MBED_WARNING1(MBED_ERROR_EACCES, "Posix Error", error_value );
88+
lastError = mbed_get_last_error();
89+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_TYPE_POSIX, MBED_GET_ERROR_TYPE(lastError));
90+
TEST_ASSERT_EQUAL_UINT(MBED_MODULE_UNKNOWN, MBED_GET_ERROR_MODULE(lastError));
91+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_CODE_EACCES, MBED_GET_ERROR_CODE(lastError));
92+
status = mbed_get_last_error_info( &error_ctx );
93+
TEST_ASSERT(status == MBED_SUCCESS);
94+
TEST_ASSERT_EQUAL_UINT(error_value, error_ctx.error_value);
95+
96+
error_value = 0;
97+
error = MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_UNKNOWN);
98+
MBED_WARNING1(error, "HAL Entity error", error_value );
99+
lastError = mbed_get_last_error();
100+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_TYPE_SYSTEM, MBED_GET_ERROR_TYPE(lastError));
101+
TEST_ASSERT_EQUAL_UINT(MBED_MODULE_HAL, MBED_GET_ERROR_MODULE(lastError));
102+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_CODE_UNKNOWN, MBED_GET_ERROR_CODE(lastError));
103+
status = mbed_get_last_error_info( &error_ctx );
104+
TEST_ASSERT(status == MBED_SUCCESS);
105+
TEST_ASSERT_EQUAL_UINT(error_value, error_ctx.error_value);
106+
107+
MBED_WARNING1(MBED_ERROR_MUTEX_LOCK_FAILED, "Mutex lock failed", 0x4455 );
108+
error = mbed_get_last_error();
109+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_MUTEX_LOCK_FAILED, error);
110+
111+
error = mbed_get_first_error();
112+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_OUT_OF_RESOURCES, error);
113+
114+
}
115+
116+
/** Test error context capture
117+
*/
118+
void test_error_context_capture()
119+
{
120+
uint32_t error_value = 0xABCD;
121+
mbed_error_ctx error_ctx = {0};
122+
123+
MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "System type error", error_value );
124+
mbed_error_status_t status = mbed_get_last_error_info( &error_ctx );
125+
TEST_ASSERT(status == MBED_SUCCESS);
126+
TEST_ASSERT_EQUAL_UINT(error_value, error_ctx.error_value);
127+
TEST_ASSERT_EQUAL_UINT(osThreadGetId(), error_ctx.thread_id);
128+
129+
//Capture thread info and compare
130+
osRtxThread_t *current_thread = osRtxInfo.thread.run.curr;
131+
TEST_ASSERT_EQUAL_UINT((uint32_t)current_thread->thread_addr, error_ctx.thread_entry_address);
132+
TEST_ASSERT_EQUAL_UINT((uint32_t)current_thread->stack_size, error_ctx.thread_stack_size);
133+
TEST_ASSERT_EQUAL_UINT((uint32_t)current_thread->stack_mem, error_ctx.thread_stack_mem);
134+
#ifdef MBED_CONF_ERROR_FILENAME_CAPTURE_ENABLED
135+
TEST_ASSERT_EQUAL_STRING(MBED_FILENAME, error_ctx.error_filename);
136+
#endif
137+
}
138+
139+
#ifndef MBED_CONF_ERROR_HIST_DISABLED
140+
/** Test error logging functionality
141+
*/
142+
void test_error_logging()
143+
{
144+
mbed_error_ctx error_ctx = {0};
145+
146+
//clear the current errors first
147+
mbed_clear_all_errors();
148+
149+
//log 3 errors and retrieve them to ensure they are correct
150+
MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Invalid argument", 1 );
151+
MBED_WARNING1(MBED_ERROR_INVALID_SIZE, "Invalid size", 2 );
152+
MBED_WARNING1(MBED_ERROR_INVALID_FORMAT, "Invalid format", 3 );
153+
154+
mbed_error_status_t status = mbed_get_error_hist_info( 0, &error_ctx );
155+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_ARGUMENT, error_ctx.error_status);
156+
TEST_ASSERT_EQUAL_UINT(1, error_ctx.error_value);
157+
158+
status = mbed_get_error_hist_info( 1, &error_ctx );
159+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_SIZE, error_ctx.error_status);
160+
TEST_ASSERT_EQUAL_UINT(2, error_ctx.error_value);
161+
162+
status = mbed_get_error_hist_info( 2, &error_ctx );
163+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_FORMAT, error_ctx.error_status);
164+
TEST_ASSERT_EQUAL_UINT(3, error_ctx.error_value);
165+
166+
//Log a bunch of errors to overflow the error log and retrieve them
167+
MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Invalid argument", 6 );
168+
MBED_WARNING1(MBED_ERROR_INVALID_SIZE, "Invalid size", 7 );
169+
MBED_WARNING1(MBED_ERROR_INVALID_FORMAT, "Invalid format", 8 );
170+
MBED_WARNING1(MBED_ERROR_NOT_READY, "Not ready error", 9 );
171+
172+
//Last 4 entries
173+
MBED_WARNING1(MBED_ERROR_TIME_OUT, "Timeout error", 10 );
174+
MBED_WARNING1(MBED_ERROR_ALREADY_IN_USE, "Already in use error", 11 );
175+
MBED_WARNING1(MBED_ERROR_UNSUPPORTED, "Not supported", 12 );
176+
MBED_WARNING1(MBED_ERROR_ACCESS_DENIED, "Access denied", 13 );
177+
178+
status = mbed_get_error_hist_info( 0, &error_ctx );
179+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_TIME_OUT, error_ctx.error_status);
180+
TEST_ASSERT_EQUAL_UINT(10, error_ctx.error_value);
181+
182+
status = mbed_get_error_hist_info( 1, &error_ctx );
183+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_ALREADY_IN_USE, error_ctx.error_status);
184+
TEST_ASSERT_EQUAL_UINT(11, error_ctx.error_value);
185+
186+
status = mbed_get_error_hist_info( 2, &error_ctx );
187+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_UNSUPPORTED, error_ctx.error_status);
188+
TEST_ASSERT_EQUAL_UINT(12, error_ctx.error_value);
189+
190+
status = mbed_get_error_hist_info( 3, &error_ctx );
191+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_ACCESS_DENIED, error_ctx.error_status);
192+
TEST_ASSERT_EQUAL_UINT(13, error_ctx.error_value);
193+
194+
//Try an index which is invalid, we should get ERROR_INVALID_ARGUMENT back
195+
status = mbed_get_error_hist_info( 99, &error_ctx );
196+
TEST_ASSERT_EQUAL_UINT(MBED_ERROR_INVALID_ARGUMENT, status);
197+
198+
}
199+
200+
#define NUM_TEST_THREADS 5
201+
202+
//Error logger threads
203+
void err_thread_func(mbed_error_status_t *error_status)
204+
{
205+
MBED_WARNING1(*error_status, "Error from Multi-Threaded error logging test", *error_status );
206+
}
207+
208+
209+
/** Test error logging multithreaded
210+
*/
211+
void test_error_logging_multithread()
212+
{
213+
mbed_error_ctx error_ctx = {0};
214+
int i=0;
215+
Thread *errThread[NUM_TEST_THREADS];
216+
mbed_error_status_t error_status[NUM_TEST_THREADS] = {
217+
MBED_ERROR_INVALID_ARGUMENT, MBED_ERROR_INVALID_DATA_DETECTED, MBED_ERROR_INVALID_FORMAT, MBED_ERROR_INVALID_SIZE, MBED_ERROR_INVALID_OPERATION
218+
};
219+
220+
221+
for(; i<NUM_TEST_THREADS; i++) {
222+
errThread[i] = new Thread(osPriorityNormal1, 512, NULL, NULL);
223+
errThread[i]->start(callback(err_thread_func, &error_status[i]));
224+
}
225+
wait(2.0);
226+
for(i=0; i<NUM_TEST_THREADS; i++) {
227+
errThread[i]->join();
228+
}
229+
230+
i = mbed_get_error_hist_count()-1;
231+
232+
for(;i>=0;--i) {
233+
mbed_error_status_t status = mbed_get_error_hist_info( i, &error_ctx );
234+
if(status != MBED_SUCCESS) {
235+
TEST_FAIL();
236+
}
237+
238+
TEST_ASSERT_EQUAL_UINT((unsigned int)error_ctx.error_value, (unsigned int)error_ctx.error_status);
239+
}
240+
}
241+
#endif
242+
243+
static Semaphore callback_sem;
244+
void MyErrorHook(const mbed_error_ctx *error_ctx)
245+
{
246+
callback_sem.release();
247+
}
248+
249+
/** Test error hook
250+
*/
251+
void test_error_hook()
252+
{
253+
if( MBED_SUCCESS != mbed_set_error_hook(MyErrorHook)) {
254+
TEST_FAIL();
255+
}
256+
257+
MBED_WARNING1(MBED_ERROR_INVALID_ARGUMENT, "Test for error hook", 1234);
258+
int32_t sem_status = callback_sem.wait(5000);
259+
260+
TEST_ASSERT(sem_status > 0);
261+
}
262+
263+
#ifdef MBED_TEST_SIM_BLOCKDEVICE
264+
265+
// test configuration
266+
#ifndef MBED_TEST_FILESYSTEM
267+
#define MBED_TEST_FILESYSTEM LittleFileSystem
268+
#endif
269+
270+
#ifndef MBED_TEST_FILESYSTEM_DECL
271+
#define MBED_TEST_FILESYSTEM_DECL MBED_TEST_FILESYSTEM fs("fs")
272+
#endif
273+
274+
#ifndef MBED_TEST_BLOCK_COUNT
275+
#define MBED_TEST_BLOCK_COUNT 64
276+
#endif
277+
278+
#ifndef MBED_TEST_SIM_BLOCKDEVICE_DECL
279+
#define MBED_TEST_SIM_BLOCKDEVICE_DECL MBED_TEST_SIM_BLOCKDEVICE fd(MBED_TEST_BLOCK_COUNT*512, 1, 1, 512)
280+
#endif
281+
282+
// declarations
283+
#define STRINGIZE(x) STRINGIZE2(x)
284+
#define STRINGIZE2(x) #x
285+
#define INCLUDE(x) STRINGIZE(x.h)
286+
287+
#include INCLUDE(MBED_TEST_FILESYSTEM)
288+
#include INCLUDE(MBED_TEST_SIM_BLOCKDEVICE)
289+
290+
MBED_TEST_FILESYSTEM_DECL;
291+
MBED_TEST_SIM_BLOCKDEVICE_DECL;
292+
293+
/** Test save error log
294+
*/
295+
void test_save_error_log()
296+
{
297+
//Log some errors
298+
MBED_WARNING1(MBED_ERROR_TIME_OUT, "Timeout error", 1 );
299+
MBED_WARNING1(MBED_ERROR_ALREADY_IN_USE, "Already in use error", 2 );
300+
MBED_WARNING1(MBED_ERROR_UNSUPPORTED, "Not supported error", 3 );
301+
MBED_WARNING1(MBED_ERROR_ACCESS_DENIED, "Access denied error", 4 );
302+
MBED_WARNING1(MBED_ERROR_ITEM_NOT_FOUND, "Not found error", 5 );
303+
304+
int error = 0;
305+
306+
error = MBED_TEST_FILESYSTEM::format(&fd);
307+
if(error < 0) {
308+
TEST_FAIL_MESSAGE("Failed formatting");
309+
}
310+
311+
error = fs.mount(&fd);
312+
if(error < 0) {
313+
TEST_FAIL_MESSAGE("Failed mounting fs");
314+
}
315+
316+
if(MBED_SUCCESS != mbed_save_error_hist("/fs/errors.log")) {
317+
TEST_FAIL_MESSAGE("Failed saving error log");
318+
}
319+
320+
FILE *error_file = fopen("/fs/errors.log", "r");
321+
if(error_file == NULL) {
322+
TEST_FAIL_MESSAGE("Unable to find error log in fs");
323+
}
324+
325+
char buff[64] = {0};
326+
while (!feof(error_file)){
327+
int size = fread(&buff[0], 1, 15, error_file);
328+
fwrite(&buff[0], 1, size, stdout);
329+
}
330+
fclose(error_file);
331+
332+
error = fs.unmount();
333+
if(error < 0) {
334+
TEST_FAIL_MESSAGE("Failed unmounting fs");
335+
}
336+
}
337+
338+
#endif
339+
340+
utest::v1::status_t test_setup(const size_t number_of_cases)
341+
{
342+
GREENTEA_SETUP(120, "default_auto");
343+
return utest::v1::verbose_test_setup_handler(number_of_cases);
344+
}
345+
346+
Case cases[] = {
347+
Case("Test error counting and reset", test_error_count_and_reset),
348+
Case("Test error encoding, value capture, first and last errors", test_error_capturing),
349+
Case("Test error context capture", test_error_context_capture),
350+
Case("Test error hook", test_error_hook),
351+
#ifndef MBED_CONF_ERROR_HIST_DISABLED
352+
Case("Test error logging", test_error_logging),
353+
Case("Test error handling multi-threaded", test_error_logging_multithread),
354+
#ifdef MBED_TEST_SIM_BLOCKDEVICE
355+
Case("Test error save log", test_save_error_log),
356+
#endif
357+
#endif
358+
};
359+
360+
utest::v1::Specification specification(test_setup, cases);
361+
362+
int main()
363+
{
364+
return !utest::v1::Harness::run(specification);
365+
}

TESTS/mbedmicro-rtos-mbed/event_flags/main.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ Semaphore sync_sem(0, 1);
5151
void error(const char* format, ...) {
5252
(void) format;
5353
}
54+
55+
//Override the set_error function to trap the errors
56+
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
57+
{
58+
return MBED_SUCCESS;
59+
}
5460
#endif
5561

5662
template<uint32_t flags, uint32_t wait_ms>

TESTS/mbedmicro-rtos-mbed/rtostimer/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ void error(const char* format, ...)
8585
{
8686
(void) format;
8787
}
88+
89+
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
90+
{
91+
return MBED_SUCCESS;
92+
}
8893
#endif
8994

9095
/** Test one-shot not restarted when elapsed

0 commit comments

Comments
 (0)