Improved general drivers state machine handling.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16291 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
62414373f0
commit
960abcdabb
|
@ -116,7 +116,8 @@ drv_reg_remove(self);
|
|||
<brief>Low level driver stop.</brief>
|
||||
<notapi />
|
||||
</method>
|
||||
<method name="drvConfigureX" shortname="configure" ctype="msg_t">
|
||||
<method name="drvConfigureX" shortname="configure"
|
||||
ctype="msg_t">
|
||||
<brief>Driver configure.</brief>
|
||||
<details><![CDATA[Applies a new configuration to the driver. The
|
||||
configuration structure is architecture-dependent.]]>
|
||||
|
@ -126,7 +127,8 @@ drv_reg_remove(self);
|
|||
depending on the driver implementation and current state.]]>
|
||||
</note>
|
||||
<param ctype="const void *" name="config" dir="in">
|
||||
New driver configuration.
|
||||
New driver
|
||||
configuration.
|
||||
</param>
|
||||
<api />
|
||||
</method>
|
||||
|
@ -138,8 +140,23 @@ drv_reg_remove(self);
|
|||
call the peripheral is physically initialized using a
|
||||
default configuration, subsequent calls are ignored.]]>
|
||||
</details>
|
||||
<note><![CDATA[The function can fail with error
|
||||
@p HAL_RET_INV_STATE if called while the driver is already
|
||||
being started or stopped. In case you need multiple threads
|
||||
to perform start and stop operation on the driver then it is
|
||||
suggested to lock/unlock the driver during such operations.]]></note>
|
||||
<return>The operation status.</return>
|
||||
<retval value="HAL_RET_SUCCESS">Operation successful.</retval>
|
||||
<retval value="HAL_RET_INV_STATE"><![CDATA[If the driver was
|
||||
in one of @p HAL_DRV_STATE_UNINIT, @p HAL_DRV_STATE_STARTING
|
||||
or @p HAL_DRV_STATE_STOPPING states.]]></retval>
|
||||
<retval value="HAL_RET_NO_RESOURCE">If a required resources
|
||||
cannot be allocated.
|
||||
</retval>
|
||||
<retval value="HAL_RET_HW_BUSY">If a required HW resource is
|
||||
already in use.
|
||||
</retval>
|
||||
<retval value="HAL_RET_HW_FAILURE">If an HW failure occurred.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
msg_t msg = HAL_RET_SUCCESS;
|
||||
|
@ -148,20 +165,28 @@ osalDbgCheck(self != NULL);
|
|||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
||||
(self->state != HAL_DRV_STATE_STOPPING) &&
|
||||
(self->state != HAL_DRV_STATE_STARTING),
|
||||
"invalid state");
|
||||
|
||||
if (self->state == HAL_DRV_STATE_STOP) {
|
||||
switch (self->state) {
|
||||
case HAL_DRV_STATE_UNINIT:
|
||||
/* Falls through.*/
|
||||
case HAL_DRV_STATE_STARTING:
|
||||
/* Falls through.*/
|
||||
case HAL_DRV_STATE_STOPPING:
|
||||
msg = HAL_RET_INV_STATE;
|
||||
break;
|
||||
case HAL_DRV_STATE_STOP:
|
||||
/* Physically starting the peripheral.*/
|
||||
msg = __drv_start(self);
|
||||
if (msg == HAL_RET_SUCCESS) {
|
||||
self->state = HAL_DRV_STATE_READY;
|
||||
|
||||
/* LLD is supposed to set a default configuration.*/
|
||||
osalDbgAssert(self->config != NULL, "no configuration");
|
||||
}
|
||||
else {
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
}
|
||||
default:
|
||||
/* Any other state ignored, driver already started.*/
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
|
@ -180,13 +205,13 @@ osalDbgCheck(self != NULL);
|
|||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
||||
(self->state != HAL_DRV_STATE_STARTING),
|
||||
"invalid state");
|
||||
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state");
|
||||
|
||||
if (self->state != HAL_DRV_STATE_STOP) {
|
||||
if ((self->state != HAL_DRV_STATE_STOP) &&
|
||||
(self->state != HAL_DRV_STATE_STARTING)) {
|
||||
__drv_stop(self);
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
self->config = NULL;
|
||||
}
|
||||
|
||||
osalSysUnlock();]]></implementation>
|
||||
|
@ -204,7 +229,8 @@ return self->state;]]></implementation>
|
|||
<method name="drvSetStateX" ctype="void">
|
||||
<brief>Driver state set.</brief>
|
||||
<param ctype="driver_state_t" name="state" dir="in">
|
||||
New driver state.
|
||||
New driver
|
||||
state.
|
||||
</param>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
|
@ -319,7 +345,8 @@ return oopGetOwner(hal_base_driver_c, regent, rep);]]></implementation>
|
|||
This function is only available when HAL registry is enabled.
|
||||
</note>
|
||||
<param name="drvp" ctype="hal_base_driver_c *" dir="in">
|
||||
Previously found driver.
|
||||
Previously
|
||||
found driver.
|
||||
</param>
|
||||
<return>A pointer to the next driver object.</return>
|
||||
<retval value="NULL">If there is no next driver.</retval>
|
||||
|
@ -346,8 +373,10 @@ return oopGetOwner(hal_base_driver_c, regent, rep);]]></implementation>
|
|||
</note>
|
||||
<param name="name" ctype="const char *" dir="in">Driver name.</param>
|
||||
<param name="msgp" ctype="msg_t *" dir="out">
|
||||
Pointer to store the error code or @p NULL. Note that in case of
|
||||
driver not found the returned code is @p HAL_RET_SUCCESS.
|
||||
Pointer to store the
|
||||
error code or @p NULL. Note that in case of
|
||||
driver not found the
|
||||
returned code is @p HAL_RET_SUCCESS.
|
||||
</param>
|
||||
<return>A reference to the driver.</return>
|
||||
<retval value="NULL">If an error occurred.</retval>
|
||||
|
@ -395,7 +424,8 @@ return drvp;]]></implementation>
|
|||
This function is only available when HAL registry is enabled.
|
||||
</note>
|
||||
<param name="drvp" ctype="hal_base_driver_c *" dir="both">
|
||||
Pointer to the @p hal_base_driver_c instance to be inserted.
|
||||
Pointer to
|
||||
the @p hal_base_driver_c instance to be inserted.
|
||||
</param>
|
||||
<implementation><![CDATA[
|
||||
|
||||
|
@ -407,7 +437,8 @@ hal_registry.prev = &drvp->regent;]]></implementation>
|
|||
<function name="drv_reg_remove" ctype="void">
|
||||
<brief>Driver removal from the HAL registry.</brief>
|
||||
<param name="drvp" ctype="hal_base_driver_c *" dir="both">
|
||||
Pointer to the @p hal_base_driver_c instance to be inserted.
|
||||
Pointer to
|
||||
the @p hal_base_driver_c instance to be inserted.
|
||||
</param>
|
||||
<implementation><![CDATA[
|
||||
|
||||
|
|
|
@ -851,7 +851,8 @@ spi_lld_stop(self);]]></implementation>
|
|||
<method shortname="configure">
|
||||
<implementation><![CDATA[
|
||||
|
||||
self->config = config;]]></implementation>
|
||||
self->config = config;
|
||||
spi_lld_configure(self);]]></implementation>
|
||||
</method>
|
||||
<method shortname="setcb">
|
||||
<implementation><![CDATA[
|
||||
|
|
|
@ -91,32 +91,38 @@
|
|||
* @{
|
||||
*/
|
||||
#define HAL_RET_SUCCESS MSG_OK
|
||||
/**
|
||||
* @brief Operation requested during invalid driver state.
|
||||
* @details This error is returned if the driver cannot accept the request
|
||||
* because its internal state.
|
||||
*/
|
||||
#define HAL_RET_INV_STATE (msg_t)-16
|
||||
/**
|
||||
* @brief Configuration error.
|
||||
* @details An error has been detected in the driver configuration structure.
|
||||
*/
|
||||
#define HAL_RET_CONFIG_ERROR (msg_t)-16
|
||||
#define HAL_RET_CONFIG_ERROR (msg_t)-17
|
||||
/**
|
||||
* @brief A required resource is not available.
|
||||
* @details One of the resources required for driver operations is not
|
||||
* available.
|
||||
*/
|
||||
#define HAL_RET_NO_RESOURCE (msg_t)-17
|
||||
#define HAL_RET_NO_RESOURCE (msg_t)-18
|
||||
/**
|
||||
* @brief The peripheral is busy.
|
||||
* @details The peripheral is not available or taken by some other system
|
||||
* actor.
|
||||
*/
|
||||
#define HAL_RET_HW_BUSY (msg_t)-18
|
||||
#define HAL_RET_HW_BUSY (msg_t)-19
|
||||
/**
|
||||
* @brief Peripheral failure.
|
||||
* @details Peripheral failed, for example HW timeouts.
|
||||
*/
|
||||
#define HAL_RET_HW_FAILURE (msg_t)-19
|
||||
#define HAL_RET_HW_FAILURE (msg_t)-20
|
||||
/**
|
||||
* @brief Unknown control code.
|
||||
*/
|
||||
#define HAL_RET_UNKNOWN_CTL (msg_t)-20
|
||||
#define HAL_RET_UNKNOWN_CTL (msg_t)-21
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -266,10 +266,21 @@ void __drv_dispose_impl(void *ip) {
|
|||
* @details Starts driver operations, on the 1st call the peripheral is
|
||||
* physically initialized using a default configuration,
|
||||
* subsequent calls are ignored.
|
||||
* @note The function can fail with error @p HAL_RET_INV_STATE if called
|
||||
* while the driver is already being started or stopped. In case
|
||||
* you need multiple threads performing start and stop operation
|
||||
* on the driver then it is suggested to lock/unlock the driver
|
||||
* during such operations.
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_base_driver_c instance.
|
||||
* @return The operation status.
|
||||
* @retval HAL_RET_SUCCESS Operation successful.
|
||||
* @retval HAL_RET_INV_STATE If the driver was in one of @p
|
||||
* HAL_DRV_STATE_UNINIT, @p HAL_DRV_STATE_STARTING
|
||||
* or @p HAL_DRV_STATE_STOPPING states.
|
||||
* @retval HAL_RET_NO_RESOURCE If a required resources cannot be allocated.
|
||||
* @retval HAL_RET_HW_BUSY If a required HW resource is already in use.
|
||||
* @retval HAL_RET_HW_FAILURE If an HW failure occurred.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
@ -281,20 +292,28 @@ msg_t drvStart(void *ip) {
|
|||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
||||
(self->state != HAL_DRV_STATE_STOPPING) &&
|
||||
(self->state != HAL_DRV_STATE_STARTING),
|
||||
"invalid state");
|
||||
|
||||
if (self->state == HAL_DRV_STATE_STOP) {
|
||||
switch (self->state) {
|
||||
case HAL_DRV_STATE_UNINIT:
|
||||
/* Falls through.*/
|
||||
case HAL_DRV_STATE_STARTING:
|
||||
/* Falls through.*/
|
||||
case HAL_DRV_STATE_STOPPING:
|
||||
msg = HAL_RET_INV_STATE;
|
||||
break;
|
||||
case HAL_DRV_STATE_STOP:
|
||||
/* Physically starting the peripheral.*/
|
||||
msg = __drv_start(self);
|
||||
if (msg == HAL_RET_SUCCESS) {
|
||||
self->state = HAL_DRV_STATE_READY;
|
||||
|
||||
/* LLD is supposed to set a default configuration.*/
|
||||
osalDbgAssert(self->config != NULL, "no configuration");
|
||||
}
|
||||
else {
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
}
|
||||
default:
|
||||
/* Any other state ignored, driver already started.*/
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
|
@ -321,13 +340,13 @@ void drvStop(void *ip) {
|
|||
|
||||
osalSysLock();
|
||||
|
||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
||||
(self->state != HAL_DRV_STATE_STARTING),
|
||||
"invalid state");
|
||||
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state");
|
||||
|
||||
if (self->state != HAL_DRV_STATE_STOP) {
|
||||
if ((self->state != HAL_DRV_STATE_STOP) &&
|
||||
(self->state != HAL_DRV_STATE_STARTING)) {
|
||||
__drv_stop(self);
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
self->config = NULL;
|
||||
}
|
||||
|
||||
osalSysUnlock();
|
||||
|
|
|
@ -134,6 +134,8 @@ void __spi_dispose_impl(void *ip) {
|
|||
*/
|
||||
msg_t __spi_start_impl(void *ip) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
|
||||
return spi_lld_start(self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,6 +148,8 @@ msg_t __spi_start_impl(void *ip) {
|
|||
*/
|
||||
void __spi_stop_impl(void *ip) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
|
||||
spi_lld_stop(self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -161,6 +165,7 @@ msg_t __spi_configure_impl(void *ip, const void *config) {
|
|||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
|
||||
self->config = config;
|
||||
spi_lld_configure(self);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue