Browse Source

added some helper functions for out-of-bounds hecking & set/clear bits ledsImage;

added tests for new functionality
master
T. Meissner 9 years ago
parent
commit
2d6db40d74
4 changed files with 101 additions and 5 deletions
  1. +44
    -4
      tdd_for_embedded_c/chapter04/src/LedDriver.c
  2. +5
    -1
      tdd_for_embedded_c/chapter04/src/LedDriver.h
  3. +47
    -0
      tdd_for_embedded_c/chapter04/test/LedDriverTest.c
  4. +5
    -0
      tdd_for_embedded_c/chapter04/test/LedDriverTestRunner.c

+ 44
- 4
tdd_for_embedded_c/chapter04/src/LedDriver.c View File

@ -4,6 +4,7 @@
enum {ALL_LEDS_ON = ~0x0000, ALL_LEDS_OFF = ~ALL_LEDS_ON}; enum {ALL_LEDS_ON = ~0x0000, ALL_LEDS_OFF = ~ALL_LEDS_ON};
enum {FIRST_LED = 1, LAST_LED = 16};
static uint16_t *ledsAddress = NULL; // LEDs memory register location static uint16_t *ledsAddress = NULL; // LEDs memory register location
static uint16_t ledsImage; // internal variable to store LEDs state static uint16_t ledsImage; // internal variable to store LEDs state
@ -14,8 +15,24 @@ static uint16_t convertLedNumberToBit(int ledNumber) {
} }
static bool IsLedOutOfBound(int ledNumber) {
return (ledNumber < 1) || (ledNumber > 16);
}
static void SetLedImageBit(int ledNumber) {
ledsImage |= convertLedNumberToBit(ledNumber);
}
static void ClearLedImageBit(int ledNumber) {
ledsImage &= ~(convertLedNumberToBit(ledNumber));
}
static void updateHardware(void) { static void updateHardware(void) {
if(ledsAddress == NULL) { if(ledsAddress == NULL) {
RUNTIME_ERROR("LED Driver: NULL pointer access", -1);
return; return;
} }
*ledsAddress = ledsImage; *ledsAddress = ledsImage;
@ -23,6 +40,10 @@ static void updateHardware(void) {
void LedDriver_Create(uint16_t *address) { void LedDriver_Create(uint16_t *address) {
if(address == NULL) {
RUNTIME_ERROR("LED Driver: NULL pointer access", -1);
return;
}
ledsAddress = address; ledsAddress = address;
ledsImage = ALL_LEDS_OFF; ledsImage = ALL_LEDS_OFF;
updateHardware(); updateHardware();
@ -34,12 +55,12 @@ void LedDriver_Destroy(uint16_t *address) {
void LedDriver_TurnOn(int ledNumber) { void LedDriver_TurnOn(int ledNumber) {
if(ledNumber < 0 || ledNumber > 16) {
if (IsLedOutOfBound(ledNumber)) {
RUNTIME_ERROR("LED Driver: out-of-bounds LED", -1); RUNTIME_ERROR("LED Driver: out-of-bounds LED", -1);
return; return;
} }
ledsImage |= convertLedNumberToBit(ledNumber);
SetLedImageBit(ledNumber);
updateHardware(); updateHardware();
} }
@ -51,11 +72,30 @@ void LedDriver_TurnAllOn(void) {
void LedDriver_TurnOff(int ledNumber) { void LedDriver_TurnOff(int ledNumber) {
if(ledNumber < 0 || ledNumber > 16) {
if (IsLedOutOfBound(ledNumber)) {
RUNTIME_ERROR("LED Driver: out-of-bounds LED", -1); RUNTIME_ERROR("LED Driver: out-of-bounds LED", -1);
return; return;
} }
ledsImage &= ~(convertLedNumberToBit(ledNumber));
ClearLedImageBit(ledNumber);
updateHardware(); updateHardware();
} }
void LedDriver_TurnAllOff(void) {
ledsImage = ALL_LEDS_OFF;
updateHardware();
}
bool LedDriver_IsOn(int ledNumber) {
if(IsLedOutOfBound(ledNumber)) {
return false;
}
return ledsImage & 1 << (ledNumber - 1);
}
bool LedDriver_IsOff(int ledNumber) {
return !(LedDriver_IsOn(ledNumber));
}

+ 5
- 1
tdd_for_embedded_c/chapter04/src/LedDriver.h View File

@ -1,5 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
@ -7,4 +8,7 @@ void LedDriver_Create(uint16_t *address);
void LedDriver_Destroy(uint16_t *address); void LedDriver_Destroy(uint16_t *address);
void LedDriver_TurnOn(int ledNumber); void LedDriver_TurnOn(int ledNumber);
void LedDriver_TurnOff(int ledNumber); void LedDriver_TurnOff(int ledNumber);
void LedDriver_TurnAllOn(void);
void LedDriver_TurnAllOn(void);
void LedDriver_TurnAllOff(void);
bool LedDriver_IsOn(int ledNumber);
bool LedDriver_IsOff(int ledNumber);

+ 47
- 0
tdd_for_embedded_c/chapter04/test/LedDriverTest.c View File

@ -132,3 +132,50 @@ TEST(LedDriver, OutOfBoundsProducesRuntimeError) {
IGNORE_TEST(LedDriver, OutOfBoundsToDo) { IGNORE_TEST(LedDriver, OutOfBoundsToDo) {
/* TODO: what should we do during runtime? */ /* TODO: what should we do during runtime? */
} }
TEST(LedDriver, IsOn) {
TEST_ASSERT_FALSE(LedDriver_IsOn(11));
LedDriver_TurnOn(11);
TEST_ASSERT_TRUE(LedDriver_IsOn(11));
}
TEST(LedDriver, OutOfBoundsLedsAreAlwaysOff) {
TEST_ASSERT_TRUE(LedDriver_IsOff(0));
TEST_ASSERT_TRUE(LedDriver_IsOff(17));
TEST_ASSERT_FALSE(LedDriver_IsOn(0));
TEST_ASSERT_FALSE(LedDriver_IsOn(17));
}
TEST(LedDriver, IsOff) {
TEST_ASSERT_TRUE(LedDriver_IsOff(12));
LedDriver_TurnOn(12);
TEST_ASSERT_FALSE(LedDriver_IsOff(12));
}
TEST(LedDriver, TurnOffMultipleLeds) {
LedDriver_TurnAllOn();
LedDriver_TurnOff(9);
LedDriver_TurnOff(8);
TEST_ASSERT_EQUAL(~(0x0180) & 0xFFFF, virtualLeds);
}
TEST(LedDriver, TurnAllOff) {
LedDriver_TurnAllOn();
LedDriver_TurnAllOff();
TEST_ASSERT_EQUAL(0x0000, virtualLeds);
}

+ 5
- 0
tdd_for_embedded_c/chapter04/test/LedDriverTestRunner.c View File

@ -7,7 +7,9 @@ TEST_GROUP_RUNNER(LedDriver) {
RUN_TEST_CASE(LedDriver, TurnOnLedOne); RUN_TEST_CASE(LedDriver, TurnOnLedOne);
RUN_TEST_CASE(LedDriver, TurnOffLedOne); RUN_TEST_CASE(LedDriver, TurnOffLedOne);
RUN_TEST_CASE(LedDriver, TurnOnMultipleLeds); RUN_TEST_CASE(LedDriver, TurnOnMultipleLeds);
RUN_TEST_CASE(LedDriver, TurnOffMultipleLeds);
RUN_TEST_CASE(LedDriver, TurnAllOn); RUN_TEST_CASE(LedDriver, TurnAllOn);
RUN_TEST_CASE(LedDriver, TurnAllOff);
RUN_TEST_CASE(LedDriver, TurnOffAnyLed); RUN_TEST_CASE(LedDriver, TurnOffAnyLed);
RUN_TEST_CASE(LedDriver, LedMemoryIsNotReadable); RUN_TEST_CASE(LedDriver, LedMemoryIsNotReadable);
RUN_TEST_CASE(LedDriver, UpperAndLowerBounds); RUN_TEST_CASE(LedDriver, UpperAndLowerBounds);
@ -15,5 +17,8 @@ TEST_GROUP_RUNNER(LedDriver) {
RUN_TEST_CASE(LedDriver, OutOfBoundsTurnOffDoesNotHarm); RUN_TEST_CASE(LedDriver, OutOfBoundsTurnOffDoesNotHarm);
RUN_TEST_CASE(LedDriver, OutOfBoundsProducesRuntimeError); RUN_TEST_CASE(LedDriver, OutOfBoundsProducesRuntimeError);
RUN_TEST_CASE(LedDriver, OutOfBoundsToDo); RUN_TEST_CASE(LedDriver, OutOfBoundsToDo);
RUN_TEST_CASE(LedDriver, IsOn);
RUN_TEST_CASE(LedDriver, OutOfBoundsLedsAreAlwaysOff);
RUN_TEST_CASE(LedDriver, IsOff);
} }

Loading…
Cancel
Save