imx6ull-驅動開發篇37——Linux MISC 驅動實驗

目錄

MISC 設備驅動

miscdevice結構體

misc_register 函數

misc_deregister 函數

實驗程序編寫

修改設備樹

驅動程序編寫

miscbeep.c

miscbeepApp.c

Makefile 文件

運行測試


MISC 驅動也叫做雜項驅動,也就是當某些外設無法進行分類的時候就可以使用 MISC 驅動。

MISC 設備驅動

?所有的 MISC 設備驅動的主設備號都為 10,不同的設備使用不同的從設備號。MISC 設備會自動創建 cdev,因此采用 MISC 設備驅動可以簡化字符設備驅動的編寫。

miscdevice結構體

我們需要向 Linux 注冊一個 miscdevice 設備, miscdevice是一個結構體,定義在文件 include/linux/miscdevice.h 中。

miscdevice結構體內容如下:

/*** struct miscdevice - 混雜設備(miscdevice)結構體* * 用于表示Linux內核中的混雜設備(次設備號動態分配的字符設備)* 通常用于簡單的字符設備驅動,避免手動申請主設備號*/
struct miscdevice {int minor;                   /* 次設備號(MISC_DYNAMIC_MINOR表示動態分配) */const char *name;            /* 設備名稱(出現在/dev和sysfs中) */const struct file_operations *fops; /* 文件操作集合(實現read/write/ioctl等) *//* 以下字段通常由內核內部管理,驅動無需初始化 */struct list_head list;       /* 內核使用的鏈表頭 */struct device *parent;       /* 父設備指針(可選) */struct device *this_device;  /* 內核創建的設備實例 *//* 可選擴展字段 */const struct attribute_group **groups; /* 屬性組(sysfs接口) */const char *nodename;        /* 設備節點名稱(覆蓋默認的命名規則) */umode_t mode;               /* 設備節點權限(如0644) */
};

定義一個 MISC 設備(miscdevice 類型)以后,我們需要設置 minor、 name 和 fops 這三個成員變量。

minor 表示子設備號, 用戶指定子設備號, Linux 系統已經預定義了一些 MISC 設備的子設備號,這些預定義的子設備號定義在include/linux/miscdevice.h 文件中,如下所示:

/* 輸入設備類 */
#define PSMOUSE_MINOR         1    /* PS/2鼠標設備 */
#define MS_BUSMOUSE_MINOR     2    /* 微軟總線鼠標(已廢棄) */
#define ATIXL_BUSMOUSE_MINOR  3    /* ATI XL總線鼠標(已廢棄) */
#define ATARIMOUSE_MINOR      5    /* Atari總線鼠標(已廢棄) */
#define SUN_MOUSE_MINOR       6    /* Sun鼠標(已廢棄) */
#define APOLLO_MOUSE_MINOR    7    /* Apollo鼠標(已廢棄) */
#define PC110PAD_MINOR        9    /* IBM PC110觸控板 */
#define ADB_MOUSE_MINOR       10   /* ADB總線鼠標(Mac) *//* 存儲/設備控制類 */  
#define WATCHDOG_MINOR        130  /* 看門狗定時器 */
#define TEMP_MINOR            131  /* 溫度傳感器 */
#define RTC_MINOR             135  /* 實時時鐘 */
#define EFI_RTC_MINOR         136  /* EFI實時時鐘 */
#define SUN_OPENPROM_MINOR    139  /* Sun Open PROM *//* 網絡/通信類 */
#define NVRAM_MINOR          144   /* 非易失性RAM */
#define I2O_MINOR            166   /* I2O設備 */
#define MICROCODE_MINOR      184   /* CPU微代碼更新 *//* 特殊功能設備 */  
#define VHCI_MINOR           255   /* USB虛擬主機控制器 */
#define MISC_DYNAMIC_MINOR   255   /* 動態分配標志(與VHCI共享) */

我們在使用的時候可以從這些預定義的子設備號中挑選一個,當然也可以自己定義一個沒有被其他設備使用地子設備號。

name : MISC 設備名字,當此設備注冊成功以后就會在/dev 目錄下生成一個名為 name的設備文件。

fops 就是字符設備的操作集合, MISC 設備驅動最終是需要使用用戶提供的 fops操作集合。

