git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1082 35acf78f-673a-0410-8e92-d51de3d6d3f4

master
gdisirio 2009-08-19 13:11:25 +00:00
parent 0a59caa507
commit 45a6b7dc5a
15 changed files with 109 additions and 351 deletions

View File

@ -66,8 +66,9 @@ CSRC = ${PORTSRC} \
${KERNSRC} \ ${KERNSRC} \
${TESTSRC} \ ${TESTSRC} \
../../os/io/pal.c \ ../../os/io/pal.c \
../../os/io/serial.c \
../../os/ports/GCC/ARMCM3/STM32F103/pal_lld.c \ ../../os/ports/GCC/ARMCM3/STM32F103/pal_lld.c \
../../os/ports/GCC/ARMCM3/STM32F103/stm32_serial.c \ ../../os/ports/GCC/ARMCM3/STM32F103/serial_lld.c \
../../os/various/evtimer.c \ ../../os/various/evtimer.c \
board.c main.c board.c main.c

View File

@ -22,14 +22,14 @@
#include <nvic.h> #include <nvic.h>
#include "board.h" #include "board.h"
#include "stm32_serial.h" #include "serial.h"
#define AIRCR_VECTKEY 0x05FA0000 #define AIRCR_VECTKEY 0x05FA0000
/* /*
* Digital I/O ports static configuration as defined in @p board.h. * Digital I/O ports static configuration as defined in @p board.h.
*/ */
static const STM32GPIOConfig config = static const STM32GPIOConfig pal_config =
{ {
{VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH}, {VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH},
{VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH}, {VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH},
@ -83,7 +83,7 @@ void hwinit0(void) {
/* /*
* I/O ports initialization as specified in board.h. * I/O ports initialization as specified in board.h.
*/ */
palInit(&config); palInit(&pal_config);
} }
/* /*
@ -112,7 +112,7 @@ void hwinit1(void) {
/* /*
* Other subsystems initialization. * Other subsystems initialization.
*/ */
serial_init(0xC0, 0xC0, 0xC0); sd_lld_init();
/* /*
* ChibiOS/RT initialization. * ChibiOS/RT initialization.

View File

@ -232,16 +232,6 @@
#define CH_USE_QUEUES TRUE #define CH_USE_QUEUES TRUE
#endif #endif
/**
* If specified then the full duplex serial driver APIs are included in the
* kernel.
* @note The default is @p TRUE.
* @note Requires @p CH_USE_QUEUES.
*/
#if !defined(CH_USE_SERIAL_FULLDUPLEX) || defined(__DOXYGEN__)
#define CH_USE_SERIAL_FULLDUPLEX TRUE
#endif
/** /**
* If specified then the memory heap allocator APIs are included in the kernel. * If specified then the memory heap allocator APIs are included in the kernel.
* @note The default is @p TRUE. * @note The default is @p TRUE.

View File

@ -22,7 +22,7 @@
#include <test.h> #include <test.h>
#include "board.h" #include "board.h"
#include "stm32_serial.h" #include "serial.h"
/* /*
* Red LEDs blinker thread, times are in milliseconds. * Red LEDs blinker thread, times are in milliseconds.
@ -45,6 +45,11 @@ static msg_t Thread1(void *arg) {
*/ */
int main(int argc, char **argv) { int main(int argc, char **argv) {
/*
* Activates the communication port 2 using the driver default configuration.
*/
sdStart(&COM2, NULL);
/* /*
* Creates the blinker thread. * Creates the blinker thread.
*/ */

View File

@ -61,36 +61,10 @@ static size_t read(void *ip, uint8_t *buffer, size_t n) {
return chIQRead(&((SerialDriver *)ip)->d2.iqueue, buffer, n); return chIQRead(&((SerialDriver *)ip)->d2.iqueue, buffer, n);
} }
static void start(void *ip, const SerialDriverConfig *config) {
SerialDriver *sdp = (SerialDriver *)ip;
chSysLock();
sd_lld_start(sdp, config);
chSysUnlock();
}
/**
* @brief Stops the driver.
* @Details Any thread waiting on the driver's queues will be awakened with
* the message @p Q_RESET.
*
* @param sd The @p SerialDriver to be stopped.
*/
static void stop(void *ip) {
SerialDriver *sdp = (SerialDriver *)ip;
chSysLock();
sd_lld_stop(sdp);
chOQResetI(&sdp->d2.oqueue);
chIQResetI(&sdp->d2.iqueue);
chSchRescheduleS();
chSysUnlock();
}
static const struct SerialDriverVMT vmt = { static const struct SerialDriverVMT vmt = {
{putwouldblock, getwouldblock, put, get}, {putwouldblock, getwouldblock, put, get},
{write, read}, {write, read},
{start, stop} {}
}; };
/** /**
@ -112,8 +86,6 @@ static const struct SerialDriverVMT vmt = {
*/ */
void sdInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify) { void sdInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify) {
chDbgCheck(sdp != NULL, "sdInit");
sdp->vmt = &vmt; sdp->vmt = &vmt;
chEvtInit(&sdp->d1.ievent); chEvtInit(&sdp->d1.ievent);
chEvtInit(&sdp->d1.oevent); chEvtInit(&sdp->d1.oevent);
@ -123,6 +95,38 @@ void sdInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify) {
chOQInit(&sdp->d2.oqueue, sdp->d2.ob, SERIAL_BUFFERS_SIZE, onotify); chOQInit(&sdp->d2.oqueue, sdp->d2.ob, SERIAL_BUFFERS_SIZE, onotify);
} }
/**
* @brief Configures and starts the driver.
*
* @param[in] ip pointer to a @p SerialDriver or derived class
* @param[in] config the architecture-dependent serial driver configuration.
* If this parameter is set to @p NULL then a default
* configuration is used.
*/
void sdStart(SerialDriver *sdp, const SerialDriverConfig *config) {
chSysLock();
sd_lld_start(sdp, config);
chSysUnlock();
}
/**
* @brief Stops the driver.
* @Details Any thread waiting on the driver's queues will be awakened with
* the message @p Q_RESET.
*
* @param[in] ip pointer to a @p SerialDriver or derived class
*/
void sdStop(SerialDriver *sdp) {
chSysLock();
sd_lld_stop(sdp);
chOQResetI(&sdp->d2.oqueue);
chIQResetI(&sdp->d2.iqueue);
chSchRescheduleS();
chSysUnlock();
}
/** /**
* @brief Handles incoming data. * @brief Handles incoming data.
* @details This function must be called from the input interrupt service * @details This function must be called from the input interrupt service

View File

@ -50,22 +50,6 @@ typedef struct _SerialDriver SerialDriver;
* @brief @p SerialDriver specific methods. * @brief @p SerialDriver specific methods.
*/ */
struct _serial_driver_methods { struct _serial_driver_methods {
/**
* @brief Configures and starts the driver.
*
* @param[in] ip pointer to a @p SerialDriver or derived class
* @param[in] config The configuration record.
*/
void (*start)(void *ip, const SerialDriverConfig *config);
/**
* @brief Stops the driver.
* @Details Any thread waiting on the driver's queues will be awakened with
* the message @p Q_RESET.
*
* @param[in] ip pointer to a @p SerialDriver or derived class
*/
void (*stop)(void *ip);
}; };
/** /**
@ -115,11 +99,13 @@ struct _SerialDriver {
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void sdInit(SerialDriver *sd, qnotify_t inotify, qnotify_t onotify); void sdInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify);
void sdIncomingDataI(SerialDriver *sd, uint8_t b); void sdStart(SerialDriver *sdp, const SerialDriverConfig *config);
msg_t sdRequestDataI(SerialDriver *sd); void sdStop(SerialDriver *sdp);
void sdAddFlagsI(SerialDriver *sd, sdflags_t mask); void sdIncomingDataI(SerialDriver *sdp, uint8_t b);
sdflags_t sdGetAndClearFlags(SerialDriver *sd); msg_t sdRequestDataI(SerialDriver *sdp);
void sdAddFlagsI(SerialDriver *sdp, sdflags_t mask);
sdflags_t sdGetAndClearFlags(SerialDriver *sdp);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@ -131,7 +117,7 @@ extern "C" {
* be used to check different channels implementations. * be used to check different channels implementations.
* @see chIOPutWouldBlock() * @see chIOPutWouldBlock()
*/ */
#define sdPutWouldBlock(sd) chOQIsFull(&(sd)->d2.oqueue) #define sdPutWouldBlock(sdp) chOQIsFull(&(sdp)->d2.oqueue)
/** /**
* @brief Direct input check on a @p SerialDriver. * @brief Direct input check on a @p SerialDriver.
@ -140,7 +126,7 @@ extern "C" {
* be used to check different channels implementations. * be used to check different channels implementations.
* @see chIOGetWouldBlock() * @see chIOGetWouldBlock()
*/ */
#define sdGetWouldBlock(sd) chIQIsEmpty(&(sd)->d2.iqueue) #define sdGetWouldBlock(sdp) chIQIsEmpty(&(sdp)->d2.iqueue)
/** /**
* @brief Direct blocking write to a @p SerialDriver. * @brief Direct blocking write to a @p SerialDriver.
@ -149,7 +135,7 @@ extern "C" {
* be used to write to different channels implementations. * be used to write to different channels implementations.
* @see chIOPut() * @see chIOPut()
*/ */
#define sdPut(sd, b) chOQPut(&(sd)->d2.oqueue, b) #define sdPut(sdp, b) chOQPut(&(sdp)->d2.oqueue, b)
/** /**
* @brief Direct blocking write on a @p SerialDriver with timeout * @brief Direct blocking write on a @p SerialDriver with timeout
@ -159,7 +145,7 @@ extern "C" {
* be used to write to different channels implementations. * be used to write to different channels implementations.
* @see chIOPutTimeout() * @see chIOPutTimeout()
*/ */
#define sdPutTimeout(sd, b, t) chOQPutTimeout(&(sd)->d2.iqueue, b, t) #define sdPutTimeout(sdp, b, t) chOQPutTimeout(&(sdp)->d2.iqueue, b, t)
/** /**
* @brief Direct blocking read from a @p SerialDriver. * @brief Direct blocking read from a @p SerialDriver.
@ -168,7 +154,7 @@ extern "C" {
* be used to read from different channels implementations. * be used to read from different channels implementations.
* @see chIOGet() * @see chIOGet()
*/ */
#define sdGet(sd) chIQGet(&(sd)->d2.iqueue) #define sdGet(sdp) chIQGet(&(sdp)->d2.iqueue)
/** /**
* @brief Direct blocking read from a @p SerialDriver with timeout * @brief Direct blocking read from a @p SerialDriver with timeout
@ -178,7 +164,7 @@ extern "C" {
* be used to read from different channels implementations. * be used to read from different channels implementations.
* @see chIOGetTimeout() * @see chIOGetTimeout()
*/ */
#define sdGetTimeout(sd, t) chIQGetTimeout(&(sd)->d2.iqueue, t) #define sdGetTimeout(sdp, t) chIQGetTimeout(&(sdp)->d2.iqueue, t)
/** /**
* @brief Direct non-blocking write to a @p SerialDriver. * @brief Direct non-blocking write to a @p SerialDriver.
@ -187,7 +173,7 @@ extern "C" {
* be used to write from different channels implementations. * be used to write from different channels implementations.
* @see chIOWrite() * @see chIOWrite()
*/ */
#define sdWrite(sd, b, n) chOQWrite(&(sd)->d2.oqueue, b, n) #define sdWrite(sdp, b, n) chOQWrite(&(sdp)->d2.oqueue, b, n)
/** /**
* @brief Direct non-blocking read on a @p SerialDriver. * @brief Direct non-blocking read on a @p SerialDriver.
@ -196,7 +182,7 @@ extern "C" {
* be used to read from different channels implementations. * be used to read from different channels implementations.
* @see chIORead() * @see chIORead()
*/ */
#define sdRead(sd, b, n) chIQRead(&(sd)->d2.iqueue, b, n) #define sdRead(sdp, b, n) chIQRead(&(sdp)->d2.iqueue, b, n)
#endif /* _SERIAL_H_ */ #endif /* _SERIAL_H_ */

