Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

296
sdk/hal/dev.c Normal file
View File

@@ -0,0 +1,296 @@
#include "basic_include.h"
struct dev_mgr {
struct dev_obj *devs;
struct dev_hotplug_obj *hotplug;
os_mutex_t mutex;
};
__bobj static struct dev_mgr s_dev_mgr;
__init int32 dev_init()
{
os_mutex_init(&s_dev_mgr.mutex);
s_dev_mgr.devs = NULL;
s_dev_mgr.hotplug = NULL;
return RET_OK;
}
void dev_put(struct dev_obj *dev)
{
if (dev && dev->hotplug) {
if(atomic_dec_and_test(&dev->ref)){
os_free(dev);
}
}
}
struct dev_obj *dev_get(uint16 dev_id)
{
struct dev_obj *dev = NULL;
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
dev = s_dev_mgr.devs;
while (dev) {
if (dev->dev_id == dev_id) {
break;
}
dev = dev->next;
}
if (dev && dev->hotplug) {
atomic_inc(&dev->ref);
if (atomic_read(&dev->ref) > 32) {
//os_printf(KERN_WARNING"Device %d Ref is %d, Maybe device reference exception!!!(%08x)\r\n", dev_id, atomic_read(&dev->ref),__builtin_return_address(0));
}
}
os_mutex_unlock(&s_dev_mgr.mutex);
return dev;
}
void dev_busy(struct dev_obj *dev, uint8 busy, uint8 set)
{
uint32 flag = disable_irq();
if (set) {
dev->busy |= busy;
} else {
dev->busy &= ~busy;
}
enable_irq(flag);
}
__init int32 dev_register(uint16 dev_id, struct dev_obj *device)
{
struct dev_obj *dev;
if (dev_id == 0 || device == NULL) {
return -EINVAL;
}
if (atomic_read(&device->ref) == 0) {
atomic_set(&device->ref, 1); //未初始化
}
dev = dev_get(dev_id);
if (dev) {
dev_put(dev);
os_printf(KERN_WARNING"Device id %d already exists!!\r\n", dev_id);
return -EEXIST;
}
#ifdef CONFIG_SLEEP
os_blklist_init(&device->blklist);
#endif
device->dev_id = dev_id;
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
device->next = s_dev_mgr.devs;
s_dev_mgr.devs = device;
atomic_inc(&device->ref);
os_mutex_unlock(&s_dev_mgr.mutex);
return RET_OK;
}
int32 dev_unregister(struct dev_obj *device)
{
struct dev_obj *dev = NULL;
struct dev_obj *last = NULL;
if (device == NULL) {
return RET_OK;
}
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
dev = s_dev_mgr.devs;
while (dev) {
if (dev == device) {
if (device == s_dev_mgr.devs) {
s_dev_mgr.devs = device->next;
} else {
last->next = device->next;
}
#ifdef CONFIG_SLEEP
os_blklist_del(&device->blklist);
#endif
break;
}
last = dev;
dev = dev->next;
}
dev_put(device);
os_mutex_unlock(&s_dev_mgr.mutex);
return RET_OK;
}
#ifdef CONFIG_SLEEP
int32 dev_suspended(struct dev_obj *dev, uint8 suspend)
{
if (dev->suspend && suspend && !__in_interrupt()) { /* 非中断上下文直接挂起当前task */
os_printf(KERN_WARNING"device %d has been suspended!\r\n", dev->dev_id);
os_blklist_suspend(&dev->blklist, NULL);
}
return dev->suspend;
}
__weak int32 dev_suspend_hook(struct dev_obj *dev, uint16 type)
{
return 1;
}
int32 dev_suspend(uint16 type)
{
int32 loop;
struct dev_obj *dev = NULL;
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
dev = s_dev_mgr.devs;
while (dev) {
if (dev->ops && dev->ops->suspend && !dev->suspend) {
os_printf("%s: func= %x\r\n", __func__, dev->ops->suspend);
if (dev_suspend_hook(dev, type)) {
loop = 0;
dev->suspend = 1;
while (dev->busy) {
os_sleep_ms(1);
if (loop++ > 100) {
loop = 0;
os_printf(KERN_WARNING"device %d busy !!!!\r\n", dev->dev_id);
}
}
dev->ops->suspend(dev);
}
}
dev = dev->next;
}
os_mutex_unlock(&s_dev_mgr.mutex);
return RET_OK;
}
__weak int32 dev_resume_hook(struct dev_obj *dev, uint16 type, uint32 wkreason)
{
return 1;
}
int32 dev_resume(uint16 type, uint32 wkreason)
{
struct dev_obj *dev = NULL;
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
dev = s_dev_mgr.devs;
while (dev) {
if (dev->ops && dev->ops->resume && dev->suspend) {
os_printf("%s: func= %x\r\n", __func__, dev->ops->resume);
if (dev_resume_hook(dev, type, wkreason)) {
dev->ops->resume(dev);
dev->suspend = 0;
os_blklist_resume(&dev->blklist);//唤醒所有被挂起的task
}
}
dev = dev->next;
}
os_mutex_unlock(&s_dev_mgr.mutex);
return RET_OK;
}
#else
int32 dev_suspended(struct dev_obj *dev, uint8 suspend)
{
return 0;
}
__weak int32 dev_suspend_hook(struct dev_obj *dev, uint16 type)
{
return 1;
}
int32 dev_suspend(uint16 type)
{
return RET_ERR;
}
__weak int32 dev_resume_hook(struct dev_obj *dev, uint16 type, uint32 wkreason)
{
return 1;
}
int32 dev_resume(uint16 type, uint32 wkreason)
{
return RET_ERR;
}
#endif
int32 dev_hotplug_in(void *hdl, uint16 dev_id, uint16 dev_type, void *info)
{
struct dev_hotplug_obj *dev;
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
dev = s_dev_mgr.hotplug;
while (dev) {
if (dev->hdl == hdl) {
break;
}
dev = dev->next;
}
if (dev) {
dev->dev_id = dev_id;
dev->dev_type = dev_type;
dev->info = info;
} else {
dev = os_zalloc(sizeof(struct dev_hotplug_obj));
if (dev) {
dev->hdl = hdl;
dev->dev_id = dev_id;
dev->dev_type = dev_type;
dev->info = info;
dev->next = s_dev_mgr.hotplug;
s_dev_mgr.hotplug = dev;
}
}
os_mutex_unlock(&s_dev_mgr.mutex);
return dev ? RET_OK : -ENOMEM;
}
int32 dev_hotplug_out(void *hdl)
{
struct dev_hotplug_obj *dev = NULL;
struct dev_hotplug_obj *prev = NULL;
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
dev = s_dev_mgr.hotplug;
while (dev) {
if (dev->hdl == hdl) {
if (prev == NULL) {
s_dev_mgr.hotplug = dev->next;
} else {
prev->next = dev->next;
}
os_free(dev);
break;
} else {
prev = dev;
dev = dev->next;
}
}
os_mutex_unlock(&s_dev_mgr.mutex);
return RET_OK;
}
int32 dev_hotplug_walk(uint16 type, dev_hotplug_walkcb cb)
{
struct dev_hotplug_obj *dev;
if (cb == NULL) {
return -EINVAL;
}
os_mutex_lock(&s_dev_mgr.mutex, osWaitForever);
dev = s_dev_mgr.hotplug;
while (dev) {
if (type == 0 || dev->dev_type == type) {
if (cb((const struct dev_hotplug_obj *)dev)) {
break;
}
}
dev = dev->next;
}
os_mutex_unlock(&s_dev_mgr.mutex);
return RET_OK;
}