misc_register 函數

當設置好 miscdevice 以后,就需要使用 misc_register 函數向系統中注冊一個 MISC 設備。

misc_register 函數原型如下:

int misc_register(struct miscdevice * misc)
  • misc:要注冊的 MISC 設備。
  • 返回值: 負數,失敗; 0,成功。

在以前的字符設備驅動中,我們會使用如下幾個函數完成設備創建過程:

alloc_chrdev_region(); /* 申請設備號 */
cdev_init(); /* 初始化 cdev */
cdev_add(); /* 添加 cdev */
class_create(); /* 創建類 */
device_create(); /* 創建設備 */

現在只需要使用 misc_register 函數來完成這些功能。

misc_deregister 函數

當我們卸載設備驅動模塊的時候。需要調用 misc_deregister 函數來注銷掉 MISC 設備,

misc_deregister 函數原型如下:

int misc_deregister(struct miscdevice *misc)
  • misc:要注銷的 MISC 設備。
  • 返回值: 負數,失敗; 0,成功。

以前注銷設備驅動的時候,我們需要刪除此前創建的 cdev、設備等等:

cdev_del(); /* 刪除 cdev */
unregister_chrdev_region(); /* 注銷設備號 */
device_destroy(); /* 刪除設備 */
class_destroy(); /* 刪除類 */

現在也只需要一個 misc_deregister 函數來實現。

實驗程序編寫

實驗程序,我們需要采用 platform 加 misc 的方式編寫 beep 驅動,這也是實際的 Linux 驅動中很常用的方法。采用 platform 來實現總線、設備和驅動, misc 主要負責完成字符設備的創建。

beep硬件原理圖和芯片資料,可以參考:裸機學習實驗5——蜂鳴器實驗

修改設備樹

正點原子I.MX6U-ALPHA開發板上的BEEP,使用了SNVS_TAMPER1這個PIN。

打開imx6ull-alientek-emmc.dts,在 iomuxc 節點的 imx6ul-evk 子節點下創建一個名為“pinctrl_beep”的子節點。

pinctrl_beep”節點內容如下所示:

pinctrl_beep: beepgrp {fsl,pins = <MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x10B0 /* beep */>;
};

在根節點“/”下創建 BEEP 節點,節點名為“beep”。

beep”節點內容如下:

beep {#address-cells = <1>;                // 子節點地址空間占1個32位字#size-cells = <1>;                   // 子節點大小空間占1個32位字compatible = "atkalpha-beep";        // 匹配驅動的唯一標識符pinctrl-names = "default";           // 引腳控制狀態名稱pinctrl-0 = <&pinctrl_beep>;         // 關聯的引腳配置組beep-gpio = <&gpio5 1 GPIO_ACTIVE_HIGH>; // GPIO控制定義:// - gpio5組第1個引腳// - 高電平有效status = "okay";                     // 設備啟用狀態
};

最后檢查imx6ull-alientek-emmc.dts文件里,PIN是否被其它外設使用,若有則屏蔽

驅動程序編寫

miscbeep.c