View File

@ -26,6 +26,10 @@
#include <ch.h> #include <ch.h>
/** @brief Driver default configuration.*/
static const SerialDriverConfig default_config = {
};
/*===========================================================================*/ /*===========================================================================*/
/* Low Level Driver local functions. */ /* Low Level Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -49,10 +53,15 @@ void sd_lld_init(void) {
* @brief Low level serial driver configuration and (re)start. * @brief Low level serial driver configuration and (re)start.
* *
* @param[in] sdp pointer to a @p SerialDriver object * @param[in] sdp pointer to a @p SerialDriver object
* @param[in] config the architecture-dependent serial driver configuration * @param[in] config the architecture-dependent serial driver configuration.
* If this parameter is set to @p NULL then a default
* configuration is used.
*/ */
void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) { void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) {
if (config == NULL)
config = &default_config;
} }
/** /**

View File

@ -45,6 +45,15 @@ SerialDriver COM2;
SerialDriver COM3; SerialDriver COM3;
#endif #endif
/** @brief Driver default configuration.*/
static const SerialDriverConfig default_config =
{
38400,
0,
USART_CR2_STOP1_BITS | USART_CR2_LINEN,
0
};
/*===========================================================================*/ /*===========================================================================*/
/* Low Level Driver local functions. */ /* Low Level Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
@ -222,10 +231,15 @@ void sd_lld_init(void) {
* @brief Low level serial driver configuration and (re)start. * @brief Low level serial driver configuration and (re)start.
* *
* @param[in] sdp pointer to a @p SerialDriver object * @param[in] sdp pointer to a @p SerialDriver object
* @param[in] config the architecture-dependent serial driver configuration * @param[in] config the architecture-dependent serial driver configuration.
* If this parameter is set to @p NULL then a default
* configuration is used.
*/ */
void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) { void sd_lld_start(SerialDriver *sdp, const SerialDriverConfig *config) {
if (config == NULL)
config = &default_config;
#if USE_STM32_USART1 #if USE_STM32_USART1
if (&COM1 == sdp) { if (&COM1 == sdp) {
RCC->APB2ENR |= RCC_APB2ENR_USART1EN; RCC->APB2ENR |= RCC_APB2ENR_USART1EN;

View File

@ -32,6 +32,7 @@
* *
* @param n the interrupt number * @param n the interrupt number
* @param prio the interrupt priority * @param prio the interrupt priority
*
* @note The parameters are not tested for correctness. * @note The parameters are not tested for correctness.
*/ */
void NVICEnableVector(uint32_t n, uint32_t prio) { void NVICEnableVector(uint32_t n, uint32_t prio) {
@ -41,6 +42,20 @@ void NVICEnableVector(uint32_t n, uint32_t prio) {
NVIC_ISER(n >> 5) = 1 << (n & 0x1F); NVIC_ISER(n >> 5) = 1 << (n & 0x1F);
} }
/**
* @brief Disables an interrupt handler.
*
* @param n the interrupt number
*
* @note The parameters are not tested for correctness.
*/
void NVICDisableVector(uint32_t n) {
unsigned sh = (n & 3) << 3;
NVIC_ICER(n >> 5) = 1 << (n & 0x1F);
NVIC_IPR(n >> 2) = NVIC_IPR(n >> 2) & ~(0xFF << sh);
}
/** /**
* @brief Changes the priority of a system handler. * @brief Changes the priority of a system handler.
* *

View File

@ -180,6 +180,7 @@ typedef struct {
extern "C" { extern "C" {
#endif #endif
void NVICEnableVector(uint32_t n, uint32_t prio); void NVICEnableVector(uint32_t n, uint32_t prio);
void NVICDisableVector(uint32_t n);
void NVICSetSystemHandlerPriority(uint32_t handler, uint32_t prio); void NVICSetSystemHandlerPriority(uint32_t handler, uint32_t prio);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -64,7 +64,11 @@ GNU-Linux-GCC - ChibiOS/RT simulator for x86 Linux systems, it is
***************************************************************************** *****************************************************************************
*** 1.3.2 *** *** 1.3.2 ***
- NEW: Reorganized and rationalized the distribution three. - NEW: Reorganized and rationalized the distribution tree.
- NEW: Enhanced serial driver. The driver now supports speed change at runtime
and low power stop mode.
- NEW: Serial driver removed from the kernel and added to the I/O subsystems
together with PAL.
- NEW: Added standard CMSIS 1.2.0 support to the Cortex-M3 port. The kernel - NEW: Added standard CMSIS 1.2.0 support to the Cortex-M3 port. The kernel
does not use it (the OS uses its own optimized code) but the functionality does not use it (the OS uses its own optimized code) but the functionality
is available to the applications. The CMSIS files were patched in order is available to the applications. The CMSIS files were patched in order
@ -72,6 +76,8 @@ GNU-Linux-GCC - ChibiOS/RT simulator for x86 Linux systems, it is
- NEW: Updated the STM32 port to use the newest ST firmware library files - NEW: Updated the STM32 port to use the newest ST firmware library files
(version 3.1.0). Note that now the ST drivers are included in the STM32 (version 3.1.0). Note that now the ST drivers are included in the STM32
demo directory. demo directory.
- CHANGE: Removed the CH_USE_SERIAL_FULLDUPLEX configuration option because
the serial driver is no more part of the kernel.
*** 1.3.1 *** *** 1.3.1 ***
- FIX: Removed mention of an obsolete option from the documentation (bug - FIX: Removed mention of an obsolete option from the documentation (bug

View File

@ -30,7 +30,6 @@
#include "testpools.h" #include "testpools.h"
#include "testdyn.h" #include "testdyn.h"
#include "testqueues.h" #include "testqueues.h"
#include "testserial.h"
#include "testbmk.h" #include "testbmk.h"
/* /*
@ -47,7 +46,6 @@ static const struct testcase **patterns[] = {
patternpools, patternpools,
patterndyn, patterndyn,
patternqueues, patternqueues,
patternserial,
patternbmk, patternbmk,
NULL NULL
}; };

View File

@ -4,8 +4,7 @@ TESTSRC = ../../test/test.c ../../test/testthd.c \
../../test/testmsg.c ../../test/testmbox.c \ ../../test/testmsg.c ../../test/testmbox.c \
../../test/testevt.c ../../test/testheap.c \ ../../test/testevt.c ../../test/testheap.c \
../../test/testpools.c ../../test/testdyn.c \ ../../test/testpools.c ../../test/testdyn.c \
../../test/testqueues.c ../../test/testserial.c \ ../../test/testqueues.c ../../test/testbmk.c
../../test/testbmk.c
# Required include directories # Required include directories
TESTINC = ../../test TESTINC = ../../test

View File

@ -1,245 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <ch.h>
#include "test.h"
/**
* @page test_serial Serial Drivers test
*
* <h2>Description</h2>
* This module implements the test sequence for the @ref Serial subsystem.
* The tests are performed on a loopback software serial driver where a
* dedicated thread echoes back in the input queue the data read from the
* output queue at a fixed rate. The test module also tests implicitly the
* channels code.
*
* <h2>Objective</h2>
* Objective of the test module is to cover 100% of the @ref Serial code
* as a necessary step in order to assess its maturity level.<br>
* Note that the @ref Serial subsystem depends on the @ref Semaphores and
* @ref Events subsystems that have to met their testing objectives as well.
*
* <h2>Preconditions</h2>
* The module requires the following kernel options:
* - @p CH_USE_SERIAL_FULLDUPLEX
* .
* In case some of the required options are not enabled then some or all tests
* may be skipped.
*
*
* <h2>Test Cases</h2>
* - @subpage test_serial_001
* - @subpage test_serial_002
* .
* @file testserial.c
* @brief Serial Driver test source file
* @file testserial.h
* @brief Serial Driver test header file
*/
#if CH_USE_SERIAL_FULLDUPLEX
#define TEST_QUEUES_SIZE 8
static FullDuplexDriver fdd;
/* Loopback thread, it simulates a low level driver. The thread terminates by
sending a zero through the loopback driver.*/
static msg_t thread1(void *p) {
while (TRUE) {
chEvtWaitAny(1);
chSysLock();
while (TRUE) {
msg_t b = chFDDRequestDataI(&fdd);
if (b < Q_OK)
break;
if (b == 0) {
chSchRescheduleS();
chSysUnlock();
return 0;
}
chFDDIncomingDataI(&fdd, (uint8_t)b);
chSchRescheduleS();
}
chSysUnlock();
}
}
static void infy(void) {}
static void onfy(void) {
chEvtSignalI(threads[0], 1);
chSchRescheduleS();
}
/**
* @page test_serial_001 Synchronous loopback
*
* <h2>Description</h2>
* A sequence of characters are sent to the loopback driver and read back. The
* test is performed twice using both the direct APIs and the channels API
* implementations.<br>
* The test expects to read all the characters back and in the correct
* sequence.
*/
static char *serial1_gettest(void) {
return "Serial driver, synchronous";
}
static void serial1_setup(void) {
/* Initializes the loopback driver.*/
chFDDInit(&fdd, wa[3], 8, infy, wa[4], 8, onfy);
/* Starts the loopback thread.*/
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() + 1,
thread1, 0);
}
static void serial1_teardown(void) {
/* Terminates the loopback thread.*/
chFDDPut(&fdd, 0);
}
static void serial1_execute(void) {
unsigned i;
msg_t b;
/* Loopback test using the direct APIs.*/
for (i = 0; i < 4; i++) {
chFDDPut(&fdd, 'A' + i);
b = chFDDGetTimeout(&fdd, S2ST(1));
if (b < Q_OK)
break;
test_emit_token(b);
}
test_assert_sequence(1, "ABCD");
test_assert(2, chFDDPutWouldBlock(&fdd) == FALSE, "output would block");
test_assert(3, chFDDGetWouldBlock(&fdd) == TRUE, "input would not block");
/* Loopback test using the channel APIs.*/
for (i = 0; i < 4; i++) {
chIOPut(&fdd, 'A' + i);
b = chIOGetTimeout(&fdd, S2ST(1));
if (b < Q_OK)
break;
test_emit_token(b);
}
test_assert_sequence(4, "ABCD");
test_assert(5, chIOPutWouldBlock(&fdd) == FALSE, "output would block");
test_assert(6, chIOGetWouldBlock(&fdd) == TRUE, "input would not block");
}
const struct testcase testserial1 = {
serial1_gettest,
serial1_setup,
serial1_teardown,
serial1_execute
};
/**
* @page test_serial_002 Asynchronous loopback
*
* <h2>Description</h2>
* A sequence of characters are sent to the loopback driver using the
* asynchronous APIs and then read back. The test is performed twice using
* both the direct APIs and the channels API. An input queue overflow test
* is performed too.<br>
* The test expects that the queues are filled and emptied as expected and that
* the overflow error condition is reported when expected.
*/
static char *serial2_gettest(void) {
return "Serial driver, asynchronous";
}
static void serial2_setup(void) {
/* Initializes the loopback driver.*/
chFDDInit(&fdd, wa[3], 8, infy, wa[4], 8, onfy);
/* Starts the loopback thread.*/
threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority() + 1,
thread1, 0);
}
static void serial2_teardown(void) {
/* Terminates the loopback thread.*/
chFDDPut(&fdd, 0);
}
static void serial2_execute(void) {
size_t n;
dflags_t flags;
/* Asynchronous test using the direct APIs.*/
n = chFDDWrite(&fdd, (uint8_t *)"ABCDEFGH", TEST_QUEUES_SIZE);
test_assert(1, n == TEST_QUEUES_SIZE, "unexpected write condition");
n = chFDDRead(&fdd, wa[1], TEST_QUEUES_SIZE);
test_assert(2, n == TEST_QUEUES_SIZE, "unexpected read condition");
test_assert(2, chFDDPutWouldBlock(&fdd) == FALSE, "output would block");
test_assert(3, chFDDGetWouldBlock(&fdd) == TRUE, "input would not block");
flags = chFDDGetAndClearFlags(&fdd);
test_assert(4, flags == 0, "unexpected error condition");
/* Input overflow testing.*/
n = chFDDWrite(&fdd, (uint8_t *)"ABCDEFGH", TEST_QUEUES_SIZE);
test_assert(5, n == TEST_QUEUES_SIZE, "unexpected write condition");
/* The following operation will fail to loopback because the input queue
* is full.*/
chFDDPut(&fdd, 'Z');
flags = chFDDGetAndClearFlags(&fdd);
test_assert(6, flags == SD_OVERRUN_ERROR, "unexpected error condition");
n = chFDDRead(&fdd, wa[1], TEST_QUEUES_SIZE);
test_assert(7, n == TEST_QUEUES_SIZE, "unexpected read condition");
/* Asynchronous test using the channel APIs.*/
n = chIOWrite(&fdd, (uint8_t *)"ABCDEFGH", TEST_QUEUES_SIZE);
test_assert(8, n == TEST_QUEUES_SIZE, "unexpected write condition");
n = chIORead(&fdd, wa[1], TEST_QUEUES_SIZE);
test_assert(9, n == TEST_QUEUES_SIZE, "unexpected read condition");
test_assert(10, chIOPutWouldBlock(&fdd) == FALSE, "output would block");
test_assert(11, chIOGetWouldBlock(&fdd) == TRUE, "input would not block");
}
const struct testcase testserial2 = {
serial2_gettest,
serial2_setup,
serial2_teardown,
serial2_execute
};
#endif /* CH_USE_SERIAL_FULLDUPLEX */
/*
* Test sequence for queues pattern.
*/
const struct testcase * const patternserial[] = {
#if CH_USE_SERIAL_FULLDUPLEX
&testserial1,
&testserial2,
#endif
NULL
};

View File

@ -1,25 +0,0 @@
/*
ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TESTSERIAL_H_
#define _TESTSERIAL_H_
extern const struct testcase *patternserial[];
#endif /* _TESTSERIAL_H_ */