tests: gadget0: delay between calls to trigger races

Attempt to be more brutal by delaying more often, instead of always
promptly servicing the usb stack.

This is implemented via using timer6 to do a known number of
microseconds busy delay, and so only works on platforms that have
reached at least core timer functionality, and provide the
rcc_apb1_frequency variable.

NOTE! This will _fail_ on devices using the st_usbfs drivers at present,
but the code _should_ work, and the tests land to verify that the
library fix, fixes the problem. (see subsequent commit)
This commit is contained in:
Karl Palsson 2017-05-01 17:22:24 +00:00
parent e652121931
commit d97c1b0435
17 changed files with 122 additions and 6 deletions

View File

@ -23,6 +23,7 @@ SHARED_DIR = ../shared
CFILES = main-$(BOARD).c
CFILES += usb-gadget0.c
CFILES += delay.c
VPATH += $(SHARED_DIR)

View File

@ -23,6 +23,7 @@ SHARED_DIR = ../shared
CFILES = main-$(BOARD).c
CFILES += usb-gadget0.c trace.c trace_stdio.c
CFILES += delay.c
VPATH += $(SHARED_DIR)

View File

@ -23,6 +23,7 @@ SHARED_DIR = ../shared
CFILES = main-$(BOARD).c
CFILES += usb-gadget0.c trace.c trace_stdio.c
CFILES += delay.c
VPATH += $(SHARED_DIR)

View File

@ -23,6 +23,7 @@ SHARED_DIR = ../shared
CFILES = main-$(BOARD).c
CFILES += usb-gadget0.c trace.c trace_stdio.c
CFILES += delay.c
VPATH += $(SHARED_DIR)

View File

@ -23,6 +23,7 @@ SHARED_DIR = ../shared
CFILES = main-$(BOARD).c
CFILES += usb-gadget0.c
CFILES += delay.c
VPATH += $(SHARED_DIR)

View File

@ -23,6 +23,7 @@ SHARED_DIR = ../shared
CFILES = main-$(BOARD).c
CFILES += usb-gadget0.c trace.c trace_stdio.c
CFILES += delay.c
VPATH += $(SHARED_DIR)

View File

@ -40,6 +40,11 @@ Ran 27 tests in 0.388s
OK (skipped=2)
```
To be even more brutal, run this in a shell loop.
```
$ while true; do python test_gadget0.py stm32f072disco; done
```
You can also run individual tests, or individual sets of tests, see the [unittest documentation](https://docs.python.org/3/library/unittest.html) for more information.
Many development environments, such as [PyCharm](https://www.jetbrains.com/pycharm/) can

50
tests/gadget-zero/delay.c Normal file
View File

@ -0,0 +1,50 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2017 Karl Palsson <karlp@tweak.net.au>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This file implements some simple busy timers. They are designed to be
* portable, not performant.
* TIM6 is appropriated for usage.
*/
#include <stdint.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/timer.h>
#include "delay.h"
void delay_setup(void)
{
/* set up a microsecond free running timer for ... things... */
rcc_periph_clock_enable(RCC_TIM6);
/* microsecond counter */
timer_set_prescaler(TIM6, rcc_apb1_frequency / 1e6 - 1);
timer_set_period(TIM6, 0xffff);
timer_one_shot_mode(TIM6);
}
void delay_us(uint16_t us)
{
TIM_ARR(TIM6) = us;
TIM_EGR(TIM6) = TIM_EGR_UG;
TIM_CR1(TIM6) |= TIM_CR1_CEN;
//timer_enable_counter(TIM6);
while (TIM_CR1(TIM6) & TIM_CR1_CEN);
}

39
tests/gadget-zero/delay.h Normal file
View File

@ -0,0 +1,39 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2017 Karl Palsson <karlp@tweak.net.au>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize the timers used for delays.
*/
void delay_setup(void);
/**
* busy wait for a number of usecs.
* @param us number of usecs to delay.
*/
void delay_us(uint16_t us);
#ifdef __cplusplus
}
#endif

View File

@ -59,7 +59,7 @@ int main(void)
ER_DPRINTF("bootup complete\n");
gpio_clear(GPIOC, GPIO7);
while (1) {
usbd_poll(usbd_dev);
gadget0_run(usbd_dev);
}
}

View File

@ -64,7 +64,7 @@ int main(void)
ER_DPRINTF("bootup complete\n");
gpio_clear(GPIOC, GPIO13);
while (1) {
usbd_poll(usbd_dev);
gadget0_run(usbd_dev);
}
}

View File

@ -52,7 +52,7 @@ int main(void)
ER_DPRINTF("bootup complete\n");
while (1) {
usbd_poll(usbd_dev);
gadget0_run(usbd_dev);
}
}

View File

@ -52,7 +52,7 @@ int main(void)
ER_DPRINTF("bootup complete\n");
while (1) {
usbd_poll(usbd_dev);
gadget0_run(usbd_dev);
}
}

View File

@ -83,7 +83,7 @@ int main(void)
ER_DPRINTF("bootup complete\n");
gpio_clear(GPIOA, GPIO5);
while (1) {
usbd_poll(usbd_dev);
gadget0_run(usbd_dev);
}
}

View File

@ -63,7 +63,7 @@ int main(void)
ER_DPRINTF("bootup complete\n");
gpio_clear(GPIOB, GPIO1);
while (1) {
usbd_poll(usbd_dev);
gadget0_run(usbd_dev);
}
}

View File

@ -28,6 +28,7 @@
#include <libopencm3/usb/usbd.h>
#include "trace.h"
#include "delay.h"
#include "usb-gadget0.h"
#define ER_DEBUG
@ -343,6 +344,14 @@ usbd_device *gadget0_init(const usbd_driver *driver, const char *userserial)
usbd_control_buffer, sizeof(usbd_control_buffer));
usbd_register_set_config_callback(our_dev, gadget0_set_config);
delay_setup();
return our_dev;
}
void gadget0_run(usbd_device *usbd_dev)
{
usbd_poll(usbd_dev);
/* This should be more than allowable! */
delay_us(100);
}

View File

@ -32,4 +32,11 @@
*/
usbd_device *gadget0_init(const usbd_driver *driver, const char *userserial);
/**
* Call this forever.
* @param usbd_dev the object returned in _init.
* @sa gadget0_init
*/
void gadget0_run(usbd_device *usbd_dev);
#endif