蜂鳴器的驅動文件,代碼如下:
?

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define MISCBEEP_NAME		"miscbeep"	/* 名字 	*/
#define MISCBEEP_MINOR		144			/* 子設備號 */
#define BEEPOFF 			0			/* 關蜂鳴器 */
#define BEEPON 				1			/* 開蜂鳴器 *//* miscbeep設備結構體 */
struct miscbeep_dev{dev_t devid;			/* 設備號 	 */struct cdev cdev;		/* cdev 	*/struct class *class;	/* 類 		*/struct device *device;	/* 設備 	 */struct device_node	*nd; /* 設備節點 */int beep_gpio;			/* beep所使用的GPIO編號		*/
};struct miscbeep_dev miscbeep;		/* beep設備 *//** @description		: 打開設備* @param - inode 	: 傳遞給驅動的inode* @param - filp 	: 設備文件,file結構體有個叫做private_data的成員變量* 					  一般在open的時候將private_data指向設備結構體。* @return 			: 0 成功;其他 失敗*/
static int miscbeep_open(struct inode *inode, struct file *filp)
{filp->private_data = &miscbeep; /* 設置私有數據 */return 0;
}/** @description		: 向設備寫數據 * @param - filp 	: 設備文件,表示打開的文件描述符* @param - buf 	: 要寫給設備寫入的數據* @param - cnt 	: 要寫入的數據長度* @param - offt 	: 相對于文件首地址的偏移* @return 			: 寫入的字節數,如果為負值,表示寫入失敗*/
static ssize_t miscbeep_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{int retvalue;unsigned char databuf[1];unsigned char beepstat;struct miscbeep_dev *dev = filp->private_data;retvalue = copy_from_user(databuf, buf, cnt);if(retvalue < 0) {printk("kernel write failed!\r\n");return -EFAULT;}beepstat = databuf[0];		/* 獲取狀態值 */if(beepstat == BEEPON) {	gpio_set_value(dev->beep_gpio, 0);	/* 打開蜂鳴器 */} else if(beepstat == BEEPOFF) {gpio_set_value(dev->beep_gpio, 1);	/* 關閉蜂鳴器 */}return 0;
}/* 設備操作函數 */
static struct file_operations miscbeep_fops = {.owner = THIS_MODULE,.open = miscbeep_open,.write = miscbeep_write,
};/* MISC設備結構體 */
static struct miscdevice beep_miscdev = {.minor = MISCBEEP_MINOR,.name = MISCBEEP_NAME,.fops = &miscbeep_fops,
};/** @description     : flatform驅動的probe函數,當驅動與*                    設備匹配以后此函數就會執行* @param - dev     : platform設備* @return          : 0,成功;其他負值,失敗*/
static int miscbeep_probe(struct platform_device *dev)
{int ret = 0;printk("beep driver and device was matched!\r\n");/* 設置BEEP所使用的GPIO *//* 1、獲取設備節點:beep */miscbeep.nd = of_find_node_by_path("/beep");if(miscbeep.nd == NULL) {printk("beep node not find!\r\n");return -EINVAL;} /* 2、 獲取設備樹中的gpio屬性,得到BEEP所使用的BEEP編號 */miscbeep.beep_gpio = of_get_named_gpio(miscbeep.nd, "beep-gpio", 0);if(miscbeep.beep_gpio < 0) {printk("can't get beep-gpio");return -EINVAL;}/* 3、設置GPIO5_IO01為輸出,并且輸出高電平,默認關閉BEEP */ret = gpio_direction_output(miscbeep.beep_gpio, 1);if(ret < 0) {printk("can't set gpio!\r\n");}/* 一般情況下會注冊對應的字符設備,但是這里我們使用MISC設備* 所以我們不需要自己注冊字符設備驅動,只需要注冊misc設備驅動即可*/ret = misc_register(&beep_miscdev);if(ret < 0){printk("misc device register failed!\r\n");return -EFAULT;}return 0;
}/** @description     : platform驅動的remove函數,移除platform驅動的時候此函數會執行* @param - dev     : platform設備* @return          : 0,成功;其他負值,失敗*/
static int miscbeep_remove(struct platform_device *dev)
{/* 注銷設備的時候關閉LED燈 */gpio_set_value(miscbeep.beep_gpio, 1);/* 注銷misc設備 */misc_deregister(&beep_miscdev);return 0;
}/* 匹配列表 */static const struct of_device_id beep_of_match[] = {{ .compatible = "atkalpha-beep" },{ /* Sentinel */ }};/* platform驅動結構體 */
static struct platform_driver beep_driver = {.driver     = {.name   = "imx6ul-beep",         /* 驅動名字,用于和設備匹配 */.of_match_table = beep_of_match, /* 設備樹匹配表          */},.probe      = miscbeep_probe,.remove     = miscbeep_remove,
};/** @description	: 驅動出口函數* @param 		: 無* @return 		: 無*/
static int __init miscbeep_init(void)
{return platform_driver_register(&beep_driver);
}/** @description	: 驅動出口函數* @param 		: 無* @return 		: 無*/
static void __exit miscbeep_exit(void)
{platform_driver_unregister(&beep_driver);
}module_init(miscbeep_init);
module_exit(miscbeep_exit);
MODULE_LICENSE("GPL");

關鍵代碼分析如下:

MISC 設備 beep_miscdev結構體,當系統啟動以后就會在/dev/目錄下存在一個名為“miscbeep”的設備文件。

