VIA University College
ICT-Engineering
Bringideastolife
VIAUniversityCollege
ObjectOrientering,TestDriven
DevelopmentogC
InfinIT, 21. November 2018
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 1
Ib Havn
B.Sc.E.E.
M.Sc.ITSoftware Construction
VIA University College
ICT-Engineering
Whatistheproblems withhardwarenear
programming?
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 2
– The nearer the hardware the testing difficulties grows
– There are not much help from different tools
– Errors/bugs are difficult to find
– The software are target dependent
– Design for Test is the solution
– Debug Later Programming (DLP) vs Test Driven Development
VIA University College
ICT-Engineering
Whydoweforgeteverythingwehave
learnedwhenprogramminglow-levelC?
Typical excuses:
1. Hardware near programming is for Electronics Engineers
2. The hardware is not available yet
3. It is not possible to test due to limited target resources
– Test Driven Development (TDD) is not possible on the small target
4. Debugging facilities in the target toolchain is limited
– Debugging is difficult and is done with oscilloscopes, leds, simple printouts
etc.
5. UML is not useful for C-programming
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 3
VIA University College
ICT-Engineering
ObjectOrientedDesignandProgramming
inC
According to Robert C. Martin an OOP language has the following:
1. Encapsulation
2. Inheritance
3. Polymorphism
The first two are easy to obtain in C, the third is a little harder
1. Abstract Data Types (ADT)
2. Nested struct’s
3. Pointer tables
For a complete description how to do use three read
Axel Schreiner’s book: Object-oriented Programming in ANSI-C
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 4
VIA University College
ICT-Engineering
Exampleofcomplete Encapsulation inC
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 5
VIA University College
ICT-Engineering
Exampleofcomplete Encapsulation inC
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 6
// Abstract Data Type (ADT)
typedef struct serial_struct *serial_p;
serial_p serial_new_instance(e_com_port_t com_port, uint32_t baud, e_data_bit_t data_bit,
e_stop_bit_t stop_bit, e_parity_t parity, uint8_t rx_fifo_size,
uint8_t tx_fifo_size,
void(*handler_call_back )(serial_p, uint8_t));
e_serial_return_code_t serial_send_bytes(serial_p handle, uint8_t *buf, uint8_t len);
e_serial_return_code_t serial_send_byte(serial_p handle, uint8_t byte);
e_serial_return_code_t serial_get_byte(serial_p handle, uint8_t *byte);
void serial_flush_rx_fifo(serial_p handle);
void serial_flush_tx_fifo(serial_p handle);
This is all the clients using the driver can see:
VIA University College
ICT-Engineering
ObjectOrientedDesignandProgramming
inC
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 7
Why not use UML – A World wide Industry Standard
VIA University College
ICT-Engineering
SOLIDDesignPrinciples
Robert C. Martin has assembled these five more or less well-known principles together
Single Responsibility Principle (SRP)
– A class should have one, and only one, reason to change
Open Close Principle (OCP)
– You should be able to extend a class’s behaviour, without modifying it
Liskov Substitution Principle (LSP)
– Derived classes must be substitutables for their base classes
Interface Segregation Principle (ISP)
– Make fine grained interfaces that are client specific
Dependency Inversion Principle (DIP)
– Depend on abstractions, not on concretions
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 8
VIA University College
ICT-Engineering
TestDrivenDevelopment(TDD)
TDDState-machine
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 9
source: Test Driven Development for Embedded C, James W. Grenning.
Is it possible on small targets?
VIA University College
ICT-Engineering
SimplifiedDevelopmentProcess
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 10
Production
code
(.h,.c)
Cross
Compiler
Target Platform
Hardware
(registers etc.)
Hardware
API(.h)
Cross
Linker
11101
00011
00110
00111
Hardware
libsandothertargetlibs(.so)
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 11
Host
Compiler
Host Platform
Production
code
(.h,.c)
Hardware
API(.h)
Host
Linker
11101
00011
00110
00111
Host
Libs(.so)
ForcedIncludefiles
(.h)
Mock’sandTestCases
(.h,.c,.cpp)
Hardware
(registers etc.)
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
Forced include files:
– The pre-processor includes specified files before anything else is included
– We can add macros and definitions that
– Disable target hardware specific things
– Enable hardware fakes
Compiler/pre-processor options
– gcc option (gnu): –include <file to be included>
– cl option (Microsoft): /FI<file to be included>
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 12
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
All what’s needed to cheat the toolchain for the ATMEGA2560 MCU:
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 13
#include <stdint.h>
#define __AVR_LIBC_DEPRECATED_ENABLE__
#define __AVR_ATmega2560__
#define _AVR_SFR_DEFS_H_ 1
// 0x136 is highest address of registers in ATMEGA2560
#define _HIGHEST_REGISTER_ADD0x136
// These global variables (fake hardware registers) needs to be accessible from both C and C++
// Therefore they must be declared in C scope if it is the C++ compiler that access
#ifdef __cplusplus
extern "C" {
#endif
extern uint8_t __avr_reg[_HIGHEST_REGISTER_ADD];
#ifdef __cplusplus
}
#endif
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
All what’s needed to cheat the toolchain for an ATMEGA2560 MCU:
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 14
// Macros to access the fake hardware registers
#define _SFR_MEM8(mem_addr) (*(uint8_t *)(&__avr_reg[mem_addr]))
#define _SFR_IO8(io_addr) (*(uint8_t *)(&__avr_reg[io_addr]))
// Byte value from bit_no
#define _BV(bit) (1 << (bit))
// Interrupt
#define _AVR_INTERRUPT_H_
#define ISR(vector, ...) void ISR_##vector(void)
#define sei() SREG |= _BV(SREG_I)
#define cli() SREG &= ~_BV(SREG_I)
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
Test cases can now check contents of hardware registers
using a test macro: CHECK_EQUAL_C_BITS(expected, actual, mask)
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 15
TEST(TEST_HAL, ADPS2AndADPS1isSetAndADPS0isClearedInADCSRAAfterCreate)
{
CHECK_EQUAL_C_BITS(_BV(ADPS2)|_BV(ADPS1), ADCSRA, _BV(ADPS2) | _BV(ADPS1)|_BV(ADPS0));
}
TEST(TEST_HAL, get_voltageCalledWithCh15SetsMuxTo100111)
{
hal_get_voltage(15);
CHECK_EQUAL_C_BITS(_BV(MUX5), ADCSRB, _BV(MUX5));
CHECK_EQUAL_C_BITS(_BV(MUX2) | _BV(MUX1) | _BV(MUX0), ADMUX,
_BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0));
}
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
Test cases can check that bits in registers are set and read in right order
and return values can be controlled
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 16
TEST(TEST_HAL, get_voltageCalledSetsAndWaitsForADSCtoClear)
{
mock().expectOneCall("mock_set_bit").withPointerParameter("reg",
&ADCSRA).withIntParameter("bit_no", ADSC);
mock().expectNCalls(5,"mock_read_bit").withPointerParameter("reg",
&ADCSRA).withIntParameter("bit_no", ADSC).andReturnValue(_BV(ADSC));
mock().expectOneCall("mock_read_bit")
.withPointerParameter("reg"&ADCSRA).withIntParameter("bit_no", ADSC).andReturnValue(0);
hal_get_voltage(0);
}
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
The Mocks are injected via dependency injection:
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 17
// ---------------------------------------------------------------------------------------
uint8_t mock_read_bit(volatile uint8_t * reg, uint8_t bit_no)
{
mock().actualCall("mock_read_bit").withPointerParameter("reg", (void *)reg)
.withIntParameter("bit_no", bit_no);
return mock().returnIntValueOrDefault(0);
}
// --------------------------------------------------------------------------------------
void mock_set_bit(volatile uint8_t * reg, uint8_t bit_no)
{
// Production code function called
set_bit(reg, bit_no);
mock().actualCall("mock_set_bit").withPointerParameter("reg", (void *)reg)
.withIntParameter("bit_no", bit_no);
}
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
Test that calculations are correct in driver, faking hardware registers
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 18
TEST(TEST_HAL, get_voltageReturnsFullVRef)
{
// Given
ADCL = 0b11111111;
ADCH = 0b00000011;
// When
float result = hal_get_voltage(0);
// Then
float expected = ((ADCH << 8) + ADCL) * _V_REF / 1024;
CHECK_EQUAL_C_REAL(expected, result, 0.001);
}
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
Faking Interrupts
The Interrupt Service Routine (ISR ) in the production code:
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 19
ISR(INT0_vect)
{
PORTA = 0x55;
}
The macro that fakes it:
#define ISR(vector, ...) void ISR_##vector(void)
In the test cases the ISR is now turned into a normal function with the following
signature:
void ISR_INT0_vect(void)
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
Faking Interrupts
The Test that check that the ISR is doing what it is supposed to do
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 20
TEST(TEST_HAL, INT0ISRIsSettingPORTAto0x55)
{
ISR_INT0_vect(); // Fake INT0 Interrupt
CHECK_EQUAL_C_INT(0x55, PORTA);
}
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
What Test-cases to write:
Take a look at James W. Grenning’s ZOMBIES:
– Z – Zero
– O – One
– M – Many (or More complex)
– B – Boundary Behaviours
– I – Interface definition
– E – Exercise Exceptional behaviour
– S – Simple Scenarios, Simple Solutions
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 21
VIA University College
ICT-Engineering
TestDrivenDevelopmentinC
Pros:
– Production code can be developed at Host-computer
– Use all Host-computer tools and Debugger facilities
– Less errors and failures when moving to target computer
– Develop without the target hardware
Cons:
– It takes time to figure out how to get rid of the hardware dependencies in the
target tool-chain (One time only investment)
– Real-time aspects can’t be tested on the Host-computer
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 22
VIA University College
ICT-Engineering
Conclusion
– It is hard to develop low-level and hardware near software
– Invest time in setting up your tools and environment
(one time investment per platform)
– Use all the principles that we know from high-level development
(OOD/P)
– Document using UML and/or SysML
– TTD is possible and not very hard when tools are setup
– Software is easy and safe to maintain if it is well designed and the test
suite is up-to-date
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 23
VIA University College
ICT-Engineering
References
– CppUTest (open source): http://cpputest.github.io/index.html
– James W. Grenning, 2011: Test Driven Development for Embedded C, 1st Edition,
ISBN-13: 978-1934356623, ISBN-10: 9781934356623
– Axel Schreiner : Object-oriented Programming in ANSI-C
– Beck, K., 2002 Test Driven Development: By Example, ISBN-10: 9780321146533
ISBN-13: 978-0321146533
– Robert C. Martin, 2002: Agile Software Development, Principles, Patterns, and
Practices, ISBN10 0135974445 ISBN13 9780135974445
– James W. Grenning’s ZOMBIES: http://blog.wingman-sw.com/archives/677
2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 24

