Skip to content

Commit f8cb240

Browse files
brandonboeschmray190
authored andcommitted
Added conconcurrent testing (#62)
* Added conconcurrent/GPIO test * Updated GPIO test to run tests more concurrently instead of sequentially * Added Comms.cpp. It is currently only running the two seperate APIs in seperate test cases. Still need to convert this to make them run concurrently in a single thread and in seperate threads. * Added concurrent test in a single thread for comms testing. Need to finish multi thread test case * Finished Comms test. Has both single thread and multithread test cases. * Should now be finished with conncurrent testing * Removed unintentional .swp file from conccurent/Mixed * Added ifdef checks for tests running AnalogIn tests.
1 parent c3d8a41 commit f8cb240

File tree

3 files changed

+693
-0
lines changed

3 files changed

+693
-0
lines changed

TESTS/concurrent/Comms/Comms.cpp

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
* Copyright (c) 2016 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+
17+
18+
#if !DEVICE_SPI // check if SPI is supported on this device
19+
#error [NOT_SUPPORTED] SPI is not supported on this platform, add 'DEVICE_SPI' definition to your platform.
20+
21+
#elif !DEVICE_I2C // check if I2C is supported on this device
22+
#error [NOT_SUPPORTED] I2C not supported on this platform, add 'DEVICE_I2C' definition to your platform.
23+
24+
#endif // !DEVICE_SPI or !DEVICE_I2C
25+
26+
27+
#include "mbed.h"
28+
#include "greentea-client/test_env.h"
29+
#include "unity.h"
30+
#include "utest.h"
31+
#include "ci_test_config.h"
32+
#include "FATFileSystem.h"
33+
#include "SDBlockDevice.h"
34+
#include <I2CEeprom.h>
35+
36+
using namespace utest::v1;
37+
38+
#define TEST_STRING_MAX 128
39+
40+
Thread Thread_I2C; // thread used in multithread tests
41+
Thread Thread_SPI; // thread used in multithread tests
42+
osThreadId Multi_Thread_ID; // thread id for main function controlling multithread tests
43+
char Test_String[TEST_STRING_MAX] = {0}; // reference string used in testing
44+
45+
// Fill array with random characters. TODO: make this string a randomly generated thing
46+
void init_string()
47+
{
48+
for(int x = 0; x < TEST_STRING_MAX-1; x++){
49+
Test_String[x] = 'A' + (rand() % 26);
50+
}
51+
Test_String[TEST_STRING_MAX-1] = 0;
52+
53+
DEBUG_PRINTF("\r\n****\r\n Test_String Size(Bytes) = %d\r\n Test_String = %s\r\n****\r\n",TEST_STRING_MAX,Test_String);
54+
}
55+
56+
57+
// test I2C API by writting and reading from EEPROM
58+
void test_I2C()
59+
{
60+
// initialize variables and API
61+
int address = 0; // starting address to write to
62+
int num_read = 0; // will report number of bytes read
63+
int num_written = 0; // will report number of bytes written
64+
volatile char read_string[TEST_STRING_MAX] = {0}; // string that will be updated from reading EEPROM
65+
I2CEeprom memory(MBED_CONF_APP_I2C_SDA,MBED_CONF_APP_I2C_SCL,MBED_CONF_APP_I2C_EEPROM_ADDR,32,0);
66+
67+
// write to EEPROM
68+
num_written = memory.write(address,Test_String,TEST_STRING_MAX);
69+
70+
// read back from EEPROM
71+
num_read = memory.read(address,(char *)read_string,TEST_STRING_MAX);
72+
73+
// test for equality
74+
TEST_ASSERT_EQUAL_STRING_MESSAGE(Test_String,(char *)read_string,"String read does not match the string written"); // test that strings match
75+
TEST_ASSERT_EQUAL_MESSAGE(num_written,num_read,"Number of bytes written does not match the number of bytes read");
76+
DEBUG_PRINTF("\r\n****\r\n I2C TEST:\r\n Address = `%d`\r\n Num Bytes Written = `%d` \r\n Num Bytes Read = `%d` \r\n String written = `%s` \r\n String read = `%s` \r\n****\r\n",address,num_written,num_read,Test_String,read_string);
77+
osSignalSet(Multi_Thread_ID, 0x1); // signal completion of thread
78+
}
79+
80+
81+
// test SPI API by writing and reading from SD card
82+
void test_SPI()
83+
{
84+
// initialze SD hardware, filesystem, and variables
85+
SDBlockDevice sd(MBED_CONF_APP_SPI_MOSI, MBED_CONF_APP_SPI_MISO, MBED_CONF_APP_SPI_CLK, MBED_CONF_APP_SPI_CS);
86+
FATFileSystem fs("sd", &sd);
87+
sd.init();
88+
fs.mount(&sd);
89+
FILE *File = fopen("/sd/test_sd_w.txt", "w");
90+
TEST_ASSERT_MESSAGE(File != NULL,"SD Card is not present. Please insert an SD Card.");
91+
volatile char read_string[TEST_STRING_MAX] = {0};
92+
93+
// write data to SD card
94+
int error = fprintf(File, Test_String); // write data
95+
TEST_ASSERT_MESSAGE(error > 0,"Writing file to sd card failed"); // error checking
96+
fclose(File); // close file on SD
97+
98+
// read data from SD card
99+
File = fopen("/sd/test_sd_w.txt", "r");
100+
fgets((char *)read_string,TEST_STRING_MAX,File); // read string from the file
101+
102+
// test for equality
103+
TEST_ASSERT_EQUAL_STRING_MESSAGE(Test_String,(char *)read_string,"String read does not match the string written"); // test that strings match
104+
DEBUG_PRINTF("\r\n****\r\n SPI TEST:\r\n String written = `%s` \r\n String read = `%s` \r\n****\r\n",Test_String,read_string);
105+
106+
// close, unmount, and deinitialize
107+
fclose(File); // close file on SD
108+
fs.unmount();
109+
sd.deinit();
110+
osSignalSet(Multi_Thread_ID, 0x2); // signal completion of thread
111+
}
112+
113+
114+
// test I2C and SPI APIs concurrently in multiple threads
115+
void test_multiple_threads()
116+
{
117+
Multi_Thread_ID = Thread::gettid(); // update thread id for this thread
118+
Thread_I2C.start(callback(test_I2C)); // kick off threads
119+
Thread_SPI.start(callback(test_SPI)); // kick off threads
120+
wait(0.1); // allow time for debug print statements to complete.
121+
122+
// Use this to wait for both signaling events to occur
123+
// Internaly the code is doing something like this:
124+
// if ((signal1 | signal2) & 0x3 == 0x3) then exit, else wait
125+
osSignalWait(0x3, osWaitForever);
126+
}
127+
128+
129+
// test I2C and SPI APIs concurrently in a single thread
130+
void test_single_thread()
131+
{
132+
// *******************************
133+
// Initialize variables and APIs
134+
// *******************************
135+
136+
// I2C test initializations
137+
int address = 0; // starting address to write to in EEPROM
138+
int num_read = 0; // will report number of bytes read
139+
int num_written = 0; // will report number of bytes written
140+
volatile char read_string_i2c[TEST_STRING_MAX] = {0}; // string that will be updated from reading EEPROM
141+
I2CEeprom memory(MBED_CONF_APP_I2C_SDA,MBED_CONF_APP_I2C_SCL,MBED_CONF_APP_I2C_EEPROM_ADDR,32,0);
142+
143+
// SPI test initializations
144+
volatile char read_string_spi[TEST_STRING_MAX] = {0}; // string that will be updated from reading SD card
145+
SDBlockDevice sd(MBED_CONF_APP_SPI_MOSI, MBED_CONF_APP_SPI_MISO, MBED_CONF_APP_SPI_CLK, MBED_CONF_APP_SPI_CS);
146+
FATFileSystem fs("sd", &sd);
147+
sd.init();
148+
fs.mount(&sd);
149+
FILE *File = fopen("/sd/test_sd_w.txt", "w");
150+
TEST_ASSERT_MESSAGE(File != NULL,"SD Card is not present. Please insert an SD Card.");
151+
152+
// ******************************
153+
// Begin concurrent API testing
154+
// ******************************
155+
// write to EEPROM using I2C
156+
num_written = memory.write(address,Test_String,TEST_STRING_MAX);
157+
158+
// write to SD card using SPI
159+
int error = fprintf(File, Test_String); // write data
160+
TEST_ASSERT_MESSAGE(error > 0,"Writing file to sd card failed"); // error checking
161+
fclose(File); // close file on SD
162+
163+
// read back from EEPROM
164+
num_read = memory.read(address,(char *)read_string_i2c,TEST_STRING_MAX);
165+
166+
// read data from SD card
167+
File = fopen("/sd/test_sd_w.txt", "r");
168+
fgets((char *)read_string_spi,TEST_STRING_MAX,File); // read string from the file
169+
170+
// ******************************
171+
// Check results
172+
// ******************************
173+
174+
// test results for I2C
175+
TEST_ASSERT_EQUAL_STRING_MESSAGE(Test_String,(char *)read_string_i2c,"String read does not match the string written"); // test that strings match
176+
TEST_ASSERT_EQUAL_MESSAGE(num_written,num_read,"Number of bytes written does not match the number of bytes read");
177+
DEBUG_PRINTF("\r\n****\r\n I2C TEST:\r\n Address = `%d`\r\n Num Bytes Written = `%d` \r\n Num Bytes Read = `%d` \r\n String written = `%s` \r\n String read = `%s` \r\n****\r\n",address,num_written,num_read,Test_String,read_string_i2c);
178+
179+
// test results for SPI
180+
TEST_ASSERT_EQUAL_STRING_MESSAGE(Test_String,(char *)read_string_spi,"String read does not match the string written"); // test that strings match
181+
DEBUG_PRINTF("\r\n****\r\n SPI TEST:\r\n String written = `%s` \r\n String read = `%s` \r\n****\r\n",Test_String,read_string_spi);
182+
fclose(File); // close file on SD
183+
fs.unmount(); // unmount
184+
sd.deinit(); // deinitialize SD
185+
}
186+
187+
188+
utest::v1::status_t test_setup(const size_t number_of_cases)
189+
{
190+
// Setup Greentea using a reasonable timeout in seconds
191+
GREENTEA_SETUP(40, "default_auto");
192+
return verbose_test_setup_handler(number_of_cases);
193+
}
194+
195+
196+
// Handle test failures, keep testing, dont stop
197+
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
198+
{
199+
greentea_case_failure_abort_handler(source, reason);
200+
return STATUS_CONTINUE;
201+
}
202+
203+
204+
// Test cases
205+
Case cases[] = {
206+
Case("Concurrent testing of I2C and SPI in a single thread",test_single_thread,greentea_failure_handler),
207+
Case("Concurrent testing of I2C and SPI in multiple threads",test_multiple_threads,greentea_failure_handler),
208+
};
209+
210+
211+
Specification specification(test_setup, cases);
212+
213+
// // Entry point into the tests
214+
int main() {
215+
init_string();
216+
return !Harness::run(specification);
217+
}

TESTS/concurrent/GPIO/GPIO.cpp

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (c) 2016 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+
17+
18+
#if !DEVICE_ANALOGIN
19+
#error [NOT_SUPPORTED] AnalogIn not supported on this platform, add 'DEVICE_ANALOGIN' definition to your platform.
20+
#endif
21+
22+
#include "mbed.h"
23+
#include "greentea-client/test_env.h"
24+
#include "unity.h"
25+
#include "utest.h"
26+
#include "ci_test_config.h"
27+
28+
using namespace utest::v1;
29+
30+
volatile bool Result = false;
31+
32+
// Callback for all InterruptInput functions
33+
void cbfn(void)
34+
{
35+
Result = true;
36+
}
37+
38+
39+
// Template to test DigitalIO, AnalogIn, and InterruptIn pins. Meant to be re-used multiple times
40+
template <PinName digitalOut_pin, PinName digitalIn_pin, PinName analogIn_pin, PinName analogBus_pin1, PinName analogBus_pin2, PinName analogBus_pin3, PinName analogBus_pin4, PinName analogBus_pin5, PinName interruptIn_pin, PinName interruptOut_pin>
41+
42+
43+
void GPIO_Test()
44+
{
45+
// ***********************
46+
// Initialize API pins
47+
// ***********************
48+
DEBUG_PRINTF("Initializing API pins\n");
49+
// Pins for DIO test
50+
DigitalOut d_out(digitalOut_pin);
51+
DigitalIn d_in(digitalIn_pin);
52+
53+
// Pins for AnalogIn test
54+
AnalogIn a_in(analogIn_pin);
55+
BusInOut aBus_outputs(analogBus_pin1,analogBus_pin2,analogBus_pin3,analogBus_pin4,analogBus_pin5);
56+
57+
// Pins for InterruptIn test
58+
InterruptIn int_in(interruptIn_pin);
59+
DigitalOut int_out(interruptOut_pin);
60+
61+
// ***********************
62+
// Begin concurrent API testing
63+
// ***********************
64+
DEBUG_PRINTF("Begining concurrent API testing\n");
65+
aBus_outputs.output();
66+
int analogOut_value= 0;
67+
aBus_outputs = 0;
68+
float prev_analog_value = 0;
69+
for(int iter = 0; iter<5; iter++) {
70+
// DigitalIO test
71+
d_out = 0; // test 0
72+
TEST_ASSERT_MESSAGE(0 == d_in.read(),"Expected value to be 0, read value was not zero");
73+
d_out = 1; // test 1
74+
TEST_ASSERT_MESSAGE(1 == d_in.read(),"Expected value to be 1, read value was not one");
75+
76+
// AnalogIn test
77+
prev_analog_value = a_in.read();
78+
analogOut_value = (analogOut_value << 1) + 1;
79+
aBus_outputs = analogOut_value;
80+
TEST_ASSERT_MESSAGE(a_in.read() > prev_analog_value,"Analog Input did not increment.");
81+
82+
// Rising Edge InterruptIn test
83+
Result = false;
84+
int_out = 0;
85+
int_in.rise(cbfn);
86+
int_out = 1;
87+
wait(0); // dummy wait to get volatile result value
88+
TEST_ASSERT_MESSAGE(Result,"cbfn was not triggered on rising edge of pin");
89+
90+
// Falling Edge InterruptIn test
91+
Result = false;
92+
int_out = 1;
93+
int_in.fall(cbfn);
94+
int_out = 0;
95+
wait(0); // dummy wait to get volatile result value
96+
TEST_ASSERT_MESSAGE(Result,"cbfn was not triggered on falling edge of pin");
97+
}
98+
}
99+
100+
101+
utest::v1::status_t test_setup(const size_t number_of_cases)
102+
{
103+
// Setup Greentea using a reasonable timeout in seconds
104+
GREENTEA_SETUP(30, "default_auto");
105+
return verbose_test_setup_handler(number_of_cases);
106+
}
107+
108+
109+
// Handle test failures, keep testing, dont stop
110+
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
111+
{
112+
greentea_case_failure_abort_handler(source, reason);
113+
return STATUS_CONTINUE;
114+
}
115+
116+
117+
// Test cases
118+
// Runs three different APIs concurrently, DIO, AnalogIn, and InterruptIn
119+
Case cases[] = {
120+
Case("Concurrent testing of DIO(D2,D3), AnalogIn(A0), and InterruptIn(D4,D5)",GPIO_Test<MBED_CONF_APP_DIO_2,MBED_CONF_APP_DIO_3,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_AIN_5,MBED_CONF_APP_DIO_4,MBED_CONF_APP_DIO_5>,greentea_failure_handler),
121+
122+
Case("Concurrent testing of DIO(D3,D2), AnalogIn(A1), and InterruptIn(D5,D4)",GPIO_Test<MBED_CONF_APP_DIO_3,MBED_CONF_APP_DIO_2, MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_AIN_5,MBED_CONF_APP_AIN_0,MBED_CONF_APP_DIO_5,MBED_CONF_APP_DIO_4>,greentea_failure_handler),
123+
124+
Case("Concurrent testing of DIO(D4,D5), AnalogIn(A2), and InterruptIn(D6,D7)",GPIO_Test<MBED_CONF_APP_DIO_4,MBED_CONF_APP_DIO_5, MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_AIN_5,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_DIO_6,MBED_CONF_APP_DIO_7>,greentea_failure_handler),
125+
126+
Case("Concurrent testing of DIO(D5,D4), AnalogIn(A3), and InterruptIn(D7,D6)",GPIO_Test<MBED_CONF_APP_DIO_5,MBED_CONF_APP_DIO_4, MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_AIN_5,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_DIO_7,MBED_CONF_APP_DIO_6>,greentea_failure_handler),
127+
128+
Case("Concurrent testing of DIO(D6,D7), AnalogIn(A4), and InterruptIn(D8,D9)",GPIO_Test<MBED_CONF_APP_DIO_6,MBED_CONF_APP_DIO_7, MBED_CONF_APP_AIN_4,MBED_CONF_APP_AIN_5,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_DIO_8,MBED_CONF_APP_DIO_9>,greentea_failure_handler),
129+
130+
Case("Concurrent testing of DIO(D7,D6), AnalogIn(A5), and InterruptIn(D9,D8)",GPIO_Test<MBED_CONF_APP_DIO_7,MBED_CONF_APP_DIO_6, MBED_CONF_APP_AIN_5,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_DIO_9,MBED_CONF_APP_DIO_8>,greentea_failure_handler),
131+
132+
Case("Concurrent testing of DIO(D8,D9), AnalogIn(A5), and InterruptIn(D2,D3)",GPIO_Test<MBED_CONF_APP_DIO_8,MBED_CONF_APP_DIO_9, MBED_CONF_APP_AIN_5,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_DIO_2,MBED_CONF_APP_DIO_3>,greentea_failure_handler),
133+
134+
Case("Concurrent testing of DIO(D9,D8), AnalogIn(A5), and InterruptIn(D3,D2)",GPIO_Test<MBED_CONF_APP_DIO_9,MBED_CONF_APP_DIO_8, MBED_CONF_APP_AIN_5,MBED_CONF_APP_AIN_0,MBED_CONF_APP_AIN_1,MBED_CONF_APP_AIN_2,MBED_CONF_APP_AIN_3,MBED_CONF_APP_AIN_4,MBED_CONF_APP_DIO_3,MBED_CONF_APP_DIO_2>,greentea_failure_handler),
135+
};
136+
137+
138+
Specification specification(test_setup, cases);
139+
140+
141+
// Entry point into the tests
142+
int main()
143+
{
144+
return !Harness::run(specification);
145+
}

0 commit comments

Comments
 (0)