diff --git a/components/dfs/dfs_v2/src/dfs_pcache.c b/components/dfs/dfs_v2/src/dfs_pcache.c index 6868170b9cb..2a68c268a4a 100644 --- a/components/dfs/dfs_v2/src/dfs_pcache.c +++ b/components/dfs/dfs_v2/src/dfs_pcache.c @@ -16,15 +16,16 @@ #include #include #include -#include -#include -#include -#include #include #ifdef RT_USING_PAGECACHE +#include +#include +#include +#include + #ifndef RT_PAGECACHE_COUNT #define RT_PAGECACHE_COUNT 4096 #endif diff --git a/components/drivers/core/device.c b/components/drivers/core/device.c index 5dfd0c4653e..751b662d4ec 100644 --- a/components/drivers/core/device.c +++ b/components/drivers/core/device.c @@ -31,9 +31,9 @@ #include /* for wqueue_init */ #endif /* RT_USING_POSIX_DEVIO */ -#ifdef RT_USING_DFS_V2 +#if defined (RT_USING_DFS_V2) && defined (RT_USING_DFS_DEVFS) #include -#endif /* RT_USING_DFS_V2 */ +#endif /* RT_USING_DFS_V2 RT_USING_DFS_DEVFS */ #ifdef RT_USING_DEVICE @@ -84,7 +84,7 @@ rt_err_t rt_device_register(rt_device_t dev, rt_wqueue_init(&(dev->wait_queue)); #endif /* RT_USING_POSIX_DEVIO */ -#ifdef RT_USING_DFS_V2 +#if defined (RT_USING_DFS_V2) && defined (RT_USING_DFS_DEVFS) dfs_devfs_device_add(dev); #endif /* RT_USING_DFS_V2 */ diff --git a/components/drivers/include/drivers/pm.h b/components/drivers/include/drivers/pm.h index f6257826168..2fa037c5e58 100644 --- a/components/drivers/include/drivers/pm.h +++ b/components/drivers/include/drivers/pm.h @@ -49,23 +49,23 @@ enum }; /* The name of all modes used in the msh command "pm_dump" */ -#define PM_SLEEP_MODE_NAMES \ -{ \ - "None Mode", \ - "Idle Mode", \ - "LightSleep Mode", \ - "DeepSleep Mode", \ - "Standby Mode", \ - "Shutdown Mode", \ -} - -#define PM_RUN_MODE_NAMES \ -{ \ - "High Speed", \ - "Normal Speed", \ - "Medium Speed", \ - "Low Mode", \ -} +#define PM_SLEEP_MODE_NAMES \ + { \ + "None Mode", \ + "Idle Mode", \ + "LightSleep Mode", \ + "DeepSleep Mode", \ + "Standby Mode", \ + "Shutdown Mode", \ + } + +#define PM_RUN_MODE_NAMES \ + { \ + "High Speed", \ + "Normal Speed", \ + "Medium Speed", \ + "Low Mode", \ + } #ifndef PM_USING_CUSTOM_CONFIG /** @@ -74,7 +74,8 @@ enum * pm_module_release(PM_BOARD_ID, PM_SLEEP_MODE_IDLE) * pm_module_release_all(PM_BOARD_ID, PM_SLEEP_MODE_IDLE) */ -enum pm_module_id { +enum pm_module_id +{ PM_NONE_ID = 0, PM_POWER_ID, PM_BOARD_ID, @@ -102,22 +103,22 @@ enum pm_module_id { #endif /* PM_USING_CUSTOM_CONFIG */ #ifndef RT_PM_DEFAULT_SLEEP_MODE -#define RT_PM_DEFAULT_SLEEP_MODE PM_SLEEP_MODE_NONE +#define RT_PM_DEFAULT_SLEEP_MODE PM_SLEEP_MODE_NONE #endif #ifndef RT_PM_DEFAULT_DEEPSLEEP_MODE -#define RT_PM_DEFAULT_DEEPSLEEP_MODE PM_SLEEP_MODE_DEEP +#define RT_PM_DEFAULT_DEEPSLEEP_MODE PM_SLEEP_MODE_DEEP #endif #ifndef RT_PM_DEFAULT_RUN_MODE -#define RT_PM_DEFAULT_RUN_MODE PM_RUN_MODE_NORMAL_SPEED +#define RT_PM_DEFAULT_RUN_MODE PM_RUN_MODE_NORMAL_SPEED #endif /** * device control flag to request or release power */ -#define RT_PM_DEVICE_CTRL_RELEASE (RT_DEVICE_CTRL_BASE(PM) + 0x00) -#define RT_PM_DEVICE_CTRL_REQUEST (RT_DEVICE_CTRL_BASE(PM) + 0x01) +#define RT_PM_DEVICE_CTRL_RELEASE (RT_DEVICE_CTRL_BASE(PM) + 0x00) +#define RT_PM_DEVICE_CTRL_REQUEST (RT_DEVICE_CTRL_BASE(PM) + 0x01) struct rt_pm; @@ -142,15 +143,15 @@ struct rt_device_pm_ops struct rt_device_pm { - const struct rt_device *device; + const struct rt_device *device; const struct rt_device_pm_ops *ops; - rt_slist_t list; + rt_slist_t list; }; struct rt_pm_module { - rt_uint8_t req_status; - rt_bool_t busy_flag; + rt_uint8_t req_status; + rt_bool_t busy_flag; rt_uint32_t timeout; rt_uint32_t start_time; }; @@ -164,17 +165,18 @@ struct rt_pm /* modes */ rt_uint8_t modes[PM_SLEEP_MODE_MAX]; - rt_uint8_t sleep_mode; /* current sleep mode */ - rt_uint8_t run_mode; /* current running mode */ + rt_uint8_t sleep_mode; /* current sleep mode */ + rt_uint8_t run_mode; /* current running mode */ +#ifndef PM_DISABLE_MODULE /* modules request status*/ struct rt_pm_module module_status[PM_MODULE_MAX_ID]; - /* sleep request table */ rt_uint32_t sleep_status[PM_SLEEP_MODE_MAX - 1][(PM_MODULE_MAX_ID + 31) / 32]; +#endif /* the list of device, which has PM feature */ - rt_slist_t device_list; + rt_slist_t device_list; struct rt_device_pm *device_pm; /* if the mode has timer, the corresponding bit is 1*/ @@ -209,18 +211,44 @@ void rt_pm_default_set(rt_uint8_t sleep_mode); void rt_system_pm_init(const struct rt_pm_ops *ops, rt_uint8_t timer_mask, - void *user_data); -rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode); -rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode); -rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode); -void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout); -rt_uint32_t rt_pm_module_get_status(void); -rt_uint8_t rt_pm_get_sleep_mode(void); + void *user_data); + +rt_uint8_t rt_pm_get_sleep_mode(void); struct rt_pm *rt_pm_get_handle(void); +#ifndef PM_DISABLE_MODULE +rt_err_t rt_pm_module_request(rt_uint16_t module_id, rt_uint8_t sleep_mode); +rt_err_t rt_pm_module_release(rt_uint16_t module_id, rt_uint8_t sleep_mode); +rt_err_t rt_pm_module_release_all(rt_uint16_t module_id, rt_uint8_t sleep_mode); +void rt_pm_module_delay_sleep(rt_uint16_t module_id, rt_tick_t timeout); +rt_uint32_t rt_pm_module_get_status(void); + /* sleep : request or release */ rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode); rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode); + +#else + +rt_inline rt_err_t rt_pm_module_request(rt_uint16_t module_id, rt_uint8_t sleep_mode) +{ + RT_UNUSED(module_id); + return rt_pm_request(sleep_mode); +} +rt_inline rt_err_t rt_pm_module_release(rt_uint16_t module_id, rt_uint8_t sleep_mode) +{ + RT_UNUSED(module_id); + return rt_pm_release(sleep_mode); +} +rt_inline rt_err_t rt_pm_module_release_all(rt_uint16_t module_id, rt_uint8_t sleep_mode) +{ + RT_UNUSED(module_id); + return rt_pm_release_all(sleep_mode); +} +#define rt_pm_sleep_request(module_id, mode) rt_pm_request(mode) +#define rt_pm_sleep_release(module_id, mode) rt_pm_release(mode) + +#endif + rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id); rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id); rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id); diff --git a/components/drivers/include/ipc/workqueue.h b/components/drivers/include/ipc/workqueue.h index e05a7ab63f8..8d0c986b4f0 100644 --- a/components/drivers/include/ipc/workqueue.h +++ b/components/drivers/include/ipc/workqueue.h @@ -13,6 +13,7 @@ #include #include +#include "completion.h" #ifdef __cplusplus extern "C" { @@ -42,6 +43,7 @@ struct rt_workqueue struct rt_semaphore sem; rt_thread_t work_thread; struct rt_spinlock spinlock; + struct rt_completion wakeup_completion; }; struct rt_work @@ -52,7 +54,7 @@ struct rt_work void *work_data; rt_uint16_t flags; rt_uint16_t type; - struct rt_timer timer; + rt_tick_t timeout_tick; struct rt_workqueue *workqueue; }; diff --git a/components/drivers/ipc/workqueue.c b/components/drivers/ipc/workqueue.c index fb3657b1925..1096ad24f00 100644 --- a/components/drivers/ipc/workqueue.c +++ b/components/drivers/ipc/workqueue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2023, RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -10,6 +10,7 @@ * 2021-08-14 Jackistang add comments for function interface * 2022-01-16 Meco Man add rt_work_urgent() * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable + * 2024-12-21 yuqingli delete timer, using list */ #include @@ -17,8 +18,6 @@ #ifdef RT_USING_HEAP -static void _delayed_work_timeout_handler(void *parameter); - rt_inline rt_err_t _workqueue_work_completion(struct rt_workqueue *queue) { rt_err_t result; @@ -50,38 +49,61 @@ rt_inline rt_err_t _workqueue_work_completion(struct rt_workqueue *queue) static void _workqueue_thread_entry(void *parameter) { - rt_base_t level; - struct rt_work *work; + rt_base_t level; + struct rt_work *work; struct rt_workqueue *queue; + rt_tick_t current_tick; + rt_int32_t delay_tick; + void (*work_func)(struct rt_work *work, void *work_data); + void *work_data; - queue = (struct rt_workqueue *) parameter; + queue = (struct rt_workqueue *)parameter; RT_ASSERT(queue != RT_NULL); while (1) { level = rt_spin_lock_irqsave(&(queue->spinlock)); - if (rt_list_isempty(&(queue->work_list))) + + /* timer check */ + current_tick = rt_tick_get(); + delay_tick = RT_WAITING_FOREVER; + while (!rt_list_isempty(&(queue->delayed_list))) { - /* no software timer exist, suspend self. */ - rt_thread_suspend_with_flag(rt_thread_self(), RT_UNINTERRUPTIBLE); + work = rt_list_entry(queue->delayed_list.next, struct rt_work, list); + if ((current_tick - work->timeout_tick) < RT_TICK_MAX / 2) + { + rt_list_remove(&(work->list)); + rt_list_insert_after(queue->work_list.prev, &(work->list)); + work->flags &= ~RT_WORK_STATE_SUBMITTING; + work->flags |= RT_WORK_STATE_PENDING; + } + else + { + delay_tick = work->timeout_tick - current_tick; + break; + } + } - /* release lock after suspend so we will not lost any wakeups */ + if (rt_list_isempty(&(queue->work_list))) + { rt_spin_unlock_irqrestore(&(queue->spinlock), level); - - rt_schedule(); + /* wait for work completion */ + rt_completion_wait(&(queue->wakeup_completion), delay_tick); continue; } /* we have work to do with. */ work = rt_list_entry(queue->work_list.next, struct rt_work, list); rt_list_remove(&(work->list)); - queue->work_current = work; - work->flags &= ~RT_WORK_STATE_PENDING; - work->workqueue = RT_NULL; + queue->work_current = work; + work->flags &= ~RT_WORK_STATE_PENDING; + work->workqueue = RT_NULL; + work_func = work->work_func; + work_data = work->work_data; rt_spin_unlock_irqrestore(&(queue->spinlock), level); /* do work */ - work->work_func(work, work->work_data); + work_func(work, work_data); /* clean current work */ queue->work_current = RT_NULL; @@ -93,52 +115,54 @@ static void _workqueue_thread_entry(void *parameter) static rt_err_t _workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t ticks) { - rt_base_t level; - rt_err_t err = RT_EOK; + rt_base_t level; + rt_err_t err = RT_EOK; + struct rt_work *work_tmp; + rt_list_t *list_tmp; level = rt_spin_lock_irqsave(&(queue->spinlock)); - /* remove list */ rt_list_remove(&(work->list)); - work->flags &= ~RT_WORK_STATE_PENDING; + work->flags = 0; if (ticks == 0) { rt_list_insert_after(queue->work_list.prev, &(work->list)); - work->flags |= RT_WORK_STATE_PENDING; - work->workqueue = queue; + work->flags |= RT_WORK_STATE_PENDING; + work->workqueue = queue; - /* whether the workqueue is doing work */ - if (queue->work_current == RT_NULL) - { - /* resume work thread, and do a re-schedule if succeed */ - rt_thread_resume(queue->work_thread); - } + rt_completion_done(&(queue->wakeup_completion)); + err = RT_EOK; } else if (ticks < RT_TICK_MAX / 2) { - /* Timer started */ - if (work->flags & RT_WORK_STATE_SUBMITTING) - { - rt_timer_control(&work->timer, RT_TIMER_CTRL_SET_TIME, &ticks); - } - else + /* insert delay work list */ + work->flags |= RT_WORK_STATE_SUBMITTING; + work->workqueue = queue; + work->timeout_tick = rt_tick_get() + ticks; + + list_tmp = &(queue->delayed_list); + rt_list_for_each_entry(work_tmp, &(queue->delayed_list), list) { - rt_timer_init(&(work->timer), "work", _delayed_work_timeout_handler, - work, ticks, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER); - work->flags |= RT_WORK_STATE_SUBMITTING; + if ((work_tmp->timeout_tick - work->timeout_tick) == 0) + { + continue; + } + else if ((work_tmp->timeout_tick - work->timeout_tick) < RT_TICK_MAX / 2) + { + list_tmp = &(work_tmp->list); + break; + } } - work->workqueue = queue; - /* insert delay work list */ - rt_list_insert_after(queue->delayed_list.prev, &(work->list)); + rt_list_insert_before(list_tmp, &(work->list)); - err = rt_timer_start(&(work->timer)); + rt_completion_done(&(queue->wakeup_completion)); + err = RT_EOK; } else { - err = - RT_ERROR; + err = -RT_ERROR; } - rt_spin_unlock_irqrestore(&(queue->spinlock), level); return err; } @@ -146,61 +170,17 @@ static rt_err_t _workqueue_submit_work(struct rt_workqueue *queue, static rt_err_t _workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work) { rt_base_t level; - rt_err_t err; + rt_err_t err; level = rt_spin_lock_irqsave(&(queue->spinlock)); rt_list_remove(&(work->list)); - work->flags &= ~RT_WORK_STATE_PENDING; - /* Timer started */ - if (work->flags & RT_WORK_STATE_SUBMITTING) - { - if ((err = rt_timer_stop(&(work->timer))) != RT_EOK) - { - goto exit; - } - rt_timer_detach(&(work->timer)); - work->flags &= ~RT_WORK_STATE_SUBMITTING; - } - err = queue->work_current != work ? RT_EOK : -RT_EBUSY; + work->flags = 0; + err = queue->work_current != work ? RT_EOK : -RT_EBUSY; work->workqueue = RT_NULL; -exit: rt_spin_unlock_irqrestore(&(queue->spinlock), level); return err; } -static void _delayed_work_timeout_handler(void *parameter) -{ - struct rt_work *work; - struct rt_workqueue *queue; - rt_base_t level; - - work = (struct rt_work *)parameter; - queue = work->workqueue; - - RT_ASSERT(work->flags & RT_WORK_STATE_SUBMITTING); - RT_ASSERT(queue != RT_NULL); - - level = rt_spin_lock_irqsave(&(queue->spinlock)); - rt_timer_detach(&(work->timer)); - work->flags &= ~RT_WORK_STATE_SUBMITTING; - /* remove delay list */ - rt_list_remove(&(work->list)); - /* insert work queue */ - if (queue->work_current != work) - { - rt_list_insert_after(queue->work_list.prev, &(work->list)); - work->flags |= RT_WORK_STATE_PENDING; - } - /* whether the workqueue is doing work */ - if (queue->work_current == RT_NULL) - { - /* resume work thread, and do a re-schedule if succeed */ - rt_thread_resume(queue->work_thread); - } - - rt_spin_unlock_irqrestore(&(queue->spinlock), level); -} - /** * @brief Initialize a work item, binding with a callback function. * @@ -221,8 +201,8 @@ void rt_work_init(struct rt_work *work, work->work_func = work_func; work->work_data = work_data; work->workqueue = RT_NULL; - work->flags = 0; - work->type = 0; + work->flags = 0; + work->type = 0; } /** @@ -248,6 +228,7 @@ struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_siz rt_list_init(&(queue->delayed_list)); queue->work_current = RT_NULL; rt_sem_init(&(queue->sem), "wqueue", 0, RT_IPC_FLAG_FIFO); + rt_completion_init(&(queue->wakeup_completion)); /* create the work thread */ queue->work_thread = rt_thread_create(name, _workqueue_thread_entry, queue, stack_size, priority, 10); @@ -346,14 +327,10 @@ rt_err_t rt_workqueue_urgent_work(struct rt_workqueue *queue, struct rt_work *wo /* NOTE: the work MUST be initialized firstly */ rt_list_remove(&(work->list)); rt_list_insert_after(&queue->work_list, &(work->list)); - /* whether the workqueue is doing work */ - if (queue->work_current == RT_NULL) - { - /* resume work thread, and do a re-schedule if succeed */ - rt_thread_resume(queue->work_thread); - } + rt_completion_done(&(queue->wakeup_completion)); rt_spin_unlock_irqrestore(&(queue->spinlock), level); + return RT_EOK; } diff --git a/components/drivers/pm/Kconfig b/components/drivers/pm/Kconfig index 0ed83510d49..f3c04aabc21 100644 --- a/components/drivers/pm/Kconfig +++ b/components/drivers/pm/Kconfig @@ -19,6 +19,10 @@ config RT_USING_PM bool "PM Device suspend change sleep mode" default n + config PM_DISABLE_MODULE + bool "PM disable module" + default n + config PM_ENABLE_THRESHOLD_SLEEP_MODE bool "PM using threshold time change sleep mode" default n diff --git a/components/drivers/pm/pm.c b/components/drivers/pm/pm.c index b4ad3b2bbd9..9ca9bdc0e44 100644 --- a/components/drivers/pm/pm.c +++ b/components/drivers/pm/pm.c @@ -22,35 +22,35 @@ /* tickless threshold time */ #ifndef PM_TICKLESS_THRESHOLD_TIME -#define PM_TICKLESS_THRESHOLD_TIME 2 +#define PM_TICKLESS_THRESHOLD_TIME 2 #endif /* tickless threshold : sleep mode */ #ifndef PM_TICKLESS_THRESHOLD_MODE -#define PM_TICKLESS_THRESHOLD_MODE PM_SLEEP_MODE_IDLE +#define PM_TICKLESS_THRESHOLD_MODE PM_SLEEP_MODE_IDLE #endif /* busy : sleep mode */ #ifndef PM_BUSY_SLEEP_MODE -#define PM_BUSY_SLEEP_MODE PM_SLEEP_MODE_IDLE +#define PM_BUSY_SLEEP_MODE PM_SLEEP_MODE_IDLE #endif /* suspend : suspend sleep mode */ #ifndef PM_SUSPEND_SLEEP_MODE -#define PM_SUSPEND_SLEEP_MODE PM_SLEEP_MODE_IDLE +#define PM_SUSPEND_SLEEP_MODE PM_SLEEP_MODE_IDLE #endif #ifdef PM_ENABLE_THRESHOLD_SLEEP_MODE #ifndef PM_LIGHT_THRESHOLD_TIME -#define PM_LIGHT_THRESHOLD_TIME 5 +#define PM_LIGHT_THRESHOLD_TIME 5 #endif #ifndef PM_DEEP_THRESHOLD_TIME -#define PM_DEEP_THRESHOLD_TIME 20 +#define PM_DEEP_THRESHOLD_TIME 20 #endif #ifndef PM_STANDBY_THRESHOLD_TIME -#define PM_STANDBY_THRESHOLD_TIME 100 +#define PM_STANDBY_THRESHOLD_TIME 100 #endif #endif @@ -63,7 +63,7 @@ static rt_uint8_t _pm_default_sleep = RT_PM_DEFAULT_SLEEP_MODE; static rt_uint8_t _pm_default_deepsleep = RT_PM_DEFAULT_DEEPSLEEP_MODE; static struct rt_pm_notify _pm_notify; -static rt_uint8_t _pm_init_flag = 0; +static rt_uint8_t _pm_init_flag = 0; rt_weak rt_uint32_t rt_pm_enter_critical(rt_uint8_t sleep_mode) { @@ -110,9 +110,9 @@ static void pm_sleep(struct rt_pm *pm, uint8_t sleep_mode) */ static rt_err_t _pm_device_suspend(rt_uint8_t mode) { - rt_err_t ret = RT_EOK; + rt_err_t ret = RT_EOK; struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; + rt_slist_t *node = RT_NULL; for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) { @@ -120,7 +120,7 @@ static rt_err_t _pm_device_suspend(rt_uint8_t mode) if (device_pm->ops != RT_NULL && device_pm->ops->suspend != RT_NULL) { ret = device_pm->ops->suspend(device_pm->device, mode); - if(ret != RT_EOK) + if (ret != RT_EOK) { break; } @@ -136,7 +136,7 @@ static rt_err_t _pm_device_suspend(rt_uint8_t mode) static void _pm_device_resume(rt_uint8_t mode) { struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; + rt_slist_t *node = RT_NULL; for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) { @@ -154,7 +154,7 @@ static void _pm_device_resume(rt_uint8_t mode) static void _pm_device_frequency_change(rt_uint8_t mode) { struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; + rt_slist_t *node = RT_NULL; for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) { @@ -177,7 +177,7 @@ static void _pm_frequency_scaling(struct rt_pm *pm) { level = rt_hw_interrupt_disable(); /* change system runing mode */ - if(pm->ops->run != RT_NULL) + if (pm->ops->run != RT_NULL) { pm->ops->run(pm, pm->run_mode); } @@ -188,6 +188,7 @@ static void _pm_frequency_scaling(struct rt_pm *pm) } } +#ifndef PM_DISABLE_MODULE /** * judge sleep mode from sleep request * @@ -200,7 +201,7 @@ static rt_uint8_t _judge_sleep_mode(void) rt_uint16_t index; rt_uint16_t len; - for (index = 0; index < PM_SLEEP_MODE_MAX -1; index++) + for (index = 0; index < PM_SLEEP_MODE_MAX - 1; index++) { for (len = 0; len < ((PM_MODULE_MAX_ID + 31) / 32); len++) { @@ -209,61 +210,13 @@ static rt_uint8_t _judge_sleep_mode(void) } } - return PM_SLEEP_MODE_MAX; /* default sleep mode */ -} - -/** - * This function selects the sleep mode according to the rt_pm_request/rt_pm_release count. - */ -static rt_uint8_t _pm_select_sleep_mode(struct rt_pm *pm) -{ - int index; - rt_uint8_t mode; - - mode = _pm_default_deepsleep; - rt_uint8_t request_mode = _judge_sleep_mode(); - for (index = PM_SLEEP_MODE_NONE; index < PM_SLEEP_MODE_MAX; index ++) - { - if (pm->modes[index]) - { - mode = index; - break; - } - } - - /* select the high power mode */ - if (request_mode < mode) - mode = request_mode; - - return mode; -} - -/** - * pm module request delay sleep. - */ -void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout) -{ - rt_base_t level; - struct rt_pm *pm; - - if (_pm_init_flag == 0) - return; - - if (module_id > (PM_MODULE_MAX_ID - 1)) - return; - - level = rt_hw_interrupt_disable(); - pm = &_pm; - pm->module_status[module_id].busy_flag = RT_TRUE; - pm->module_status[module_id].timeout = timeout; - pm->module_status[module_id].start_time = rt_tick_get(); - rt_hw_interrupt_enable(level); + return PM_SLEEP_MODE_MAX; /* default sleep mode */ } /** * This function check if all modules in idle status. */ -static rt_bool_t _pm_device_check_idle(void) +static rt_bool_t _pm_module_check_idle(void) { struct rt_pm *pm; @@ -278,7 +231,7 @@ static rt_bool_t _pm_device_check_idle(void) if (rt_tick_get() - pm->module_status[i].start_time > pm->module_status[i].timeout) { pm->module_status[i].busy_flag = RT_FALSE; - pm->module_status[i].timeout = 0x00; + pm->module_status[i].timeout = 0x00; } } if (pm->module_status[i].busy_flag == RT_TRUE) @@ -290,6 +243,39 @@ static rt_bool_t _pm_device_check_idle(void) return RT_TRUE; } +#endif + +/** + * This function selects the sleep mode according to the rt_pm_request/rt_pm_release count. + */ +static rt_uint8_t _pm_select_sleep_mode(struct rt_pm *pm) +{ + int index; + rt_uint8_t mode; + + mode = _pm_default_deepsleep; + for (index = PM_SLEEP_MODE_NONE; index < PM_SLEEP_MODE_MAX; index++) + { + if (pm->modes[index]) + { + mode = index; + break; + } + } + +#ifndef PM_DISABLE_MODULE + { + rt_uint8_t request_mode; + request_mode = _judge_sleep_mode(); + /* select the high power mode */ + if (request_mode < mode) + mode = request_mode; + } +#endif + + return mode; +} + /** * @brief Get the next system wake-up time * @note When used by default, it goes into STANDBY mode and sleeps forever. tickless external rewriting is required @@ -300,11 +286,11 @@ rt_weak rt_tick_t pm_timer_next_timeout_tick(rt_uint8_t mode) { switch (mode) { - case PM_SLEEP_MODE_LIGHT: - return rt_timer_next_timeout_tick(); - case PM_SLEEP_MODE_DEEP: - case PM_SLEEP_MODE_STANDBY: - return rt_lptimer_next_timeout_tick(); + case PM_SLEEP_MODE_LIGHT: + return rt_timer_next_timeout_tick(); + case PM_SLEEP_MODE_DEEP: + case PM_SLEEP_MODE_STANDBY: + return rt_lptimer_next_timeout_tick(); } return RT_TICK_MAX; @@ -370,22 +356,23 @@ static void _pm_change_sleep_mode(struct rt_pm *pm) { rt_tick_t timeout_tick = 0, delta_tick = 0; rt_base_t level = 0; - uint8_t sleep_mode = PM_SLEEP_MODE_DEEP; level = rt_pm_enter_critical(pm->sleep_mode); /* judge sleep mode from module request */ pm->sleep_mode = _pm_select_sleep_mode(pm); +#ifndef PM_DISABLE_MODULE /* module busy request check */ - if (_pm_device_check_idle() == RT_FALSE) + if (_pm_module_check_idle() == RT_FALSE) { - sleep_mode = PM_BUSY_SLEEP_MODE; + uint8_t sleep_mode = PM_BUSY_SLEEP_MODE; if (sleep_mode < pm->sleep_mode) { pm->sleep_mode = sleep_mode; /* judge the highest sleep mode */ } } +#endif if (_pm.sleep_mode == PM_SLEEP_MODE_NONE) { @@ -487,7 +474,7 @@ void rt_system_power_manager(void) */ rt_err_t rt_pm_request(rt_uint8_t mode) { - rt_base_t level; + rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) @@ -501,9 +488,9 @@ rt_err_t rt_pm_request(rt_uint8_t mode) } level = rt_hw_interrupt_disable(); - pm = &_pm; + pm = &_pm; if (pm->modes[mode] < 255) - pm->modes[mode] ++; + pm->modes[mode]++; rt_hw_interrupt_enable(level); return RT_EOK; @@ -518,7 +505,7 @@ rt_err_t rt_pm_request(rt_uint8_t mode) */ rt_err_t rt_pm_release(rt_uint8_t mode) { - rt_base_t level; + rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) @@ -532,9 +519,9 @@ rt_err_t rt_pm_release(rt_uint8_t mode) } level = rt_hw_interrupt_disable(); - pm = &_pm; + pm = &_pm; if (pm->modes[mode] > 0) - pm->modes[mode] --; + pm->modes[mode]--; rt_hw_interrupt_enable(level); return RT_EOK; @@ -549,7 +536,7 @@ rt_err_t rt_pm_release(rt_uint8_t mode) */ rt_err_t rt_pm_release_all(rt_uint8_t mode) { - rt_base_t level; + rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) @@ -562,14 +549,15 @@ rt_err_t rt_pm_release_all(rt_uint8_t mode) return -RT_EINVAL; } - level = rt_hw_interrupt_disable(); - pm = &_pm; + level = rt_hw_interrupt_disable(); + pm = &_pm; pm->modes[mode] = 0; rt_hw_interrupt_enable(level); return RT_EOK; } +#ifndef PM_DISABLE_MODULE /** * Upper application or device driver requests the system * stall in corresponding power mode. @@ -577,9 +565,9 @@ rt_err_t rt_pm_release_all(rt_uint8_t mode) * @param module_id the application or device module id * @param mode the system power sleep mode */ -rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t mode) +rt_err_t rt_pm_module_request(rt_uint16_t module_id, rt_uint8_t mode) { - rt_base_t level; + rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) @@ -597,11 +585,11 @@ rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t mode) return -RT_EINVAL; } - level = rt_hw_interrupt_disable(); - pm = &_pm; + level = rt_hw_interrupt_disable(); + pm = &_pm; pm->module_status[module_id].req_status = 0x01; if (pm->modes[mode] < 255) - pm->modes[mode] ++; + pm->modes[mode]++; rt_hw_interrupt_enable(level); return RT_EOK; @@ -615,9 +603,9 @@ rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t mode) * @param mode the system power sleep mode * */ -rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t mode) +rt_err_t rt_pm_module_release(rt_uint16_t module_id, rt_uint8_t mode) { - rt_base_t level; + rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) @@ -636,9 +624,9 @@ rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t mode) } level = rt_hw_interrupt_disable(); - pm = &_pm; + pm = &_pm; if (pm->modes[mode] > 0) - pm->modes[mode] --; + pm->modes[mode]--; if (pm->modes[mode] == 0) pm->module_status[module_id].req_status = 0x00; rt_hw_interrupt_enable(level); @@ -654,9 +642,9 @@ rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t mode) * @param mode the system power sleep mode * */ -rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode) +rt_err_t rt_pm_module_release_all(rt_uint16_t module_id, rt_uint8_t mode) { - rt_base_t level; + rt_base_t level; struct rt_pm *pm; if (_pm_init_flag == 0) @@ -669,15 +657,53 @@ rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t mode) return -RT_EINVAL; } - level = rt_hw_interrupt_disable(); - pm = &_pm; - pm->modes[mode] = 0; + level = rt_hw_interrupt_disable(); + pm = &_pm; + pm->modes[mode] = 0; pm->module_status[module_id].req_status = 0x00; rt_hw_interrupt_enable(level); return RT_EOK; } +/** + * pm module request delay sleep. + */ +void rt_pm_module_delay_sleep(rt_uint16_t module_id, rt_tick_t timeout) +{ + rt_base_t level; + struct rt_pm *pm; + + if (_pm_init_flag == 0) + return; + + if (module_id > (PM_MODULE_MAX_ID - 1)) + return; + + level = rt_hw_interrupt_disable(); + pm = &_pm; + pm->module_status[module_id].busy_flag = RT_TRUE; + pm->module_status[module_id].timeout = timeout; + pm->module_status[module_id].start_time = rt_tick_get(); + rt_hw_interrupt_enable(level); +} + +rt_uint32_t rt_pm_module_get_status(void) +{ + rt_uint8_t index = 0; + struct rt_pm *pm; + rt_uint32_t req_status = 0x00; + pm = &_pm; + + for (index = 0; index < PM_MODULE_MAX_ID; index++) + { + if (pm->module_status[index].req_status == 0x01) + req_status |= 1 << index; + } + + return req_status; +} + /** * This function will let current module work with specified sleep mode. * @@ -700,74 +726,76 @@ rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode) return -RT_EINVAL; } - level = rt_hw_interrupt_disable(); + level = rt_hw_interrupt_disable(); _pm.sleep_status[mode][module_id / 32] |= 1 << (module_id % 32); rt_hw_interrupt_enable(level); return RT_EOK; } /** - * This function will let current module work with PM_SLEEP_MODE_NONE mode. + * When current module don't work, release requested sleep mode. * * @param module_id the pm module id + * @param mode the pm sleep mode * * @return NULL */ -rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id) +rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode) { - return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_NONE); + rt_base_t level; + + if (module_id >= PM_MODULE_MAX_ID) + { + return -RT_EINVAL; + } + + if (mode >= (PM_SLEEP_MODE_MAX - 1)) + { + return -RT_EINVAL; + } + + level = rt_hw_interrupt_disable(); + _pm.sleep_status[mode][module_id / 32] &= ~(1 << (module_id % 32)); + rt_hw_interrupt_enable(level); + return RT_EOK; } +#endif + /** - * This function will let current module work with PM_SLEEP_MODE_IDLE mode. + * This function will let current module work with PM_SLEEP_MODE_NONE mode. * * @param module_id the pm module id * * @return NULL */ -rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id) +rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id) { - return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_IDLE); + return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_NONE); } /** - * This function will let current module work with PM_SLEEP_MODE_LIGHT mode. + * This function will let current module work with PM_SLEEP_MODE_IDLE mode. * * @param module_id the pm module id * * @return NULL */ -rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id) +rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id) { - return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_LIGHT); + return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_IDLE); } /** - * When current module don't work, release requested sleep mode. + * This function will let current module work with PM_SLEEP_MODE_LIGHT mode. * * @param module_id the pm module id - * @param mode the pm sleep mode * * @return NULL */ -rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode) +rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id) { - rt_base_t level; - - if (module_id >= PM_MODULE_MAX_ID) - { - return -RT_EINVAL; - } - - if (mode >= (PM_SLEEP_MODE_MAX - 1)) - { - return -RT_EINVAL; - } - - level = rt_hw_interrupt_disable(); - _pm.sleep_status[mode][module_id / 32] &= ~(1 << (module_id % 32)); - rt_hw_interrupt_enable(level); - return RT_EOK; + return rt_pm_sleep_request(module_id, PM_SLEEP_MODE_LIGHT); } /** @@ -833,7 +861,7 @@ void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_o void rt_pm_device_unregister(struct rt_device *device) { struct rt_device_pm *device_pm = RT_NULL; - rt_slist_t *node = RT_NULL; + rt_slist_t *node = RT_NULL; for (node = rt_slist_first(&_pm.device_list); node; node = rt_slist_next(node)) { device_pm = rt_slist_entry(node, struct rt_device_pm, list); @@ -852,7 +880,7 @@ void rt_pm_device_unregister(struct rt_device *device) void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data) { _pm_notify.notify = notify; - _pm_notify.data = data; + _pm_notify.data = data; } /** @@ -867,22 +895,22 @@ void rt_pm_default_set(rt_uint8_t sleep_mode) * RT-Thread device interface for PM device */ static rt_ssize_t _rt_pm_device_read(rt_device_t dev, - rt_off_t pos, - void *buffer, - rt_size_t size) + rt_off_t pos, + void *buffer, + rt_size_t size) { struct rt_pm *pm; - rt_size_t length; + rt_size_t length; length = 0; - pm = (struct rt_pm *)dev; + pm = (struct rt_pm *)dev; RT_ASSERT(pm != RT_NULL); if (pos < PM_SLEEP_MODE_MAX) { int mode; - mode = pm->modes[pos]; + mode = pm->modes[pos]; length = rt_snprintf(buffer, size, "%d", mode); } @@ -890,9 +918,9 @@ static rt_ssize_t _rt_pm_device_read(rt_device_t dev, } static rt_ssize_t _rt_pm_device_write(rt_device_t dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) + rt_off_t pos, + const void *buffer, + rt_size_t size) { unsigned char request; @@ -900,7 +928,7 @@ static rt_ssize_t _rt_pm_device_write(rt_device_t dev, { /* get request */ request = *(unsigned char *)buffer; - if (request == 0x01) + if (request == 0x01) { rt_pm_request(pos); } @@ -937,9 +965,9 @@ static rt_err_t _rt_pm_device_control(rt_device_t dev, rt_err_t rt_pm_run_enter(rt_uint8_t mode) { - rt_base_t level = 0; - struct rt_pm *pm = RT_NULL; - rt_err_t ret = RT_EOK; + rt_base_t level = 0; + struct rt_pm *pm = RT_NULL; + rt_err_t ret = RT_EOK; if (_pm_init_flag == 0) return -RT_EIO; @@ -953,7 +981,7 @@ rt_err_t rt_pm_run_enter(rt_uint8_t mode) if (mode < pm->run_mode) { /* change system runing mode */ - if(pm->ops != RT_NULL && pm->ops->run != RT_NULL) + if (pm->ops != RT_NULL && pm->ops->run != RT_NULL) { pm->ops->run(pm, mode); } @@ -972,13 +1000,13 @@ rt_err_t rt_pm_run_enter(rt_uint8_t mode) #ifdef RT_USING_DEVICE_OPS const static struct rt_device_ops pm_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - _rt_pm_device_read, - _rt_pm_device_write, - _rt_pm_device_control, + { + RT_NULL, + RT_NULL, + RT_NULL, + _rt_pm_device_read, + _rt_pm_device_write, + _rt_pm_device_control, }; #endif @@ -994,9 +1022,9 @@ void rt_system_pm_init(const struct rt_pm_ops *ops, void *user_data) { struct rt_device *device; - struct rt_pm *pm; + struct rt_pm *pm; - pm = &_pm; + pm = &_pm; device = &(_pm.parent); device->type = RT_Device_Class_PM; @@ -1006,14 +1034,14 @@ void rt_system_pm_init(const struct rt_pm_ops *ops, #ifdef RT_USING_DEVICE_OPS device->ops = &pm_ops; #else - device->init = RT_NULL; - device->open = RT_NULL; - device->close = RT_NULL; - device->read = _rt_pm_device_read; - device->write = _rt_pm_device_write; - device->control = _rt_pm_device_control; + device->init = RT_NULL; + device->open = RT_NULL; + device->close = RT_NULL; + device->read = _rt_pm_device_read; + device->write = _rt_pm_device_write; + device->control = _rt_pm_device_control; #endif - device->user_data = user_data; + device->user_data = user_data; /* register PM device to the system */ rt_device_register(device, "pm", RT_DEVICE_FLAG_RDWR); @@ -1023,7 +1051,9 @@ void rt_system_pm_init(const struct rt_pm_ops *ops, /* when system power on, set default sleep modes */ pm->modes[pm->sleep_mode] = 1; +#ifndef PM_DISABLE_MODULE pm->module_status[PM_POWER_ID].req_status = 1; +#endif pm->run_mode = RT_PM_DEFAULT_RUN_MODE; pm->timer_mask = timer_mask; @@ -1034,7 +1064,7 @@ void rt_system_pm_init(const struct rt_pm_ops *ops, rt_slist_init(&pm->device_list); #if IDLE_THREAD_STACK_SIZE <= 256 - #error "[pm.c ERR] IDLE Stack Size Too Small!" +#error "[pm.c ERR] IDLE Stack Size Too Small!" #endif _pm_init_flag = 1; @@ -1044,7 +1074,7 @@ void rt_system_pm_init(const struct rt_pm_ops *ops, #include static const char *_pm_sleep_str[] = PM_SLEEP_MODE_NAMES; -static const char *_pm_run_str[] = PM_RUN_MODE_NAMES; +static const char *_pm_run_str[] = PM_RUN_MODE_NAMES; static void rt_pm_release_mode(int argc, char **argv) { @@ -1085,12 +1115,12 @@ MSH_CMD_EXPORT_ALIAS(rt_pm_request_mode, pm_request, request power management mo static void rt_module_release_mode(int argc, char **argv) { int module = 0; - int mode = 0; + int mode = 0; if (argc >= 3) { module = atoi(argv[1]); - mode = atoi(argv[2]); + mode = atoi(argv[2]); } rt_pm_module_release(module, mode); @@ -1100,12 +1130,12 @@ MSH_CMD_EXPORT_ALIAS(rt_module_release_mode, pm_module_release, release module p static void rt_module_release_mode_all(int argc, char **argv) { int module = 0; - int mode = 0; + int mode = 0; if (argc >= 3) { module = atoi(argv[1]); - mode = atoi(argv[2]); + mode = atoi(argv[2]); } rt_pm_module_release_all(module, mode); @@ -1115,32 +1145,34 @@ MSH_CMD_EXPORT_ALIAS(rt_module_release_mode_all, pm_module_release_all, release static void rt_module_request_mode(int argc, char **argv) { int module = 0; - int mode = 0; + int mode = 0; if (argc >= 3) { module = atoi(argv[1]); - mode = atoi(argv[2]); + mode = atoi(argv[2]); } rt_pm_module_request(module, mode); } MSH_CMD_EXPORT_ALIAS(rt_module_request_mode, pm_module_request, request power management mode); +#ifndef PM_DISABLE_MODULE static void rt_module_delay_sleep(int argc, char **argv) { - int module = 0; + int module = 0; unsigned int timeout = 0; if (argc >= 3) { - module = atoi(argv[1]); + module = atoi(argv[1]); timeout = atoi(argv[2]); } rt_pm_module_delay_sleep(module, timeout); } MSH_CMD_EXPORT_ALIAS(rt_module_delay_sleep, pm_module_delay, module request delay sleep); +#endif static void rt_pm_run_mode_switch(int argc, char **argv) { @@ -1154,22 +1186,6 @@ static void rt_pm_run_mode_switch(int argc, char **argv) } MSH_CMD_EXPORT_ALIAS(rt_pm_run_mode_switch, pm_run, switch power management run mode); -rt_uint32_t rt_pm_module_get_status(void) -{ - rt_uint8_t index = 0; - struct rt_pm *pm; - rt_uint32_t req_status = 0x00; - pm = &_pm; - - for (index = 0; index < PM_MODULE_MAX_ID; index ++) - { - if (pm->module_status[index].req_status == 0x01) - req_status |= 1<= 3) { module = atoi(argv[1]); - mode = atoi(argv[2]); + mode = atoi(argv[2]); rt_pm_sleep_request(module, mode); } } @@ -1229,12 +1245,12 @@ MSH_CMD_EXPORT(pm_sleep_request, pm_sleep_request module sleep_mode); static void pm_sleep_release(int argc, char **argv) { int module = 0; - int mode = 0; + int mode = 0; if (argc >= 3) { module = atoi(argv[1]); - mode = atoi(argv[2]); + mode = atoi(argv[2]); rt_pm_sleep_release(module, mode); } } @@ -1243,14 +1259,14 @@ MSH_CMD_EXPORT(pm_sleep_release, pm_sleep_release module sleep_mode); static void rt_pm_dump_status(void) { - rt_uint32_t index; + rt_uint32_t index; struct rt_pm *pm; pm = &_pm; rt_kprintf("| Power Management Mode | Counter | Timer |\n"); rt_kprintf("+-----------------------+---------+-------+\n"); - for (index = 0; index < PM_SLEEP_MODE_MAX; index ++) + for (index = 0; index < PM_SLEEP_MODE_MAX; index++) { int has_timer = 0; if (pm->timer_mask & (1 << index)) @@ -1263,24 +1279,26 @@ static void rt_pm_dump_status(void) rt_kprintf("pm current sleep mode: %s\n", _pm_sleep_str[pm->sleep_mode]); rt_kprintf("pm current run mode: %s\n", _pm_run_str[pm->run_mode]); +#ifndef PM_DISABLE_MODULE rt_kprintf("\n"); rt_kprintf("| module | busy | start time | timeout |\n"); rt_kprintf("+--------+------+------------+-----------+\n"); - for (index = 0; index < PM_MODULE_MAX_ID; index ++) + for (index = 0; index < PM_MODULE_MAX_ID; index++) { - if ((pm->module_status[index].busy_flag == RT_TRUE) || - (pm->module_status[index].req_status != 0x00)) + if ((pm->module_status[index].busy_flag == RT_TRUE) || (pm->module_status[index].req_status != 0x00)) { rt_kprintf("| %04d | %d | 0x%08x | 0x%08x |\n", - index, pm->module_status[index].busy_flag, - pm->module_status[index].start_time, - pm->module_status[index].timeout); + index, pm->module_status[index].busy_flag, + pm->module_status[index].start_time, + pm->module_status[index].timeout); } } rt_kprintf("+--------+------+------------+-----------+\n"); +#endif } FINSH_FUNCTION_EXPORT_ALIAS(rt_pm_dump_status, pm_dump, dump power management status); MSH_CMD_EXPORT_ALIAS(rt_pm_dump_status, pm_dump, dump power management status); -#endif + +#endif /* RT_USING_FINSH */ #endif /* RT_USING_PM */ diff --git a/components/fal/src/fal_rtt.c b/components/fal/src/fal_rtt.c index 9ef5be14401..9ae93ea6793 100644 --- a/components/fal/src/fal_rtt.c +++ b/components/fal/src/fal_rtt.c @@ -10,6 +10,8 @@ */ #include +#include +#include #include #define DBG_TAG "FAL" @@ -50,7 +52,7 @@ static rt_err_t blk_dev_control(rt_device_t dev, rt_uint8_t cmd, void *args) return -RT_ERROR; } - memcpy(geometry, &part->geometry, sizeof(struct rt_device_blk_geometry)); + rt_memcpy(geometry, &part->geometry, sizeof(struct rt_device_blk_geometry)); } else if (cmd == RT_DEVICE_CTRL_BLK_ERASE) {