git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1082 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
0a59caa507
commit
45a6b7dc5a
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
};
|
|
|
@ -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_ */
|
|
Loading…
Reference in New Issue