Object orientering, test driven development og c

  • 1.
    VIA University College ICT-Engineering Bringideastolife VIAUniversityCollege ObjectOrientering,TestDriven DevelopmentogC InfinIT,21. November 2018 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 1 Ib Havn B.Sc.E.E. M.Sc.ITSoftware Construction
  • 2.
    VIA University College ICT-Engineering Whatistheproblemswithhardwarenear programming? 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 2 – The nearer the hardware the testing difficulties grows – There are not much help from different tools – Errors/bugs are difficult to find – The software are target dependent – Design for Test is the solution – Debug Later Programming (DLP) vs Test Driven Development
  • 3.
    VIA University College ICT-Engineering Whydoweforgeteverythingwehave learnedwhenprogramminglow-levelC? Typicalexcuses: 1. Hardware near programming is for Electronics Engineers 2. The hardware is not available yet 3. It is not possible to test due to limited target resources – Test Driven Development (TDD) is not possible on the small target 4. Debugging facilities in the target toolchain is limited – Debugging is difficult and is done with oscilloscopes, leds, simple printouts etc. 5. UML is not useful for C-programming 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 3
  • 4.
    VIA University College ICT-Engineering ObjectOrientedDesignandProgramming inC Accordingto Robert C. Martin an OOP language has the following: 1. Encapsulation 2. Inheritance 3. Polymorphism The first two are easy to obtain in C, the third is a little harder 1. Abstract Data Types (ADT) 2. Nested struct’s 3. Pointer tables For a complete description how to do use three read Axel Schreiner’s book: Object-oriented Programming in ANSI-C 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 4
  • 5.
    VIA University College ICT-Engineering ExampleofcompleteEncapsulation inC 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 5
  • 6.
    VIA University College ICT-Engineering ExampleofcompleteEncapsulation inC 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 6 // Abstract Data Type (ADT) typedef struct serial_struct *serial_p; serial_p serial_new_instance(e_com_port_t com_port, uint32_t baud, e_data_bit_t data_bit, e_stop_bit_t stop_bit, e_parity_t parity, uint8_t rx_fifo_size, uint8_t tx_fifo_size, void(*handler_call_back )(serial_p, uint8_t)); e_serial_return_code_t serial_send_bytes(serial_p handle, uint8_t *buf, uint8_t len); e_serial_return_code_t serial_send_byte(serial_p handle, uint8_t byte); e_serial_return_code_t serial_get_byte(serial_p handle, uint8_t *byte); void serial_flush_rx_fifo(serial_p handle); void serial_flush_tx_fifo(serial_p handle); This is all the clients using the driver can see:
  • 7.
    VIA University College ICT-Engineering ObjectOrientedDesignandProgramming inC 2018-11-21ObjectOrientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 7 Why not use UML – A World wide Industry Standard
  • 8.
    VIA University College ICT-Engineering SOLIDDesignPrinciples RobertC. Martin has assembled these five more or less well-known principles together Single Responsibility Principle (SRP) – A class should have one, and only one, reason to change Open Close Principle (OCP) – You should be able to extend a class’s behaviour, without modifying it Liskov Substitution Principle (LSP) – Derived classes must be substitutables for their base classes Interface Segregation Principle (ISP) – Make fine grained interfaces that are client specific Dependency Inversion Principle (DIP) – Depend on abstractions, not on concretions 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 8
  • 9.
    VIA University College ICT-Engineering TestDrivenDevelopment(TDD) TDDState-machine 2018-11-21ObjectOrientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 9 source: Test Driven Development for Embedded C, James W. Grenning. Is it possible on small targets?
  • 10.
    VIA University College ICT-Engineering SimplifiedDevelopmentProcess 2018-11-21ObjectOrientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 10 Production code (.h,.c) Cross Compiler Target Platform Hardware (registers etc.) Hardware API(.h) Cross Linker 11101 00011 00110 00111 Hardware libsandothertargetlibs(.so)
  • 11.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC 2018-11-21ObjectOrientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 11 Host Compiler Host Platform Production code (.h,.c) Hardware API(.h) Host Linker 11101 00011 00110 00111 Host Libs(.so) ForcedIncludefiles (.h) Mock’sandTestCases (.h,.c,.cpp) Hardware (registers etc.)
  • 12.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC Forcedinclude files: – The pre-processor includes specified files before anything else is included – We can add macros and definitions that – Disable target hardware specific things – Enable hardware fakes Compiler/pre-processor options – gcc option (gnu): –include <file to be included> – cl option (Microsoft): /FI<file to be included> 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 12
  • 13.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC Allwhat’s needed to cheat the toolchain for the ATMEGA2560 MCU: 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 13 #include <stdint.h> #define __AVR_LIBC_DEPRECATED_ENABLE__ #define __AVR_ATmega2560__ #define _AVR_SFR_DEFS_H_ 1 // 0x136 is highest address of registers in ATMEGA2560 #define _HIGHEST_REGISTER_ADD0x136 // These global variables (fake hardware registers) needs to be accessible from both C and C++ // Therefore they must be declared in C scope if it is the C++ compiler that access #ifdef __cplusplus extern "C" { #endif extern uint8_t __avr_reg[_HIGHEST_REGISTER_ADD]; #ifdef __cplusplus } #endif
  • 14.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC Allwhat’s needed to cheat the toolchain for an ATMEGA2560 MCU: 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 14 // Macros to access the fake hardware registers #define _SFR_MEM8(mem_addr) (*(uint8_t *)(&__avr_reg[mem_addr])) #define _SFR_IO8(io_addr) (*(uint8_t *)(&__avr_reg[io_addr])) // Byte value from bit_no #define _BV(bit) (1 << (bit)) // Interrupt #define _AVR_INTERRUPT_H_ #define ISR(vector, ...) void ISR_##vector(void) #define sei() SREG |= _BV(SREG_I) #define cli() SREG &= ~_BV(SREG_I)
  • 15.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC Testcases can now check contents of hardware registers using a test macro: CHECK_EQUAL_C_BITS(expected, actual, mask) 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 15 TEST(TEST_HAL, ADPS2AndADPS1isSetAndADPS0isClearedInADCSRAAfterCreate) { CHECK_EQUAL_C_BITS(_BV(ADPS2)|_BV(ADPS1), ADCSRA, _BV(ADPS2) | _BV(ADPS1)|_BV(ADPS0)); } TEST(TEST_HAL, get_voltageCalledWithCh15SetsMuxTo100111) { hal_get_voltage(15); CHECK_EQUAL_C_BITS(_BV(MUX5), ADCSRB, _BV(MUX5)); CHECK_EQUAL_C_BITS(_BV(MUX2) | _BV(MUX1) | _BV(MUX0), ADMUX, _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1) | _BV(MUX0)); }
  • 16.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC Testcases can check that bits in registers are set and read in right order and return values can be controlled 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 16 TEST(TEST_HAL, get_voltageCalledSetsAndWaitsForADSCtoClear) { mock().expectOneCall("mock_set_bit").withPointerParameter("reg", &ADCSRA).withIntParameter("bit_no", ADSC); mock().expectNCalls(5,"mock_read_bit").withPointerParameter("reg", &ADCSRA).withIntParameter("bit_no", ADSC).andReturnValue(_BV(ADSC)); mock().expectOneCall("mock_read_bit") .withPointerParameter("reg"&ADCSRA).withIntParameter("bit_no", ADSC).andReturnValue(0); hal_get_voltage(0); }
  • 17.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC TheMocks are injected via dependency injection: 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 17 // --------------------------------------------------------------------------------------- uint8_t mock_read_bit(volatile uint8_t * reg, uint8_t bit_no) { mock().actualCall("mock_read_bit").withPointerParameter("reg", (void *)reg) .withIntParameter("bit_no", bit_no); return mock().returnIntValueOrDefault(0); } // -------------------------------------------------------------------------------------- void mock_set_bit(volatile uint8_t * reg, uint8_t bit_no) { // Production code function called set_bit(reg, bit_no); mock().actualCall("mock_set_bit").withPointerParameter("reg", (void *)reg) .withIntParameter("bit_no", bit_no); }
  • 18.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC Testthat calculations are correct in driver, faking hardware registers 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 18 TEST(TEST_HAL, get_voltageReturnsFullVRef) { // Given ADCL = 0b11111111; ADCH = 0b00000011; // When float result = hal_get_voltage(0); // Then float expected = ((ADCH << 8) + ADCL) * _V_REF / 1024; CHECK_EQUAL_C_REAL(expected, result, 0.001); }
  • 19.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC FakingInterrupts The Interrupt Service Routine (ISR ) in the production code: 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 19 ISR(INT0_vect) { PORTA = 0x55; } The macro that fakes it: #define ISR(vector, ...) void ISR_##vector(void) In the test cases the ISR is now turned into a normal function with the following signature: void ISR_INT0_vect(void)
  • 20.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC FakingInterrupts The Test that check that the ISR is doing what it is supposed to do 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 20 TEST(TEST_HAL, INT0ISRIsSettingPORTAto0x55) { ISR_INT0_vect(); // Fake INT0 Interrupt CHECK_EQUAL_C_INT(0x55, PORTA); }
  • 21.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC WhatTest-cases to write: Take a look at James W. Grenning’s ZOMBIES: – Z – Zero – O – One – M – Many (or More complex) – B – Boundary Behaviours – I – Interface definition – E – Exercise Exceptional behaviour – S – Simple Scenarios, Simple Solutions 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 21
  • 22.
    VIA University College ICT-Engineering TestDrivenDevelopmentinC Pros: –Production code can be developed at Host-computer – Use all Host-computer tools and Debugger facilities – Less errors and failures when moving to target computer – Develop without the target hardware Cons: – It takes time to figure out how to get rid of the hardware dependencies in the target tool-chain (One time only investment) – Real-time aspects can’t be tested on the Host-computer 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 22
  • 23.
    VIA University College ICT-Engineering Conclusion –It is hard to develop low-level and hardware near software – Invest time in setting up your tools and environment (one time investment per platform) – Use all the principles that we know from high-level development (OOD/P) – Document using UML and/or SysML – TTD is possible and not very hard when tools are setup – Software is easy and safe to maintain if it is well designed and the test suite is up-to-date 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 23
  • 24.
    VIA University College ICT-Engineering References –CppUTest (open source): http://cpputest.github.io/index.html – James W. Grenning, 2011: Test Driven Development for Embedded C, 1st Edition, ISBN-13: 978-1934356623, ISBN-10: 9781934356623 – Axel Schreiner : Object-oriented Programming in ANSI-C – Beck, K., 2002 Test Driven Development: By Example, ISBN-10: 9780321146533 ISBN-13: 978-0321146533 – Robert C. Martin, 2002: Agile Software Development, Principles, Patterns, and Practices, ISBN10 0135974445 ISBN13 9780135974445 – James W. Grenning’s ZOMBIES: http://blog.wingman-sw.com/archives/677 2018-11-21Object Orientering, Test Driven Development og C - InfinIT - Ib Havn, iha@via.dk 24