Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
Expand All @@ -25,7 +25,7 @@
#include "drv_config.h"
#include <string.h>

//#define DRV_DEBUG
/*#define DRV_DEBUG*/
#define LOG_TAG "drv.spi"
#include <drv_log.h>

Expand Down Expand Up @@ -683,6 +683,47 @@ rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name,
return result;
}

/**
* Detach the spi device from SPI bus.
*
* @param device_name the name of the spi device to be detached.
*/
rt_err_t rt_hw_spi_device_detach(const char *device_name)
{
RT_ASSERT(device_name != RT_NULL);

rt_err_t result;
struct rt_spi_device *spi_device;

rt_device_t device = rt_device_find(device_name);
if (device == RT_NULL)
{
LOG_E("SPI device %s not found.", device_name);
return -RT_ERROR;
}

if (device->type != RT_Device_Class_SPIDevice)
{
LOG_E("%s is not an SPI device.", device_name);
return -RT_ERROR;
}

spi_device = (struct rt_spi_device *)device;

result = rt_spi_bus_detach_device_cspin(spi_device);
if (result != RT_EOK)
{
LOG_E("Failed to detach %s from its bus, error code: %d", device_name, result);
return result;
}

rt_free(spi_device);
Copy link
Preview

Copilot AI Sep 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

English: The function frees the SPI device memory directly, but this assumes the device was dynamically allocated. If the device was statically allocated or managed elsewhere, this will cause undefined behavior or memory corruption.

中文: 该函数直接释放SPI设备内存,但这假设设备是动态分配的。如果设备是静态分配的或在其他地方管理,这将导致未定义行为或内存损坏。

Suggested change
rt_free(spi_device);
/* Do not free spi_device here, as its allocation source is unknown. */

Copilot uses AI. Check for mistakes.


LOG_D("SPI device %s has been detached.", device_name);

return RT_EOK;
}

#if defined(BSP_SPI1_TX_USING_DMA) || defined(BSP_SPI1_RX_USING_DMA)
void SPI1_IRQHandler(void)
{
Expand Down
3 changes: 2 additions & 1 deletion bsp/stm32/libraries/HAL_Drivers/drivers/drv_spi.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
Expand All @@ -23,6 +23,7 @@ extern "C" {
#endif

rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin);
rt_err_t rt_hw_spi_device_detach(const char *device_name);

#ifdef __cplusplus
}
Expand Down
30 changes: 29 additions & 1 deletion components/drivers/include/drivers/dev_spi.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -349,6 +349,19 @@ rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device,
const char *bus_name,
void *user_data);

/**
* @brief Detach a device from the SPI bus.
*
* This function serves as the high-level API to detach a SPI device from its bus.
* It unregisters the device from the device framework and ensures all associated
* resources, such as the chip select pin, are properly released by calling
* the underlying implementation.
*
* @param device The SPI device to be detached.
*
* @return rt_err_t The result of the operation. RT_EOK on success, otherwise an error code.
*/
rt_err_t rt_spi_bus_detach_device(struct rt_spi_device *device);

/**
* @brief attach a device on SPI bus with CS pin
Expand All @@ -367,6 +380,21 @@ rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device,
rt_base_t cs_pin,
void *user_data);

/**
* @brief Detach a device from the SPI bus and release its CS pin.
*
* This function provides the low-level implementation for detaching a device
* from the SPI bus. It specifically handles the operations for the chip select (CS)
* pin, resetting it to input mode to release it. This function is typically
* called by the higher-level rt_spi_bus_detach_device() and should not be
* called directly by the user application.
*
* @param device The SPI device to be detached.
*
* @return rt_err_t The result of the operation. RT_EOK on success, otherwise an error code.
*/
rt_err_t rt_spi_bus_detach_device_cspin(struct rt_spi_device *device);

/**
* @brief Reconfigure the SPI bus for the specified device.
*
Expand Down
33 changes: 33 additions & 0 deletions components/drivers/spi/dev_spi_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,34 @@ rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device,
return -RT_ERROR;
}

rt_err_t rt_spi_bus_detach_device_cspin(struct rt_spi_device *device)
{
rt_err_t result;

RT_ASSERT(device != RT_NULL);

result = rt_device_unregister(&device->parent);
if (result != RT_EOK)
{
LOG_E("Failed to unregister spi device, result: %d", result);
return result;
}

if (device->bus != RT_NULL && device->bus->owner == device)
{
device->bus->owner = RT_NULL;
}

if (device->cs_pin != PIN_NONE)
{
rt_pin_mode(device->cs_pin, PIN_MODE_INPUT);
}

device->bus = RT_NULL;

return RT_EOK;
}

rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device,
const char *name,
const char *bus_name,
Expand All @@ -131,6 +159,11 @@ rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device,
return rt_spi_bus_attach_device_cspin(device, name, bus_name, PIN_NONE, user_data);
}

rt_err_t rt_spi_bus_detach_device(struct rt_spi_device *device)
{
return rt_spi_bus_detach_device_cspin(device);
}

rt_err_t rt_spi_bus_configure(struct rt_spi_device *device)
{
rt_err_t result = -RT_ERROR;
Expand Down