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

This commit is contained in:
gdisirio 2014-11-03 14:07:06 +00:00
parent fb68952e20
commit 8b0021db47
11 changed files with 1377 additions and 152 deletions

View File

@ -0,0 +1,134 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file console.c
* @brief Simulator console driver code.
* @{
*/
#include <stdio.h>
#include "ch.h"
#include "hal.h"
#include "console.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief Console driver 1.
*/
BaseChannel CD1;
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static size_t write(void *ip, const uint8_t *bp, size_t n) {
size_t ret;
(void)ip;
ret = fwrite(bp, 1, n, stdout);
fflush(stdout);
return ret;
}
static size_t read(void *ip, uint8_t *bp, size_t n) {
(void)ip;
return fread(bp, 1, n, stdin);
}
static msg_t put(void *ip, uint8_t b) {
(void)ip;
fputc(b, stdout);
fflush(stdout);
return MSG_OK;
}
static msg_t get(void *ip) {
(void)ip;
return fgetc(stdin);
}
static msg_t putt(void *ip, uint8_t b, systime_t time) {
(void)ip;
(void)time;
fputc(b, stdout);
fflush(stdout);
return MSG_OK;
}
static msg_t gett(void *ip, systime_t time) {
(void)ip;
(void)time;
return fgetc(stdin);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
size_t ret;
(void)ip;
(void)time;
ret = fwrite(bp, 1, n, stdout);
fflush(stdout);
return ret;
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
(void)ip;
(void)time;
return fread(bp, 1, n, stdin);
}
static const struct BaseChannelVMT vmt = {
write, read, put, get,
putt, gett, writet, readt
};
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
void conInit(void) {
CD1.vmt = &vmt;
}
/** @} */

View File

@ -0,0 +1,62 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file console.h
* @brief Simulator console driver header.
* @{
*/
#ifndef _CONSOLE_H_
#define _CONSOLE_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
extern BaseChannel CD1;
#ifdef __cplusplus
extern "C" {
#endif
void conInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _CONSOLE_H_ */
/** @} */

View File

@ -0,0 +1,94 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file pal_lld.c
* @brief Win32 simulator low level PAL driver code.
*
* @addtogroup WIN32_PAL
* @{
*/
#include "hal.h"
#if HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief VIO1 simulated port.
*/
sim_vio_port_t vio_port_1;
/**
* @brief VIO2 simulated port.
*/
sim_vio_port_t vio_port_2;
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high
* state.
* @note This function does not alter the @p PINSELx registers. Alternate
* functions setup must be handled by device-specific code.
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode) {
switch (mode) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT:
port->dir &= ~mask;
break;
case PAL_MODE_UNCONNECTED:
port->latch |= mask;
case PAL_MODE_OUTPUT_PUSHPULL:
port->dir |= mask;
break;
}
}
#endif /* HAL_USE_PAL */
/** @} */

View File

@ -0,0 +1,206 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file pal_lld.h
* @brief Win32 simulator low level PAL driver header.
*
* @addtogroup WIN32_PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
#undef PAL_MODE_INPUT_PULLUP
#undef PAL_MODE_INPUT_PULLDOWN
#undef PAL_MODE_OUTPUT_OPENDRAIN
#undef PAL_MODE_INPUT_ANALOG
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @brief VIO port structure.
*/
typedef struct {
/**
* @brief VIO_LATCH register.
* @details This register represents the output latch of the VIO port.
*/
uint32_t latch;
/**
* @brief VIO_PIN register.
* @details This register represents the logical level at the VIO port
* pin level.
*/
uint32_t pin;
/**
* @brief VIO_DIR register.
* @details Direction of the VIO port bits, 0=input, 1=output.
*/
uint32_t dir;
} sim_vio_port_t;
/**
* @brief Virtual I/O ports static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized the digital I/O
* subsystem. This represents only the initial setup, specific pads
* or whole ports can be reprogrammed at later time.
*/
typedef struct {
/**
* @brief Virtual port 1 setup data.
*/
sim_vio_port_t VP1Data;
/**
* @brief Virtual port 2 setup data.
*/
sim_vio_port_t VP2Data;
} PALConfig;
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32
/**
* @brief Whole port mask.
* @brief This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFF)
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Digital I/O modes.
*/
typedef uint32_t iomode_t;
/**
* @brief Port Identifier.
*/
typedef sim_vio_port_t *ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief VIO port 1 identifier.
*/
#define IOPORT1 (&vio_port_1)
/**
* @brief VIO port 2 identifier.
*/
#define IOPORT2 (&vio_port_2)
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @param[in] config architecture-dependent ports configuration
*
* @notapi
*/
#define pal_lld_init(config) \
(vio_port_1 = (config)->VP1Data, \
vio_port_2 = (config)->VP2Data)
/**
* @brief Reads the physical I/O port states.
*
* @param[in] port port identifier
* @return The port bits.
*
* @notapi
*/
#define pal_lld_readport(port) ((port)->pin)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
*
* @param[in] port port identifier
* @return The latched logical states.
*
* @notapi
*/
#define pal_lld_readlatch(port) ((port)->latch)
/**
* @brief Writes a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*
* @notapi
*/
#define pal_lld_writeport(port, bits) ((port)->latch = (bits))
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] mode group mode
*
* @notapi
*/
#define pal_lld_setgroupmode(port, mask, offset, mode) \
_pal_lld_setgroupmode(port, mask << offset, mode)
#if !defined(__DOXYGEN__)
extern sim_vio_port_t vio_port_1;
extern sim_vio_port_t vio_port_2;
extern const PALConfig pal_default_config;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
iomode_t mode);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_PAL */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@ -0,0 +1,110 @@
/*
ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_lld.c
* @brief WIN32 simulator HAL subsystem low level driver code.
*
* @addtogroup WIN32_HAL
* @{
*/
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
static LARGE_INTEGER nextcnt;
static LARGE_INTEGER slice;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
WSADATA wsaData;
/* Initialization.*/
if (WSAStartup(2, &wsaData) != 0) {
printf("Unable to locate a winsock DLL\n");
exit(1);
}
printf("ChibiOS/RT simulator (Win32)\n");
if (!QueryPerformanceFrequency(&slice)) {
printf("QueryPerformanceFrequency() error");
exit(1);
}
slice.QuadPart /= CH_FREQUENCY;
QueryPerformanceCounter(&nextcnt);
nextcnt.QuadPart += slice.QuadPart;
fflush(stdout);
}
/**
* @brief Interrupt simulation.
*/
void _sim_check_for_interrupts(void) {
LARGE_INTEGER n;
#if HAL_USE_SERIAL
if (sd_lld_interrupt_pending()) {
dbg_check_lock();
if (chSchIsPreemptionRequired())
chSchDoReschedule();
dbg_check_unlock();
return;
}
#endif
/* Interrupt Timer simulation (10ms interval).*/
QueryPerformanceCounter(&n);
if (n.QuadPart > nextcnt.QuadPart) {
nextcnt.QuadPart += slice.QuadPart;
CH_IRQ_PROLOGUE();
chSysLockFromISR();
chSysTimerHandlerI();
chSysUnlockFromISR();
CH_IRQ_EPILOGUE();
dbg_check_lock();
if (chSchIsPreemptionRequired())
chSchDoReschedule();
dbg_check_unlock();
}
}
/** @} */

