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>
|
<brief>Low level driver stop.</brief>
|
||||||
<notapi />
|
<notapi />
|
||||||
</method>
|
</method>
|
||||||
<method name="drvConfigureX" shortname="configure" ctype="msg_t">
|
<method name="drvConfigureX" shortname="configure"
|
||||||
|
ctype="msg_t">
|
||||||
<brief>Driver configure.</brief>
|
<brief>Driver configure.</brief>
|
||||||
<details><![CDATA[Applies a new configuration to the driver. The
|
<details><![CDATA[Applies a new configuration to the driver. The
|
||||||
configuration structure is architecture-dependent.]]>
|
configuration structure is architecture-dependent.]]>
|
||||||
|
@ -126,7 +127,8 @@ drv_reg_remove(self);
|
||||||
depending on the driver implementation and current state.]]>
|
depending on the driver implementation and current state.]]>
|
||||||
</note>
|
</note>
|
||||||
<param ctype="const void *" name="config" dir="in">
|
<param ctype="const void *" name="config" dir="in">
|
||||||
New driver configuration.
|
New driver
|
||||||
|
configuration.
|
||||||
</param>
|
</param>
|
||||||
<api />
|
<api />
|
||||||
</method>
|
</method>
|
||||||
|
@ -138,8 +140,23 @@ drv_reg_remove(self);
|
||||||
call the peripheral is physically initialized using a
|
call the peripheral is physically initialized using a
|
||||||
default configuration, subsequent calls are ignored.]]>
|
default configuration, subsequent calls are ignored.]]>
|
||||||
</details>
|
</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>
|
<return>The operation status.</return>
|
||||||
<retval value="HAL_RET_SUCCESS">Operation successful.</retval>
|
<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 />
|
<api />
|
||||||
<implementation><![CDATA[
|
<implementation><![CDATA[
|
||||||
msg_t msg = HAL_RET_SUCCESS;
|
msg_t msg = HAL_RET_SUCCESS;
|
||||||
|
@ -148,20 +165,28 @@ osalDbgCheck(self != NULL);
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
|
|
||||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
switch (self->state) {
|
||||||
(self->state != HAL_DRV_STATE_STOPPING) &&
|
case HAL_DRV_STATE_UNINIT:
|
||||||
(self->state != HAL_DRV_STATE_STARTING),
|
/* Falls through.*/
|
||||||
"invalid state");
|
case HAL_DRV_STATE_STARTING:
|
||||||
|
/* Falls through.*/
|
||||||
if (self->state == HAL_DRV_STATE_STOP) {
|
case HAL_DRV_STATE_STOPPING:
|
||||||
|
msg = HAL_RET_INV_STATE;
|
||||||
|
break;
|
||||||
|
case HAL_DRV_STATE_STOP:
|
||||||
/* Physically starting the peripheral.*/
|
/* Physically starting the peripheral.*/
|
||||||
msg = __drv_start(self);
|
msg = __drv_start(self);
|
||||||
if (msg == HAL_RET_SUCCESS) {
|
if (msg == HAL_RET_SUCCESS) {
|
||||||
self->state = HAL_DRV_STATE_READY;
|
self->state = HAL_DRV_STATE_READY;
|
||||||
|
|
||||||
|
/* LLD is supposed to set a default configuration.*/
|
||||||
|
osalDbgAssert(self->config != NULL, "no configuration");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self->state = HAL_DRV_STATE_STOP;
|
self->state = HAL_DRV_STATE_STOP;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
/* Any other state ignored, driver already started.*/
|
||||||
}
|
}
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
@ -180,13 +205,13 @@ osalDbgCheck(self != NULL);
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
|
|
||||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state");
|
||||||
(self->state != HAL_DRV_STATE_STARTING),
|
|
||||||
"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);
|
__drv_stop(self);
|
||||||
self->state = HAL_DRV_STATE_STOP;
|
self->state = HAL_DRV_STATE_STOP;
|
||||||
|
self->config = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
osalSysUnlock();]]></implementation>
|
osalSysUnlock();]]></implementation>
|
||||||
|
@ -204,7 +229,8 @@ return self->state;]]></implementation>
|
||||||
<method name="drvSetStateX" ctype="void">
|
<method name="drvSetStateX" ctype="void">
|
||||||
<brief>Driver state set.</brief>
|
<brief>Driver state set.</brief>
|
||||||
<param ctype="driver_state_t" name="state" dir="in">
|
<param ctype="driver_state_t" name="state" dir="in">
|
||||||
New driver state.
|
New driver
|
||||||
|
state.
|
||||||
</param>
|
</param>
|
||||||
<api />
|
<api />
|
||||||
<implementation><![CDATA[
|
<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.
|
This function is only available when HAL registry is enabled.
|
||||||
</note>
|
</note>
|
||||||
<param name="drvp" ctype="hal_base_driver_c *" dir="in">
|
<param name="drvp" ctype="hal_base_driver_c *" dir="in">
|
||||||
Previously found driver.
|
Previously
|
||||||
|
found driver.
|
||||||
</param>
|
</param>
|
||||||
<return>A pointer to the next driver object.</return>
|
<return>A pointer to the next driver object.</return>
|
||||||
<retval value="NULL">If there is no next driver.</retval>
|
<retval value="NULL">If there is no next driver.</retval>
|
||||||
|
@ -346,8 +373,10 @@ return oopGetOwner(hal_base_driver_c, regent, rep);]]></implementation>
|
||||||
</note>
|
</note>
|
||||||
<param name="name" ctype="const char *" dir="in">Driver name.</param>
|
<param name="name" ctype="const char *" dir="in">Driver name.</param>
|
||||||
<param name="msgp" ctype="msg_t *" dir="out">
|
<param name="msgp" ctype="msg_t *" dir="out">
|
||||||
Pointer to store the error code or @p NULL. Note that in case of
|
Pointer to store the
|
||||||
driver not found the returned code is @p HAL_RET_SUCCESS.
|
error code or @p NULL. Note that in case of
|
||||||
|
driver not found the
|
||||||
|
returned code is @p HAL_RET_SUCCESS.
|
||||||
</param>
|
</param>
|
||||||
<return>A reference to the driver.</return>
|
<return>A reference to the driver.</return>
|
||||||
<retval value="NULL">If an error occurred.</retval>
|
<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.
|
This function is only available when HAL registry is enabled.
|
||||||
</note>
|
</note>
|
||||||
<param name="drvp" ctype="hal_base_driver_c *" dir="both">
|
<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>
|
</param>
|
||||||
<implementation><![CDATA[
|
<implementation><![CDATA[
|
||||||
|
|
||||||
|
@ -407,7 +437,8 @@ hal_registry.prev = &drvp->regent;]]></implementation>
|
||||||
<function name="drv_reg_remove" ctype="void">
|
<function name="drv_reg_remove" ctype="void">
|
||||||
<brief>Driver removal from the HAL registry.</brief>
|
<brief>Driver removal from the HAL registry.</brief>
|
||||||
<param name="drvp" ctype="hal_base_driver_c *" dir="both">
|
<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>
|
</param>
|
||||||
<implementation><![CDATA[
|
<implementation><![CDATA[
|
||||||
|
|
||||||
|
|
|
@ -851,7 +851,8 @@ spi_lld_stop(self);]]></implementation>
|
||||||
<method shortname="configure">
|
<method shortname="configure">
|
||||||
<implementation><![CDATA[
|
<implementation><![CDATA[
|
||||||
|
|
||||||
self->config = config;]]></implementation>
|
self->config = config;
|
||||||
|
spi_lld_configure(self);]]></implementation>
|
||||||
</method>
|
</method>
|
||||||
<method shortname="setcb">
|
<method shortname="setcb">
|
||||||
<implementation><![CDATA[
|
<implementation><![CDATA[
|
||||||
|
|
|
@ -91,32 +91,38 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define HAL_RET_SUCCESS MSG_OK
|
#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.
|
* @brief Configuration error.
|
||||||
* @details An error has been detected in the driver configuration structure.
|
* @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.
|
* @brief A required resource is not available.
|
||||||
* @details One of the resources required for driver operations is not
|
* @details One of the resources required for driver operations is not
|
||||||
* available.
|
* available.
|
||||||
*/
|
*/
|
||||||
#define HAL_RET_NO_RESOURCE (msg_t)-17
|
#define HAL_RET_NO_RESOURCE (msg_t)-18
|
||||||
/**
|
/**
|
||||||
* @brief The peripheral is busy.
|
* @brief The peripheral is busy.
|
||||||
* @details The peripheral is not available or taken by some other system
|
* @details The peripheral is not available or taken by some other system
|
||||||
* actor.
|
* actor.
|
||||||
*/
|
*/
|
||||||
#define HAL_RET_HW_BUSY (msg_t)-18
|
#define HAL_RET_HW_BUSY (msg_t)-19
|
||||||
/**
|
/**
|
||||||
* @brief Peripheral failure.
|
* @brief Peripheral failure.
|
||||||
* @details Peripheral failed, for example HW timeouts.
|
* @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.
|
* @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
|
* @details Starts driver operations, on the 1st call the peripheral is
|
||||||
* physically initialized using a default configuration,
|
* physically initialized using a default configuration,
|
||||||
* subsequent calls are ignored.
|
* 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.
|
* @param[in,out] ip Pointer to a @p hal_base_driver_c instance.
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval HAL_RET_SUCCESS Operation successful.
|
* @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
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -281,20 +292,28 @@ msg_t drvStart(void *ip) {
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
|
|
||||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
switch (self->state) {
|
||||||
(self->state != HAL_DRV_STATE_STOPPING) &&
|
case HAL_DRV_STATE_UNINIT:
|
||||||
(self->state != HAL_DRV_STATE_STARTING),
|
/* Falls through.*/
|
||||||
"invalid state");
|
case HAL_DRV_STATE_STARTING:
|
||||||
|
/* Falls through.*/
|
||||||
if (self->state == HAL_DRV_STATE_STOP) {
|
case HAL_DRV_STATE_STOPPING:
|
||||||
|
msg = HAL_RET_INV_STATE;
|
||||||
|
break;
|
||||||
|
case HAL_DRV_STATE_STOP:
|
||||||
/* Physically starting the peripheral.*/
|
/* Physically starting the peripheral.*/
|
||||||
msg = __drv_start(self);
|
msg = __drv_start(self);
|
||||||
if (msg == HAL_RET_SUCCESS) {
|
if (msg == HAL_RET_SUCCESS) {
|
||||||
self->state = HAL_DRV_STATE_READY;
|
self->state = HAL_DRV_STATE_READY;
|
||||||
|
|
||||||
|
/* LLD is supposed to set a default configuration.*/
|
||||||
|
osalDbgAssert(self->config != NULL, "no configuration");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
self->state = HAL_DRV_STATE_STOP;
|
self->state = HAL_DRV_STATE_STOP;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
/* Any other state ignored, driver already started.*/
|
||||||
}
|
}
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
@ -321,13 +340,13 @@ void drvStop(void *ip) {
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
|
|
||||||
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
|
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state");
|
||||||
(self->state != HAL_DRV_STATE_STARTING),
|
|
||||||
"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);
|
__drv_stop(self);
|
||||||
self->state = HAL_DRV_STATE_STOP;
|
self->state = HAL_DRV_STATE_STOP;
|
||||||
|
self->config = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
|
|
@ -134,6 +134,8 @@ void __spi_dispose_impl(void *ip) {
|
||||||
*/
|
*/
|
||||||
msg_t __spi_start_impl(void *ip) {
|
msg_t __spi_start_impl(void *ip) {
|
||||||
hal_spi_driver_c *self = (hal_spi_driver_c *)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) {
|
void __spi_stop_impl(void *ip) {
|
||||||
hal_spi_driver_c *self = (hal_spi_driver_c *)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;
|
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||||
|
|
||||||
self->config = config;
|
self->config = config;
|
||||||
|
spi_lld_configure(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue