project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp: Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem. sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately. sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades. sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for fastboot. Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
131 lines
3.5 KiB
C
131 lines
3.5 KiB
C
/*
|
|
* COPYRIGHT (C) 2018, Real-Thread Information Technology Ltd
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2014-04-16 Grissiom first version
|
|
*/
|
|
|
|
struct rt_watermark_queue
|
|
{
|
|
/* Current water level. */
|
|
unsigned int level;
|
|
unsigned int high_mark;
|
|
unsigned int low_mark;
|
|
rt_list_t suspended_threads;
|
|
};
|
|
|
|
/** Init the struct rt_watermark_queue.
|
|
*/
|
|
void rt_wm_que_init(struct rt_watermark_queue *wg,
|
|
unsigned int low, unsigned int high);
|
|
void rt_wm_que_set_mark(struct rt_watermark_queue *wg,
|
|
unsigned int low, unsigned int high);
|
|
void rt_wm_que_dump(struct rt_watermark_queue *wg);
|
|
|
|
/* Water marks are often used in performance critical places. Benchmark shows
|
|
* inlining functions will have 10% performance gain in some situation(for
|
|
* example, VBus). So keep the inc/dec compact and inline. */
|
|
|
|
/** Increase the water level.
|
|
*
|
|
* It should be called in the thread that want to raise the water level. If the
|
|
* current level is above the high mark, the thread will be suspended up to
|
|
* @timeout ticks.
|
|
*
|
|
* @return RT_EOK if water level increased successfully. -RT_EFULL on @timeout
|
|
* is zero and the level is above water mark. -RT_ETIMEOUT if timeout occurred.
|
|
*/
|
|
rt_inline rt_err_t rt_wm_que_inc(struct rt_watermark_queue *wg,
|
|
int timeout)
|
|
{
|
|
rt_base_t ilvl;
|
|
|
|
/* Assert as early as possible. */
|
|
if (timeout != 0)
|
|
{
|
|
RT_DEBUG_IN_THREAD_CONTEXT;
|
|
}
|
|
|
|
ilvl = rt_hw_interrupt_disable();
|
|
|
|
while (wg->level > wg->high_mark)
|
|
{
|
|
rt_thread_t thread;
|
|
|
|
if (timeout == 0)
|
|
{
|
|
rt_hw_interrupt_enable(ilvl);
|
|
return -RT_EFULL;
|
|
}
|
|
|
|
thread = rt_thread_self();
|
|
thread->error = RT_EOK;
|
|
rt_thread_suspend(thread);
|
|
rt_list_insert_after(&wg->suspended_threads, &thread->tlist);
|
|
if (timeout > 0)
|
|
{
|
|
rt_timer_control(&(thread->thread_timer),
|
|
RT_TIMER_CTRL_SET_TIME,
|
|
&timeout);
|
|
rt_timer_start(&(thread->thread_timer));
|
|
}
|
|
rt_hw_interrupt_enable(ilvl);
|
|
rt_schedule();
|
|
if (thread->error != RT_EOK)
|
|
return thread->error;
|
|
|
|
ilvl = rt_hw_interrupt_disable();
|
|
}
|
|
|
|
wg->level++;
|
|
|
|
if (wg->level == 0)
|
|
{
|
|
wg->level = ~0;
|
|
}
|
|
|
|
rt_hw_interrupt_enable(ilvl);
|
|
|
|
return RT_EOK;
|
|
}
|
|
|
|
/** Decrease the water level.
|
|
*
|
|
* It should be called by the consumer that drain the water out. If the water
|
|
* level reached low mark, all the thread suspended in this queue will be waken
|
|
* up. It's safe to call this function in interrupt context.
|
|
*/
|
|
rt_inline void rt_wm_que_dec(struct rt_watermark_queue *wg)
|
|
{
|
|
int need_sched = 0;
|
|
rt_base_t ilvl;
|
|
|
|
if (wg->level == 0)
|
|
return;
|
|
|
|
ilvl = rt_hw_interrupt_disable();
|
|
wg->level--;
|
|
if (wg->level == wg->low_mark)
|
|
{
|
|
/* There should be spaces between the low mark and high mark, so it's
|
|
* safe to resume all the threads. */
|
|
while (!rt_list_isempty(&wg->suspended_threads))
|
|
{
|
|
rt_thread_t thread;
|
|
|
|
thread = rt_list_entry(wg->suspended_threads.next,
|
|
struct rt_thread,
|
|
tlist);
|
|
rt_thread_resume(thread);
|
|
need_sched = 1;
|
|
}
|
|
}
|
|
rt_hw_interrupt_enable(ilvl);
|
|
|
|
if (need_sched)
|
|
rt_schedule();
|
|
}
|