static struct miscdevice beep_miscdev = {.minor = MISCBEEP_MINOR,.name = MISCBEEP_NAME,.fops = &miscbeep_fops,
};

miscbeep_probe函數,platform 框架的 probe 函數,當驅動與設備匹配以后此函數就會執行,首先在此函數中初始化 BEEP 所使用的 IO,然后通過 misc_register 函數向 Linux 內核注冊MISC 設備 beep_miscdev。

ret = misc_register(&beep_miscdev);

miscbeep_remove函數,platform 框架的 remove 函數,調用 misc_deregister 函數來注銷MISC 設備。

misc_deregister(&beep_miscdev);

miscbeepApp.c

測試app文件miscbeepApp.c,代碼如下:

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"#define BEEPOFF	0
#define BEEPON 	1/** @description		: main主程序* @param - argc 	: argv數組元素個數* @param - argv 	: 具體參數* @return 			: 0 成功;其他 失敗*/
int main(int argc, char *argv[])
{int fd, retvalue;char *filename;unsigned char databuf[1];if(argc != 3){printf("Error Usage!\r\n");return -1;}filename = argv[1];fd = open(filename, O_RDWR);	/* 打開beep驅動 */if(fd < 0){printf("file %s open failed!\r\n", argv[1]);return -1;}databuf[0] = atoi(argv[2]);	/* 要執行的操作:打開或關閉 */retvalue = write(fd, databuf, sizeof(databuf));if(retvalue < 0){printf("BEEP Control Failed!\r\n");close(fd);return -1;}retvalue = close(fd); /* 關閉文件 */if(retvalue < 0){printf("file %s close failed!\r\n", argv[1]);return -1;}return 0;
}
Makefile 文件

makefile文件只需要修改?obj-m 變量的值,改為miscbeep.o。

KERNELDIR := /home/huax/linux/linux_test/linux-imx-rel_imx_4.1.15_2.1.0_gaCURRENT_PATH := $(shell pwd)
obj-m := miscbeep.obuild: kernel_modules
kernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

運行測試

編譯代碼:

make -j32 //編譯makefile文件
arm-linux-gnueabihf-gcc miscbeepApp.c -o miscbeepApp  //編譯測試app

編譯成功以后,就會生成一個名為“miscbeep.ko”的驅動模塊文件,和miscbeepApp 應用程序。

將編譯出來的miscbeep.ko 和 miscbeepApp 這兩個文件拷貝到rootfs/lib/modules/4.1.15 目錄中,重啟開發板。

進入到目錄 lib/modules/4.1.15 中,輸入如下命令加載 miscbeep.ko 這個驅動模塊:

depmod //第一次加載驅動的時候需要運行此命令
modprobe miscbeep.ko //加載設備模塊

當驅動模塊加載成功以后,我們可以在/sys/class/misc 這個目錄下看到一個名為“miscbeep”的子目錄,如圖:

所有的 misc 設備都屬于同一個類, /sys/class/misc 目錄下就是 misc 這個類的所有設備,每個設備對應一個子目錄。

驅動與設備匹配成功以后就會生成/dev/miscbeep 這個設備驅動文件,要查看這個文件的主次設備號,可以輸入如下命令:

ls /dev/miscbeep -l

輸入如下命令測試 BEEP:

./miscbeepApp /dev/miscbeep 1 //打開 BEEP
./miscbeepApp /dev/miscbeep 0 //關閉 BEEP

觀察一下 BEEP 能否打開和關閉,如果可以的話就說明驅動工作正常。

卸載驅動,輸入如下命令:

rmmod miscbeep.ko

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94087.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94087.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94087.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C# 項目“交互式展廳管理客戶端“針對的是“.NETFramework,Version=v4.8”,但此計算機上沒有安裝它。

C# 項目“交互式展廳管理客戶端"針對的是".NETFramework,Versionv4.8”&#xff0c;但此計算機上沒有安裝它。 解決方法&#xff1a; C# 項目“交互式展廳管理客戶端"針對的是".NETFramework,Versionv4.8”&#xff0c;但此計算機上沒有安裝它。 下載地址…

FFmpeg及 RTSP、RTMP