View File

@ -0,0 +1,67 @@
/*
ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file hal_lld.h
* @brief WIN32 simulator HAL subsystem low level driver header.
*
* @addtogroup WIN32_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include <windows.h>
#include <stdio.h>
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "Win32 Simulator"
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void _sim_check_for_interrupts(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@ -0,0 +1,8 @@
# List of all the Win32 platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/ports/simulator/win32/hal_lld.c \
${CHIBIOS}/os/hal/ports/simulator/win32/serial_lld.c \
${CHIBIOS}/os/hal/ports/simulator/pal_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/ports/simulator/win32 \
${CHIBIOS}/os/hal/ports/simulator

View File

@ -0,0 +1,278 @@
/*
ChibiOS/HAL - Copyright (C) 2006-2014 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file serial_lld.c
* @brief Win32 simulator low level serial driver code.
*
* @addtogroup WIN32_SERIAL
* @{
*/
#include "hal.h"
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief Serial driver 1 identifier.*/
#if USE_WIN32_SERIAL1 || defined(__DOXYGEN__)
SerialDriver SD1;
#endif
/** @brief Serial driver 2 identifier.*/
#if USE_WIN32_SERIAL2 || defined(__DOXYGEN__)
SerialDriver SD2;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/** @brief Driver default configuration.*/
static const SerialConfig default_config = {
};
static u_long nb = 1;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void init(SerialDriver *sdp, uint16_t port) {
struct sockaddr_in sad;
struct protoent *prtp;
if ((prtp = getprotobyname("tcp")) == NULL) {
printf("%s: Error mapping protocol name to protocol number\n", sdp->com_name);
goto abort;
}
sdp->com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
if (sdp->com_listen == INVALID_SOCKET) {
printf("%s: Error creating simulator socket\n", sdp->com_name);
goto abort;
}
if (ioctlsocket(sdp->com_listen, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on socket\n", sdp->com_name);
goto abort;
}
memset(&sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons(port);
if (bind(sdp->com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
printf("%s: Error binding socket\n", sdp->com_name);
goto abort;
}
if (listen(sdp->com_listen, 1) != 0) {
printf("%s: Error listening socket\n", sdp->com_name);
goto abort;
}
printf("Full Duplex Channel %s listening on port %d\n", sdp->com_name, port);
return;
abort:
if (sdp->com_listen != INVALID_SOCKET)
closesocket(sdp->com_listen);
WSACleanup();
exit(1);
}
static bool connint(SerialDriver *sdp) {
if (sdp->com_data == INVALID_SOCKET) {
struct sockaddr addr;
int addrlen = sizeof(addr);
if ((sdp->com_data = accept(sdp->com_listen, &addr, &addrlen)) == INVALID_SOCKET)
return FALSE;
if (ioctlsocket(sdp->com_data, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on data socket\n", sdp->com_name);
goto abort;
}
chSysLockFromISR();
chnAddFlagsI(sdp, CHN_CONNECTED);
chSysUnlockFromISR();
return TRUE;
}
return FALSE;
abort:
if (sdp->com_listen != INVALID_SOCKET)
closesocket(sdp->com_listen);
if (sdp->com_data != INVALID_SOCKET)
closesocket(sdp->com_data);
WSACleanup();
exit(1);
}
static bool inint(SerialDriver *sdp) {
if (sdp->com_data != INVALID_SOCKET) {
int i;
uint8_t data[32];
/*
* Input.
*/
int n = recv(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
chSysLockFromISR();
chnAddFlagsI(sdp, CHN_DISCONNECTED);
chSysUnlockFromISR();
return FALSE;
case SOCKET_ERROR:
if (WSAGetLastError() == WSAEWOULDBLOCK)
return FALSE;
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
for (i = 0; i < n; i++) {
chSysLockFromISR();
sdIncomingDataI(sdp, data[i]);
chSysUnlockFromISR();
}
return TRUE;
}
return FALSE;
}
static bool outint(SerialDriver *sdp) {
if (sdp->com_data != INVALID_SOCKET) {
int n;
uint8_t data[1];
/*
* Input.
*/
chSysLockFromISR();
n = sdRequestDataI(sdp);
chSysUnlockFromISR();
if (n < 0)
return FALSE;
data[0] = (uint8_t)n;
n = send(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
chSysLockFromISR();
chnAddFlagsI(sdp, CHN_DISCONNECTED);
chSysUnlockFromISR();
return FALSE;
case SOCKET_ERROR:
if (WSAGetLastError() == WSAEWOULDBLOCK)
return FALSE;
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
return TRUE;
}
return FALSE;
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_WIN32_SERIAL1
sdObjectInit(&SD1, NULL, NULL);
SD1.com_listen = INVALID_SOCKET;
SD1.com_data = INVALID_SOCKET;
SD1.com_name = "SD1";
#endif
#if USE_WIN32_SERIAL1
sdObjectInit(&SD2, NULL, NULL);
SD2.com_listen = INVALID_SOCKET;
SD2.com_data = INVALID_SOCKET;
SD2.com_name = "SD2";
#endif
}
/**
* @brief Low level serial driver configuration and (re)start.
*
* @param[in] sdp pointer to a @p SerialDriver object
* @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 SerialConfig *config) {
if (config == NULL)
config = &default_config;
#if USE_WIN32_SERIAL1
if (sdp == &SD1)
init(&SD1, SD1_PORT);
#endif
#if USE_WIN32_SERIAL1
if (sdp == &SD2)
init(&SD2, SD2_PORT);
#endif
}
/**
* @brief Low level serial driver stop.
* @details De-initializes the USART, stops the associated clock, resets the
* interrupt vector.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
void sd_lld_stop(SerialDriver *sdp) {
(void)sdp;
}
bool sd_lld_interrupt_pending(void) {
bool b;
CH_IRQ_PROLOGUE();
b = connint(&SD1) || connint(&SD2) ||
inint(&SD1) || inint(&SD2) ||
outint(&SD1) || outint(&SD2);
CH_IRQ_EPILOGUE();
return b;
}
#endif /* HAL_USE_SERIAL */
/** @} */

View File

@ -0,0 +1,143 @@
/*
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file serial_lld.h
* @brief Win32 simulator low level serial driver header.
*
* @addtogroup WIN32_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 1024
#endif
/**
* @brief SD1 driver enable switch.
* @details If set to @p TRUE the support for SD1 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_WIN32_SERIAL1) || defined(__DOXYGEN__)
#define USE_WIN32_SERIAL1 TRUE
#endif
/**
* @brief SD2 driver enable switch.
* @details If set to @p TRUE the support for SD2 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_WIN32_SERIAL2) || defined(__DOXYGEN__)
#define USE_WIN32_SERIAL2 TRUE
#endif
/**
* @brief Listen port for SD1.
*/
#if !defined(SD1_PORT) || defined(__DOXYGEN__)
#define SD1_PORT 29001
#endif
/**
* @brief Listen port for SD2.
*/
#if !defined(SD2_PORT) || defined(__DOXYGEN__)
#define SD2_PORT 29002
#endif
/*===========================================================================*/
/* Unsupported event flags and custom events. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Generic Serial Driver configuration structure.
* @details An instance of this structure must be passed to @p sdStart()
* in order to configure and start a serial driver operations.
* @note This structure content is architecture dependent, each driver
* implementation defines its own version and the custom static
* initializers.
*/
typedef struct {
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Listen socket for simulated serial port.*/ \
SOCKET com_listen; \
/* Data socket for simulated serial port.*/ \
SOCKET com_data; \
/* Port readable name.*/ \
const char *com_name;
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_WIN32_SERIAL1 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if USE_WIN32_SERIAL2 && !defined(__DOXYGEN__)
extern SerialDriver SD2;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void sd_lld_init(void);
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
void sd_lld_stop(SerialDriver *sdp);
bool sd_lld_interrupt_pending(void);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@ -1,6 +1,6 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012,2013 Giovanni Di Sirio.
2011,2012,2013,2014 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@ -16,24 +16,41 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @addtogroup SIMIA32_CORE
* @file SIMIA32/chcore.c
* @brief Simulator on IA32 port code.
*
* @addtogroup SIMIA32_GCC_CORE
* @{
*/
#include <stdlib.h>
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
/**
* Performs a context switch between two threads.
@ -68,15 +85,6 @@ static void __dummy(Thread *ntp, Thread *otp) {
"ret");
}
/**
* Halts the system. In this implementation it just exits the simulation.
*/
__attribute__((fastcall))
void port_halt(void) {
exit(2);
}
/**
* @brief Start a thread by invoking its work function.
* @details If the work function returns @p chThdExit() is automatically

View File

@ -1,6 +1,6 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012,2013 Giovanni Di Sirio.
2011,2012,2013,2014 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
@ -16,77 +16,124 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @addtogroup SIMIA32_CORE
* @file SIMIA32/chcore.h
* @brief Simulator on IA32 port macros and structures.
*
* @addtogroup SIMIA32_GCC_CORE
* @{
*/
#ifndef _CHCORE_H_
#define _CHCORE_H_
#if CH_DBG_ENABLE_STACK_CHECK
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
#endif
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/**
* Macro defining the a simulated architecture into x86.
*/
#define CH_ARCHITECTURE_SIMIA32
#define PORT_ARCHITECTURE_SIMIA32
/**
* Name of the implemented architecture.
*/
#define CH_ARCHITECTURE_NAME "Simulator"
#define PORT_ARCHITECTURE_NAME "Simulator"
/**
* @brief Name of the architecture variant (optional).
*/
#define CH_CORE_VARIANT_NAME "x86 (integer only)"
#define PORT_CORE_VARIANT_NAME "x86 (integer only)"
/**
* @brief Name of the compiler supported by this port.
*/
#define CH_COMPILER_NAME "GCC " __VERSION__
#define PORT_COMPILER_NAME "GCC " __VERSION__
/**
* @brief Port-specific information string.
*/
#define CH_PORT_INFO "No preemption"
#define PORT_INFO "No preemption"
/**
* 16 bytes stack alignment.
* @brief This port supports a realtime counter.
*/
#define PORT_SUPPORTS_RT FALSE
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Stack size for the system idle thread.
* @details This size depends on the idle thread implementation, usually
* the idle thread should take no more space than those reserved
* by @p PORT_INT_REQUIRED_STACK.
*/
#ifndef PORT_IDLE_THREAD_STACK_SIZE
#define PORT_IDLE_THREAD_STACK_SIZE 256
#endif
/**
* @brief Per-thread stack overhead for interrupts servicing.
* @details This constant is used in the calculation of the correct working
* area size.
*/
#ifndef PORT_INT_REQUIRED_STACK
#define PORT_INT_REQUIRED_STACK 16384
#endif
/**
* @brief Enables an alternative timer implementation.
* @details Usually the port uses a timer interface defined in the file
* @p chcore_timer.h, if this option is enabled then the file
* @p chcore_timer_alt.h is included instead.
*/
#if !defined(PORT_USE_ALT_TIMER)
#define PORT_USE_ALT_TIMER FALSE
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if CH_DBG_ENABLE_STACK_CHECK
#error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
#endif
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief 16 bytes stack and memory alignment enforcement.
*/
typedef struct {
uint8_t a[16];
} stkalign_t __attribute__((aligned(16)));
/**
* Generic x86 register.
* @brief Type of a generic x86 register.
*/
typedef void *regx86;
/**
* Interrupt saved context.
* This structure represents the stack frame saved during a preemption-capable
* interrupt handler.
* @brief Interrupt saved context.
* @details This structure represents the stack frame saved during a
* preemption-capable interrupt handler.
*/
struct extctx {
struct port_extctx {
};
/**
* System saved context.
* @note In this demo the floating point registers are not saved.
* @brief System saved context.
* @details This structure represents the inner stack frame during a context
* switch.
*/
struct intctx {
struct port_intctx {
regx86 ebx;
regx86 edi;
regx86 esi;
@ -95,14 +142,19 @@ struct intctx {
};
/**
* Platform dependent part of the @p Thread structure.
* This structure usually contains just the saved stack pointer defined as a
* pointer to a @p intctx structure.
* @brief Platform dependent part of the @p thread_t structure.
* @details In this port the structure just holds a pointer to the
* @p port_intctx structure representing the stack pointer
* at context switch time.
*/
struct context {
struct port_context {
struct intctx volatile *esp;
};
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
#define APUSH(p, a) (p) -= sizeof(void *), *(void **)(p) = (void*)(a)
/* Darwin requires the stack to be aligned to a 16-byte boundary at
@ -112,139 +164,202 @@ struct context {
#define AALIGN(p, mask, mod) p = (void *)((((uintptr_t)(p) - mod) & ~mask) + mod)
/**
* Platform dependent part of the @p chThdCreateI() API.
* This code usually setup the context switching frame represented by a
* @p intctx structure.
* @brief Platform dependent part of the @p chThdCreateI() API.
* @details This code usually setup the context switching frame represented
* by an @p port_intctx structure.
*/
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
uint8_t *esp = (uint8_t *)workspace + wsize; \
APUSH(esp, 0); \
uint8_t *savebp = esp; \
AALIGN(esp, 15, 8); \
APUSH(esp, arg); \
APUSH(esp, pf); \
APUSH(esp, 0); \
esp -= sizeof(struct intctx); \
((struct intctx *)esp)->eip = _port_thread_start; \
((struct intctx *)esp)->ebx = 0; \
((struct intctx *)esp)->edi = 0; \
((struct intctx *)esp)->esi = 0; \
((struct intctx *)esp)->ebp = savebp; \
tp->p_ctx.esp = (struct intctx *)esp; \
#define PORT_SETUP_CONTEXT(tp, workspace, wsize, pf, arg) { \
uint8_t *esp = (uint8_t *)workspace + wsize; \
APUSH(esp, 0); \
uint8_t *savebp = esp; \
AALIGN(esp, 15, 8); \
APUSH(esp, arg); \
APUSH(esp, pf); \
APUSH(esp, 0); \
esp -= sizeof(struct port_intctx); \
((struct port_intctx *)esp)->eip = _port_thread_start; \
((struct port_intctx *)esp)->ebx = 0; \
((struct port_intctx *)esp)->edi = 0; \
((struct port_intctx *)esp)->esi = 0; \
((struct port_intctx *)esp)->ebp = savebp; \
(tp)->p_ctx.esp = (struct port_intctx *)esp; \
}
/**
* Stack size for the system idle thread.
*/
#ifndef PORT_IDLE_THREAD_STACK_SIZE
#define PORT_IDLE_THREAD_STACK_SIZE 256
#endif
/**
* Per-thread stack overhead for interrupts servicing, it is used in the
* calculation of the correct working area size.
* It requires stack space because the simulated "interrupt handlers" can
* invoke host library functions inside so it better have a lot of space.
*/
#ifndef PORT_INT_REQUIRED_STACK
#define PORT_INT_REQUIRED_STACK 16384
#endif
/**
* Enforces a correct alignment for a stack area size value.
*/
#define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
/**
* Computes the thread working area global size.
* @brief Computes the thread working area global size.
* @note There is no need to perform alignments in this macro.
*/
#define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \
sizeof(void *) * 4 + \
sizeof(struct intctx) + \
sizeof(struct extctx) + \
(n) + (PORT_INT_REQUIRED_STACK))
#define PORT_WA_SIZE(n) (sizeof(void *) * 4 + \
sizeof(struct port_intctx) + \
sizeof(struct port_extctx) + \
(n) + \
PORT_INT_REQUIRED_STACK)
/**
* Macro used to allocate a thread working area aligned as both position and
* size.
*/
#define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
/**
* IRQ prologue code, inserted at the start of all IRQ handlers enabled to
* invoke system APIs.
* @brief IRQ prologue code.
* @details This macro must be inserted at the start of all IRQ handlers
* enabled to invoke system APIs.
*/
#define PORT_IRQ_PROLOGUE()
/**
* IRQ epilogue code, inserted at the end of all IRQ handlers enabled to
* invoke system APIs.
* @brief IRQ epilogue code.
* @details This macro must be inserted at the end of all IRQ handlers
* enabled to invoke system APIs.
*/
#define PORT_IRQ_EPILOGUE()
/**
* IRQ handler function declaration.
* @brief IRQ handler function declaration.
* @note @p id can be a function name or a vector number depending on the
* port implementation.
*/
#define PORT_IRQ_HANDLER(id) void id(void)
/**
* Simulator initialization.
* @brief Fast IRQ handler function declaration.
* @note @p id can be a function name or a vector number depending on the
* port implementation.
*/
#define port_init()
#define PORT_FAST_IRQ_HANDLER(id) void id(void)
/**
* Does nothing in this simulator.
*/
#define port_lock() asm volatile("nop")
/**
* Does nothing in this simulator.
*/
#define port_unlock() asm volatile("nop")
/**
* Does nothing in this simulator.
*/
#define port_lock_from_isr()
/**
* Does nothing in this simulator.
*/
#define port_unlock_from_isr()
/**
* Does nothing in this simulator.
*/
#define port_disable()
/**
* Does nothing in this simulator.
*/
#define port_suspend()
/**
* Does nothing in this simulator.
*/
#define port_enable()
/**
* In the simulator this does a polling pass on the simulated interrupt
* sources.
*/
#define port_wait_for_interrupt() ChkIntSources()
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
__attribute__((fastcall)) void port_switch(Thread *ntp, Thread *otp);
__attribute__((fastcall)) void port_halt(void);
__attribute__((cdecl, noreturn)) void _port_thread_start(msg_t (*pf)(void *),
void *p);
void ChkIntSources(void);
void _sim_check_for_interrupts(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Module inline functions. */
/*===========================================================================*/
/**
* @brief Port-related initialization code.
*/
static inline void port_init(void) {
}
/**
* @brief Returns a word encoding the current interrupts status.
*
* @return The interrupts status.
*/
static inline syssts_t port_get_irq_status(void) {
return (syssts_t)0;
}
/**
* @brief Checks the interrupt status.
*
* @param[in] sts the interrupt status word
*
* @return The interrupt status.
* @retvel false the word specified a disabled interrupts status.
* @retvel true the word specified an enabled interrupts status.
*/
static inline bool port_irq_enabled(syssts_t sts) {
return (sts & 1) == 0;
}
/**
* @brief Determines the current execution context.
*
* @return The execution context.
* @retval false not running in ISR mode.
* @retval true running in ISR mode.
*/
static inline bool port_is_isr_context(void) {
return false;
}
/**
* @brief Kernel-lock action.
* @details In this port this function disables interrupts globally.
*/
static inline void port_lock(void) {
asm volatile("nop");
}
/**
* @brief Kernel-unlock action.
* @details In this port this function enables interrupts globally.
*/
static inline void port_unlock(void) {
asm volatile("nop");
}
/**
* @brief Kernel-lock action from an interrupt handler.
* @details In this port this function disables interrupts globally.
* @note Same as @p port_lock() in this port.
*/
static inline void port_lock_from_isr(void) {
asm volatile("nop");
}
/**
* @brief Kernel-unlock action from an interrupt handler.
* @details In this port this function enables interrupts globally.
* @note Same as @p port_lock() in this port.
*/
static inline void port_unlock_from_isr(void) {
asm volatile("nop");
}
/**
* @brief Disables all the interrupt sources.
*/
static inline void port_disable(void) {
asm volatile("nop");
}
/**
* @brief Disables the interrupt sources below kernel-level priority.
*/
static inline void port_suspend(void) {
asm volatile("nop");
}
/**
* @brief Enables all the interrupt sources.
*/
static inline void port_enable(void) {
asm volatile("nop");
}
/**
* @brief Enters an architecture-dependent IRQ-waiting mode.
* @details The function is meant to return when an interrupt becomes pending.
* The simplest implementation is an empty function or macro but this
* would not take advantage of architecture-specific power saving
* modes.
* @note Implemented as an inlined @p WFI instruction.
*/
static inline void port_wait_for_interrupt(void) {
_sim_check_for_interrupts();
}
#endif /* _CHCORE_H_ */
/** @} */