mirror of
https://github.com/apache/nuttx.git
synced 2026-05-20 20:44:39 +08:00
boards/boardctl.c: BOARDIOC_SPINLOCK missing some Conditional branch
Add missing else branches to handle spinlock operations when no valid spinlock pointer is available. This fixes a regression in IRQ save/restore operations introduced by a previous refactoring of the spinlock control logic. Signed-off-by: hujun5 <hujun5@xiaomi.com>
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
==================================
|
||||
BOARDIOC_SPINLOCK Spinlock Example
|
||||
==================================
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
This example demonstrates the usage of the BOARDIOC_SPINLOCK board control
|
||||
interface for managing hardware spinlock operations in NuttX. The BOARDIOC_SPINLOCK
|
||||
interface provides a low-level mechanism to synchronize access to shared resources
|
||||
across multiple threads or CPUs using spinlock primitives.
|
||||
|
||||
What is BOARDIOC_SPINLOCK?
|
||||
==========================
|
||||
|
||||
BOARDIOC_SPINLOCK is a board control request that allows applications to perform
|
||||
atomic spinlock operations through the boardctl() interface.
|
||||
|
||||
The BOARDIOC_SPINLOCK interface supports three primary operations:
|
||||
|
||||
* **BOARDIOC_SPINLOCK_LOCK** - Acquire a spinlock (blocks until available)
|
||||
* **BOARDIOC_SPINLOCK_TRYLOCK** - Try to acquire a spinlock (non-blocking)
|
||||
* **BOARDIOC_SPINLOCK_UNLOCK** - Release a spinlock
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
The following configuration options must be enabled:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Enable board spinlock support
|
||||
CONFIG_BOARDCTL_SPINLOCK=y
|
||||
|
||||
|
||||
Basic Usage
|
||||
===========
|
||||
|
||||
Header Files
|
||||
------------
|
||||
|
||||
Include the following headers in your application:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <sys/boardctl.h> /* For boardctl() interface */
|
||||
#include <nuttx/spinlock.h> /* For spinlock types */
|
||||
|
||||
Data Structures
|
||||
---------------
|
||||
|
||||
The BOARDIOC_SPINLOCK interface uses the following structure:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct boardioc_spinlock_s
|
||||
{
|
||||
int action; /* Operation: LOCK, TRYLOCK, or UNLOCK */
|
||||
spinlock_t *lock; /* Pointer to the spinlock variable */
|
||||
void *flags; /* Optional flags (reserved, set to NULL) */
|
||||
};
|
||||
|
||||
Actions
|
||||
-------
|
||||
|
||||
The following action values are supported:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
BOARDIOC_SPINLOCK_LOCK /* Acquire lock (blocks if unavailable) */
|
||||
BOARDIOC_SPINLOCK_TRYLOCK /* Try to acquire (non-blocking) */
|
||||
BOARDIOC_SPINLOCK_UNLOCK /* Release lock */
|
||||
|
||||
Return Values
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
* **0** - Success
|
||||
* **Negative value** - Error code (converted to errno)
|
||||
|
||||
Simple Lock Example
|
||||
-------------------
|
||||
|
||||
Here's a basic example of acquiring and releasing a spinlock:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
spinlock_t my_lock;
|
||||
struct boardioc_spinlock_s spinlock_op;
|
||||
int ret;
|
||||
|
||||
/* Initialize the spinlock */
|
||||
spin_lock_init(&my_lock);
|
||||
|
||||
/* Acquire the spinlock */
|
||||
spinlock_op.action = BOARDIOC_SPINLOCK_LOCK;
|
||||
spinlock_op.lock = &my_lock;
|
||||
spinlock_op.flags = NULL;
|
||||
|
||||
ret = boardctl(BOARDIOC_SPINLOCK, (uintptr_t)&spinlock_op);
|
||||
if (ret == 0) {
|
||||
printf("Spinlock acquired successfully\n");
|
||||
} else {
|
||||
printf("Failed to acquire spinlock: %d\n", ret);
|
||||
}
|
||||
|
||||
printf("Inside spinlock\n");
|
||||
|
||||
/* Release the spinlock */
|
||||
spinlock_op.action = BOARDIOC_SPINLOCK_UNLOCK;
|
||||
ret = boardctl(BOARDIOC_SPINLOCK, (uintptr_t)&spinlock_op);
|
||||
if (ret == 0) {
|
||||
printf("Spinlock released successfully\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -819,6 +819,10 @@ int boardctl(unsigned int cmd, uintptr_t arg)
|
||||
spin_lock(lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*flags = up_irq_save();
|
||||
}
|
||||
}
|
||||
else if (spinlock->action == BOARDIOC_SPINLOCK_TRYLOCK)
|
||||
{
|
||||
@@ -850,6 +854,10 @@ int boardctl(unsigned int cmd, uintptr_t arg)
|
||||
spin_unlock(lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
up_irq_restore(*flags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user