FFmpeg 是一個功能強大的跨平臺開源音視頻處理工具集 &#xff0c;集錄制、轉碼、編解碼、流媒體傳輸等功能于一體&#xff0c;被廣泛應用于音視頻處理、直播、點播等場景。它支持幾乎所有主流的音視頻格式和協議&#xff0c;是許多媒體軟件&#xff08;如 VLC、YouTube、抖音等…

金山辦公的服務端開發工程師-25屆春招筆試編程題

1.作弊 溪染&#xff1a;六王畢&#xff0c;四海一&#xff1b;蜀山兀&#xff0c;阿房出。覆壓三百余里&#xff0c;隔離天日。驪山北構而西折&#xff0c;直走咸陽。二川溶溶&#xff0c;流入宮墻。五步一樓&#xff0c;十步一閣&#xff1b;廊腰縵回&#xff0c;檐牙高啄&am…

注意力機制中為什么q與k^T相乘是注意力分數

要理解 “qkT\mathbf{q} \times \mathbf{k}^TqkT 是注意力分數”&#xff0c;核心是抓住注意力機制的本質目標 ——量化 “查詢&#xff08;q&#xff09;” 與 “鍵&#xff08;k&#xff09;” 之間的關聯程度&#xff0c;而向量點積&#xff08;矩陣相乘的元素本質&#xff…

Krea Video:Krea AI推出的AI視頻生成工具

本文轉載自&#xff1a;Krea Video&#xff1a;Krea AI推出的AI視頻生成工具 - Hello123工具導航 ** 一、平臺定位與技術特性 Krea Video 是 Krea AI 推出的 AI 視頻生成工具&#xff0c;通過結合關鍵幀圖像與文本提示實現精準視頻控制。用戶可自定義視頻首尾幀、為每張圖片設…

C++初階(2)C++入門基礎1

C是在C的基礎之上&#xff0c;容納進去了面向對象編程思想&#xff0c;并增加了許多有用的庫&#xff0c;以及編程范式 等。熟悉C語言之后&#xff0c;對C學習有一定的幫助。 本章節主要目標&#xff1a; 補充C語言語法的不足&#xff0c;以及C是如何對C語言設計不合理的地方…

ANSI終端色彩控制知識散播(II):封裝的層次(Python)——不同的邏輯“一樣”的預期

基礎高階各有色&#xff0c;本原純真動乾坤。 筆記模板由python腳本于2025-08-22 18:05:28創建&#xff0c;本篇筆記適合喜歡終端色彩ansi編碼和python的coder翻閱。 學習的細節是歡悅的歷程 博客的核心價值&#xff1a;在于輸出思考與經驗&#xff0c;而不僅僅是知識的簡單復述…

前端無感刷新 Token 的 Axios 封裝方案

在現代前端應用中&#xff0c;基于 Token 的身份驗證已成為主流方案。然而&#xff0c;Token 過期問題常常困擾開發者 —— 如何在不打斷用戶操作的情況下自動刷新 Token&#xff0c;實現 "無感刷新" 體驗&#xff1f;本文將詳細介紹基于 Axios 的解決方案。什么是無…

【數據結構】線性表——鏈表

這里寫自定義目錄標題線性表鏈表&#xff08;鏈式存儲&#xff09;單鏈表的定義單鏈表初始化不帶頭結點的單鏈表初始化帶頭結點的單鏈表初始化單鏈表的插入按位序插入帶頭結點不帶頭結點指定結點的后插操作指定結點的前插操作單鏈表的刪除按位序刪除&#xff08;帶頭結點&#…

容器安全實踐(三):信任、約定與“安全基線”鏡像庫

容器安全實踐&#xff08;一&#xff09;&#xff1a;概念篇 - 從“想當然”到“真相” 容器安全實踐&#xff08;二&#xff09;&#xff1a;實踐篇 - 從 Dockerfile 到 Pod 的權限深耕 在系列的前兩篇文章中&#xff0c;我們探討了容器安全的底層原理&#xff0c;并詳細闡述…

百度面試題:賽馬問題

題目現在有25匹馬和一個賽馬場&#xff0c;賽馬場有5條跑道&#xff08;即一次只能比較5匹馬&#xff09;&#xff0c;并且沒有秒表等計時工具&#xff0c;因此每次賽馬只能知道這5匹馬的相對時間而非絕對時間。問&#xff1a;如何篩選出跑的最快的3匹馬&#xff1f;需要比賽幾…

centos下安裝Nginx(搭建高可用集群)

CentOS-7下安裝Nginx的詳細過程_centos7安裝nginx-CSDN博客 centos換yum軟件管理包鏡像 CentOS 7.* 更換國內鏡像源完整指南_centos7更換國內源-CSDN博客 VMware虛擬機上CentOS配置nginx后,本機無法訪問 執行命令&#xff1a;/sbin/iptables -I INPUT -p tcp --dport 80 -j…

實時視頻技術選型深度解析:RTSP、RTMP 與 WebRTC 的邊界

引言&#xff1a;WebRTC 的“光環”與現實落差 在實時音視頻領域&#xff0c;WebRTC 常常被貼上“終極解決方案”的標簽&#xff1a;瀏覽器原生支持、無需插件、點對點傳輸、毫秒級延遲&#xff0c;這些特性讓它在媒體和開發者群體中擁有了近乎神話般的地位。許多人甚至認為&a…

基于深度學習的阿爾茨海默癥MRI圖像分類系統

基于深度學習的阿爾茨海默癥MRI圖像分類系統 項目概述 阿爾茨海默癥是一種進行性神經退行性疾病&#xff0c;早期診斷對于患者的治療和生活質量至關重要。本項目利用深度學習技術&#xff0c;基于MRI腦部掃描圖像&#xff0c;構建了一個高精度的阿爾茨海默癥分類系統&#xff0…

54 C++ 現代C++編程藝術3-移動構造函數

C 現代C編程藝術3-移動構造函數 文章目錄C 現代C編程藝術3-移動構造函數場景1&#xff1a;動態數組資源轉移 #include <iostream> #include <vector> class DynamicArray { int* data; size_t size; public: // 移動構造函數&#xff08;關鍵實現&#xf…

Sping Boot + RabbitMQ :如何在Spring Boot中整合RabbitMQ實現消息可靠投遞?

Spring Boot整合RabbitMQ實現消息可靠投遞全解析 在分布式系統中&#xff0c;消息中間件是解耦、異步、流量削峰的核心組件。RabbitMQ作為高可靠、易擴展的AMQP協議實現&#xff0c;被廣泛應用于企業級場景。但消息傳遞過程中可能因網絡波動、服務宕機等問題導致消息丟失&#…

STAR-CCM+|K-epsilon湍流模型溯源

【1】引言 三維CFD仿真經典軟件很多&#xff0c;我接觸過的有Ansys和STAR-CCM兩種。因為一些機緣&#xff0c;我使用STAR-CCM更多&#xff0c;今天就來回顧一下STAR-CCM中K-epsilon湍流模型的基本定義。 【2】學習地址介紹 點擊鏈接User Guide可以到達網頁版本的STAR-CCM 24…

osgEarth 圖像融合正片疊底

* 需求&#xff1a;* 高程渲染圖 RGB.tif、 山體陰影圖 AMP.tif** 高程渲染圖 rgb波段分別 乘以 山體陰影圖r波段&#xff0c; 然后除以255(AI說 讀取的紋理就已經歸一化到了 0~1 范圍&#xff0c;不用除以 255)。本人遙感知識匱乏。問了AI,以上 需求在許多商業軟件上已實現。…

Java接口響應速度優化

在 Java 開發中&#xff0c;接口響應速度直接影響用戶體驗和系統吞吐量。優化接口性能需要從代碼、數據庫、緩存、架構等多個維度綜合考量&#xff0c;以下是具體方案及詳細解析&#xff1a;一、代碼層面優化代碼是接口性能的基礎&#xff0c;低效的代碼會直接導致響應緩慢。1.…

A Large Scale Synthetic Graph Dataset Generation Framework的學習筆記

文章的簡介 作者提出了一個可擴展的合成圖生成框架&#xff0c;能夠從真實圖中學習結構和特征分布&#xff0c;并生成任意規模的圖數據集&#xff0c;支持&#xff1a; 節點和邊的結構生成節點和邊的特征生成特征與結構的對齊&#xff08;Aligner&#xff09; 它區別于GraphWor…