linux_NandFlash_driver_超詳細分析 .

分類: Linux 驅動 Nand 驅動 474人閱讀 評論(0) 收藏 舉報

今天學習了NandFlash的驅動,硬件操作非常簡單,就是這個linux下的驅動比較復雜,主要還是MTD層的問題,用了一下午時間整理出來一份詳細的分析,只是分析函數結構和調用關系,具體代碼實現就不看了,里面有N個結構體,搞得我頭大。

?

我用linux2.6.25內核,2440板子,先從啟動信息入手。

內核啟動信息,NAND部分:

S3C24XX NAND Driver, (c) 2004 Simtec Electronics

s3c2440-nand s3c2440-nand: Tacls=2, 20ns Twrph0=3 30ns, Twrph1=2 20ns

NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)

Scanning device for bad blocks

Creating 3 MTD partitions on "NAND 64MiB 3,3V 8-bit":

0x00000000-0x00040000 : "boot"

0x0004c000-0x0024c000 : "kernel"

0x0024c000-0x03ffc000 : "yaffs2"

?

第一行,在driver/mtd/nand/s3c2410.c中第910行,s3c2410_nand_init函數:

printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");

?

行二行,同一文件,第212行,s3c2410_nand_inithw函數:

dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));

?

第三行,在driver/mtd/nand/nand_base.c中第2346行,

printk(KERN_INFO "NAND device: Manufacturer ID:" " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id, nand_manuf_ids[maf_idx].name, type->name);

?

第四行,在driver/mtd/nand/nand_bbt.c中第380行,creat_bbt函數:

Printk(KERN INFO " Scanning device for bad blocks \n");

?

第五行,在driver/mtd/mtdpart.c中第340行,add_mtd_partitions函數:

printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);

?

下面三行,是flash分區表,也在mtdpart.c同一函數中,第430行:

printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, slave->offset + slave->mtd.size, slave->mtd.name);

?

MTD體系結構:

在linux中提供了MTD(Memory Technology Device,內存技術設備)系統來建立Flash針對linux的統一、抽象的接口

引入MTD后,linux系統中的Flash設備驅動及接口可分為4層:

設備節點

MTD設備層

MTD原始設備層

硬件驅動層

?

硬件驅動層:Flash硬件驅動層負責底層硬件設備實際的讀、寫、擦除,Linux MTD設備的NAND型Flash驅動位于driver/mtd/nand子目錄下

s3c2410對應的nand Flash驅動為s3c2410.c

MTD原始設備層:MTD原始設備層由兩部分構成,一部分是MTD原始設備的通用代碼,另一部分是各個特定Flash的數據,比如分區

主要構成的文件有:

drivers/mtd/mtdcore.c 支持mtd字符設備

driver/mtd/mtdpart.c? 支持mtd塊設備

MTD設備層:基于MTD原始設備,Linux系統可以定義出MTD的塊設備(主設備號31) 和字符設備(設備號90),構成MTD設備層

?

簡單的說就是:使用一個mtd層來作為具體的硬件設備驅動和上層文件系統的橋梁。mtd給出了系統中所有mtd設備(nand,nor,diskonchip)的統一組織方式。

?

mtd層用一個數組struct mtd_info *mtd_table[MAX_MTD_DEVICES]保存系統中所有的設備,mtd設備利用struct mtd_info 這個結構來描述,該結構中描述了存儲設備的基本信息和具體操作所需要的內核函數,mtd系統的那個機制主要就是圍繞這個結構來實現的。結構體在include/linux/mtd/mtd.h中定義:

struct mtd_info {

u_char type;????????? ??//MTD 設備類型

u_int32_t flags;??? ????//MTD設備屬性標志

u_int32_t size; ????????//標示了這個mtd設備的大小

u_int32_t erasesize; ???//MTD設備的擦除單元大小,對于NandFlash來說就是Block的大小

u_int32_t oobblock;? ????//oob區在頁內的位置,對于512字節一頁的nand來說是512

u_int32_t oobsize;?? ???//oob區的大小,對于512字節一頁的nand來說是16

u_int32_t ecctype;????? //ecc校驗類型

u_int32_t eccsize; ?????//ecc的大小

?

char *name;???????????? //設備的名字

int index;????????????? //設備在MTD列表中的位置

?

struct nand_oobinfo oobinfo; //oob區的信息,包括是否使用ecc,ecc的大小

?

//以下是關于mtd的一些讀寫函數,將在nand_base中的nand_scan中重載

int (*erase)

int (*read)

int (*write)

int (*read_ecc)

int (*write_ecc)

int (*read_oob)

int (*read_oob)

?

void *priv;//設備私有數據指針,對于NandFlash來說指nand芯片的結構

?

下面看nand_chip結構,在include/linux/mtd/nand.h中定義:

struct nand_chip {

void? __iomem?? *IO_ADDR_R;? ??//這是nandflash的讀寫寄存器

void? __iomem???? *IO_ADDR_W;?

//以下都是nandflash的操作函數,這些函數將根據相應的配置進行重載

u_char??? (*read_byte)(struct mtd_info *mtd);

void????? (*write_byte)(struct mtd_info *mtd, u_char byte);

u16?????? (*read_word)(struct mtd_info *mtd);

void????? (*write_word)(struct mtd_info *mtd, u16 word);

void???? (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);

void???? (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);

int???? (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);

void???? (*select_chip)(struct mtd_info *mtd, int chip);

int???? (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);

int????? (*block_markbad)(struct mtd_info *mtd, loff_t ofs);

void???? (*hwcontrol)(struct mtd_info *mtd, int cmd);

int????? (*dev_ready)(struct mtd_info *mtd);

void?? ??(*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);

int??? ??(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);

int???? (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);

int? ?(*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);

void? ??(*enable_hwecc)(struct mtd_info *mtd, int mode);

void??? (*erase_cmd)(struct mtd_info *mtd, int page);

int???? (*scan_bbt)(struct mtd_info *mtd);

int?????? eccmode;?? ??//ecc的校驗模式(軟件,硬件)

int? ?????chip_delay;? //芯片時序延遲參數

int?????? page_shift;? //頁偏移,對于512B/頁的,一般是9

u_char??? *data_buf; ??//數據緩存區

?

跟NAND操作相關的函數:

1、 nand_base.c:

定義了NAND驅動中對NAND芯片最基本的操作函數和操作流程,如擦除、讀寫page、讀寫oob等。當然這些函數都只是進行一些常規的操作,若你的系統在對NAND操作時有一些特殊的動作,則需要在你自己的驅動代碼中進行定義。

2、 nand_bbt.c:

定義了NAND驅動中與壞塊管理有關的函數和結構體。

3、 nand_ids.c:

定義了兩個全局類型的結構體:struct nand_flash_dev nand_flash_ids[ ]和struct nand_manufacturers nand_manuf_ids[ ]。其中前者定義了一些NAND芯片的類型,后者定義了NAND芯片的幾個廠商。NAND芯片的ID至少包含兩項內容:廠商ID和廠商為自己的NAND芯片定義的芯片ID。當NAND加載時會找這兩個結構體,讀出ID,如果找不到,就會加載失敗。

4、 nand_ecc.c:

定義了NAND驅動中與softeware ECC有關的函數和結構體,若你的系統支持hardware ECC,且不需要software ECC,則該文件也不需理會。

?

我們需要關心的是/nand/s3c2410,這個文件實現的是s3c2410/2440nandflash控制器最基本的硬件操作,讀寫擦除操作由上層函數完成。

s3c2410.c分析:

首先看一下要用到的結構體的注冊:

struct s3c2410_nand_mtd {

??? struct mtd_info????? mtd;?? //mtd_info的結構體

??? struct nand_chip???? chip;? //nand_chip的結構體

??? struct s3c2410_nand_set???? *set;

??? struct s3c2410_nand_info ?? *info;

??? int?????????? scan_res;

};

?

enum s3c_cpu_type {? //用來枚舉CPU類型

??? TYPE_S3C2410,

??? TYPE_S3C2412,

??? TYPE_S3C2440,

};

struct s3c2410_nand_info {?

??? /* mtd info */

??? struct nand_hw_control????? controller;

??? struct s3c2410_nand_mtd???? *mtds;

??? struct s3c2410_platform_nand??? *platform;

?

??? /* device info */

??? struct device??????? *device;

??? struct resource????????? *area;

??? struct clk??????? *clk;

??? void __iomem???????? *regs;

??? void __iomem???????? *sel_reg;

??? int?????????? sel_bit;

??? int?????????? mtd_count;

??? unsigned long??????? save_nfconf;

??? enum s3c_cpu_type??? cpu_type;

};

?

設備的注冊:

static int __init s3c2410_nand_init(void)

{

??? printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");

?

??? platform_driver_register(&s3c2412_nand_driver);

??? platform_driver_register(&s3c2440_nand_driver);

??? return platform_driver_register(&s3c2410_nand_driver);

}

platform_driver_register向內核注冊設備,同時支持這三種CPU。

&s3c2440_nand_driver是一個platform_driver類型的結構體:

?

static struct platform_driver s3c2440_nand_driver = {

??? .probe???? = s3c2440_nand_probe,

??? .remove?? = s3c2410_nand_remove,

??? .suspend?? = s3c24xx_nand_suspend,

??? .resume??? = s3c24xx_nand_resume,

??? .driver??? = {

?????? .name? = "s3c2440-nand",

?????? .owner = THIS_MODULE,

??? },

};

?

最主要的函數就是s3c2440_nand_probe,(調用s3c24XX_nand_probe),完成對nand設備的探測,

static int s3c24xx_nand_probe(struct platform_device *pdev,

?????????? ????? enum s3c_cpu_type cpu_type)

{

?????? /*主要完成一些硬件的初始化,其中調用函數:*/

?????? s3c2410_nand_init_chip(info, nmtd, sets);

?????? /*init_chip結束后,調用nand_scan完成對flash的探測及mtd_info讀寫函數的賦值*/

nmtd->scan_res = nand_scan(&nmtd->mtd, (sets) ? sets->nr_chips : 1);

?????? if (nmtd->scan_res == 0) {

?????????? s3c2410_nand_add_partition(info, nmtd, sets);

?????? }

}

Nand_scan是在初始化nand的時候對nand進行的一步非常好重要的操作,在nand_scan中會對我們所寫的關于特定芯片的讀寫函數重載到nand_chip結構中去,并會將mtd_info結構體中的函數用nand的函數來重載,實現了mtd到底層驅動的聯系。

并且在nand_scan函數中會通過讀取nand芯片的設備號和廠家號自動在芯片列表中尋找相應的型號和參數,并將其注冊進去。

?

?

static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,

????????????? ?? struct s3c2410_nand_mtd *nmtd,

????????????? ?? struct s3c2410_nand_set *set)

{

??? struct nand_chip *chip = &nmtd->chip;

??? void __iomem *regs = info->regs;

??? /*以下都是對chip賦值,對應nand_chip中的函數*/

??? chip->write_buf??? = s3c2410_nand_write_buf;? //寫buf

??? chip->read_buf???? = s3c2410_nand_read_buf;?? //讀buf

??? chip->select_chip? = s3c2410_nand_select_chip;//片選

??? chip->chip_delay?? = 50;

??? chip->priv ?? = nmtd;

??? chip->options ?? = 0;

??? chip->controller?? = &info->controller; //??

?

??? switch (info->cpu_type) {

??? case TYPE_S3C2440:

?????? chip->IO_ADDR_W = regs + S3C2440_NFDATA;? //數據寄存器

?????? info->sel_reg?? = regs + S3C2440_NFCONT;? //控制寄存器

?????? info->sel_bit = S3C2440_NFCONT_nFCE;

?????? chip->cmd_ctrl? = s3c2440_nand_hwcontrol; //硬件控制

?????? chip->dev_ready = s3c2440_nand_devready;? //設備就緒

?????? chip->read_buf? = s3c2440_nand_read_buf;? //讀buf

?????? chip->write_buf?? = s3c2440_nand_write_buf;//寫buf

?????? break;

? ? }

??? chip->IO_ADDR_R = chip->IO_ADDR_W; //讀寫寄存器都是同一個

??? nmtd->info ?? = info;

??? nmtd->mtd.priv??? ?? = chip; //私有數據指針指向chip

??? nmtd->mtd.owner??? = THIS_MODULE;

??? nmtd->set? ?? = set;

??? /*后面是和ECC校驗有關的,省略*/

}

?

初始化后,實現對nand的基本硬件操作就可以了,包括以下函數:

s3c2410_nand_inithw? //初始化硬件,在probe中調用

s3c2410_nand_select_chip? //片選

s3c2440_nand_hwcontrol? //硬件控制,其實就是片選

s3c2440_nand_devready? //設備就緒

s3c2440_nand_enable_hwecc? //使能硬件ECC校驗

s3c2440_nand_calculate_ecc? //計算ECC

s3c2440_nand_read_buf? s3c2440_nand_write_buf

?

注冊nand設備到MTD原始設備層:(這個函數由probe調用)

#ifdef CONFIG_MTD_PARTITIONS?? //如果定義了MTD分區

static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,

????????????? ????? struct s3c2410_nand_mtd *mtd,

????????????? ????? struct s3c2410_nand_set *set)

{

??? if (set == NULL)

?????? return add_mtd_device(&mtd->mtd);

??? if (set->nr_partitions > 0 && set->partitions != NULL) {

?????? return add_mtd_partitions(&mtd->mtd, set->partitions, set->nr_partitions);

??? }

??? return add_mtd_device(&mtd->mtd);

}

#else

注冊設備用這兩個函數:

add_mtd_device? //如果nand整體不分區,用這個,

//該函數在mtdcore.c中實現

add_mtd_partitions? //如果nand是分區結構,用這個,

//該函數在mtdpart.c中實現

同樣,注銷設備也有兩個函數:

del_mtd_device

del_mtd_partitions

?

NandFlash還有一個分區表結構體,mtd_partition,這個是在arch/arm/plat-s3c24XX/common-smdk.c中定義的。

?

static struct mtd_partition smdk_default_nand_part[] = {

??? [0] = {

?????? .name? = "boot",

?????? .size? = 0x00040000,

?????? .offset??? = 0,

??? },

??? [1] = {

?????? .name? = "kernel",

?????? .offset = 0x0004C000,

?????? .size? = 0x00200000,

??? },

??? [2] = {

?????? .name? = "yaffs2",

?????? .offset = 0x0024C000,

?????? .size? = 0x03DB0000,

??? },

};

記錄了當前的nand flash有幾個分區,每個分區的名字,大小,偏移量是多少

系統就是依靠這些分區表找到各個文件系統的

這些分區表nand中的文件系統沒有必然關系,分區表只是把flash分成不同的部分

?

如果自己編寫一個nandflash驅動,只需要填充這三個結構體:

Mtd_info???? nand_chip???? mtd_partition

并實現對物理設備的控制,上層的驅動控制已由mtd做好了,不需要關心

?

2410NandFlash控制器

管腳配置

D[7:0]: DATA0-7 數據/命令/地址/的輸入/輸出口(與數據總線共享)

CLE : GPA17? 命令鎖存使能 (輸出)

ALE : GPA18? 地址鎖存使能(輸出)

nFCE : GPA22 NAND Flash 片選使能(輸出)

nFRE : GPA20 NAND Flash 讀使能 (輸出)

nFWE : GPA19 NAND Flash 寫使能 (輸出)

R/nB : GPA21 NAND Flash 準備好/繁忙(輸入)

?

相關寄存器:

NFCONF?? NandFlash控制寄存器

?[15]NandFlash控制器使能/禁止???? 0 = 禁止?? 1 = 使能

?[14:13]保留

?[12]初始化ECC解碼器/編碼器??? 0 = 不初始化?? 1 = 初始化

?[11]芯片使能? nFCE控制??????? 0 = 使能?????? 1 = 禁止

?[10:8]TACLS?? 持續時間 = HCLK*(TACLS+1)

?[6:4] TWRPH0

?[2:0] TWRPH1

?

NFCMD? 命令設置寄存器

?[7:0] 命令值

NFADDR 地址設置寄存器

?[7:0] 存儲器地址

NFDATA 數據寄存器

?[7:0] 存放數據

NFSTAT 狀態寄存器

?[0]??? 0 = 存儲器忙???? 1 = 存儲器準備好

NFECC? ECC寄存器

?[23:16]ECC校驗碼2

?[15:8] ECC校驗碼1

?[8:0]? ECC校驗碼0

?

寫操作:

寫入操作以頁為單位。寫入必須在擦除之后,否則寫入將出錯。

頁寫入周期中包括以下步驟:

寫入串行數據輸入指令(80h)。然后寫入4個字節的地址,最后串行寫入數據(528Byte)。串行寫入的數據最多為528byte。

串行數據寫入完成后,需要寫入“頁寫入確認”指令10h,這條指令將初始化器件內部寫入操作。

10h寫入之后,nand flash的內部寫控制器將自動執行內部寫入和校驗中必要的算法和時序,

系統可以通過檢測R/B的輸出,或讀狀態寄存器的狀態位(I/O 6)來判斷內部寫入是否結束

?

擦除操作:

擦除操作時以塊(16K Byte)為單位進行的

擦除的啟動指令為60h,隨后的3個時鐘周期是塊地址。其中只有A14到A25是有效的,而A9到A13是可以忽略的。

塊地址之后是擦除確認指令D0h,用來開始內部的擦除操作。

器件檢測到擦除確認命令后,在/WE的上升沿啟動內部寫控制器,開始執行擦除和擦除校驗。內部擦除操作完成后,應該檢測寫狀態位(I/O 0),從而了解擦除操作是否成功完成。

?

讀操作有兩種讀模式:

讀方式1用于讀正常數據;

讀方式2用于讀附加數據

在初始上電時,器件進入缺省的“讀方式1模式”。在這一模式下,頁讀取操作通過將00h指令寫入指令寄存器,接著寫入3個地址(一個列地址和2個行地址)來啟動。一旦頁讀指令被器件鎖存,下面的頁操作就不需要再重復寫入指令了。

寫入指令和地址后,處理器可以通過對信號線R//B的分析來判斷該才作是否完成。

外部控制器可以再以50ns為周期的連續/RE脈沖信號的控制下,從I/O口依次讀出數據

備用區域的從512到527地址的數據,可以通過讀方式2指令進行指令進行讀取(命令為50h)。地址A0~A3設置了備用區域的起始地址,A4~A7被忽略掉

?

時序要求:

寫地址、數據、命令時,nCE、nWE信號必須為低電平,它們在nWE信號的上升沿被鎖存。命令鎖存使能信號CLE和地址鎖存信號ALE用來區分I/O引腳上傳輸的是命令還是地址。

?

尋址方式:

NAND Flash的尋址方式和NAND Flash的memory組織方式緊密相關。NAND Flash的數據以bit的方式保存在memory cell,一個cell中只能存儲一個bit。這些cell以8個或者16個為單位,連成bit line,形成byte(x8)/word(x16),這就是NAND的數據寬度。

??????

?????? 這些Line會再組成Page,典型情況下:通常是528Byte/page或者264Word/page。然后,每32個page形成一個Block,Sizeof(block)=16.5kByte。其中528Byte = 512Byte+16Byte,前512Byte為數據區,后16Byte存放數據校驗碼等,因此習慣上人們稱1page有512個字節,每個Block有16Kbytes;

????? 現在在一些大容量的FLASH存貯設備中也采用以下配置:2112 Byte /page 或 1056 Word/page;64page/Block;Sizeof(block) = 132kByte;同上:2112 = 2048 +64,人們習慣稱一頁含2k個字節,一個Block含有64個頁,容量為128KB;

?

?????? Block是NAND Flash中最大的操作單元,擦除可以按照block或page為單位完成,而編程/讀取是按照page為單位完成的

?????? 所以,按照這樣的組織方式可以形成所謂的三類地址:

???????? -Block? Address?? 塊地址

???????? -Page?? Address?? 頁地址

???????? -Column Address? 列地址

??? ? 首先,必須清楚一點,對于NAND Flash來講,地址和命令只能在I/O[7:0]上傳遞,數據寬度可以是8位或者16位,但是,對于x16的NAND Device,I/O[15:8]只用于傳遞數據。

??? 清楚了這一點,我們就可以開始分析NAND Flash的尋址方式了。

以528Byte/page 總容量64M Byte+512kbyte的NAND器件為例:

因為

1page=528byte=512byte(Main Area)+16byte(Spare Area)

1block=32page = 16kbyte

64Mbyte = 4096 Block

?

用戶數據保存在main area中。

512byte需要9bit來表示,對于528byte系列的NAND,這512byte被分成1st half和2nd half,各自的訪問由所謂的pointer operation命令來選擇,也就是選擇了bit8的高低。因此A8就是halfpage pointer,A[7:0]就是所謂的column address。

?

32個page需要5bit來表示,占用A[13:9],即該page在塊內的相對地址。

Block的地址是由A14以上的bit來表示,例如64MB的NAND,共4096block,因此,需要12個bit來表示,即A[25:14],如果是1Gbit的528byte/page的NAND Flash,共8192個block,則block address用A[30:14]表示。

?

NAND Flash的地址表示為:

Block Address? |? Page Address in block? |? half page pointer | ?Column Address

地址傳送順序是Column Address , Page Address , Block Address。

?

例如一個地址:0x00aa55aa

? ?????? 0000 0000? 1010? 1010? 0101 ?0101 ?1010 ?1010

?

由于地址只能在I/O[7:0]上傳遞,因此,必須采用移位的方式進行。

例如,對于64MBx8的NAND flash,地址范圍是0~0x3FF_FFFF,只要是這個范圍內的數值表示的地址都是有效的。

??????

?????? 以NAND_ADDR為例:

?????? 第1步是傳遞column address,就是NAND_ADDR[7:0],不需移位即可傳遞到I/O[7:0]上, 而halfpage pointer即bit8是由操作指令決定的,即指令決定在哪個halfpage上進行讀寫,而真正的bit8的值是don't care的。

?????? 第2步就是將NAND_ADDR右移9位,將NAND_ADDR[16:9]傳到I/O[7:0]上;

?????? 第3步將NAND_ADDR[24:17]放到I/O上;

?????? 第4步需要將NAND_ADDR[25]放到I/O上;

?????? 因此,整個地址傳遞過程需要4步才能完成,即4-step addressing。

?????? 如果NAND Flash的容量是32MB以下,那么,block adress最高位只到bit24,因此尋址只需要3步。

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

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

相關文章

HTTPS 路徑配置

1: 首先安裝 fiddlercertmaker.exe 文件2:Tools -> HTTPS 3: Connections 勾中Allow remote computer to connect轉載于:https://www.cnblogs.com/eason-d/p/7492177.html

CMOS圖像傳感器——相位對焦

之前介紹了許多自動對焦的方案 自動對焦方法學習_滄海一升的博客-CSDN博客自動對焦的各類方法學習介紹https://blog.csdn.net/qq_21842097/article/details/121373263 在里面提到了遮蔽像素相位檢測法,原理上算是相位檢測法(Phase Detection Auto Focus,PDAF)的一種。…

51nod 1343 行列式的根

這題分塊搞一搞,算到最后發現結果就是算矩陣J的行列式,要取模m,那個sign消掉了。 參考文獻在這,歐幾里德算法的應用,金斌 代碼還是比較好寫的,python代碼 n,mmap(int,raw_input().split()) a[] for i in ra…

Spring Cloud Config 和Spring Cloud Bus實現配置中心

2019獨角獸企業重金招聘Python工程師標準>>> Spring Cloud是很多組件的集合,Spring將常用的技術框架進行包裝和整合,如mybatis zookeeper rabbitmq redis等等,還有一些科技公司貢獻出來的一些經過生產環境驗證的組件如奈飛公司貢獻…

ARM Linux啟動過程分析

1. 引 言 Linux 最初是由瑞典赫爾辛基大學的學生 Linus Torvalds在1991 年開發出來的,之后在 GNU的支持下,Linux 獲得了巨大的發展。雖然 Linux 在桌面 PC 機上的普及程度遠不及微軟的 Windows 操作系統,但它的發展速度之快、用戶數量的日益…

你有沒有靠譜的基因?一個人靠不靠譜,其實就看這三點:“凡事有交代,件件有著落,事事有回音。”...

你有沒有靠譜的基因?一個人靠不靠譜,其實就看這三點:“凡事有交代,件件有著落,事事有回音。” 故事一、做了就忘了? 一天上班后,我讓小王給上級部門送一個材料。 一個小時過去了,沒…

CMOS圖像傳感器——閃爍(flicker)現象

一、概述 閃爍(Flicker),通常發生在室內場景,曝光時間設置如果不是光源能量周期的整數倍,則圖像不同位置處積累的信號強度不同,并呈周期性變化,這是單幀圖像的情況。在視頻序列上,如果滿足一定條件,視頻會出現條紋模式在垂直方向上緩慢移動。 二、形成原因 1、光源 …

一條命令教你安裝centos下面的pip服務

yum install -y python-pip轉載于:https://blog.51cto.com/12131824/2177874

strcpy,memcpy,memset函數實現

strcpy 實現,只能拷貝字符串 char* strcpy(char* des,const char* source) {char* rdes; assert((des ! NULL) && (source ! NULL));while((*des *source)!\0);return r; } memcpy 實現,注意目的地址和源地址重合的情況,以及強制類…

CMOS圖像傳感器——圖像傳感器噪聲

圖像傳感器噪聲取決于圖像傳感器的制作工藝、內部結構及內部補償技術等原因,噪聲反應了圖像傳感器的內部特性。CMOS圖像傳感器基本原理見: CMOS圖像傳感——概述_滄海一升的博客-CSDN博客_cmos圖像傳感器CMOS圖像傳感器基本介紹https://blog.csdn.net/qq_21842097/article/d…

TI Davinci DM6441嵌入式Linux移植攻略——UBL移植篇

目錄(?)[] 一DM6441的Boot過程簡介二DM6441的UBL移植 CCS文件夾Common文件夾GNU文件夾 移植DDR2移植Nand Flash其它 聲明:本文參考網友zjb_integrated的文章《TI Davinci DM6446開發攻略——UBL移植》和《DAVINCI DM365-DM368開發攻略——U-BOOT-2010.12及UBL的移…

python接口自動化測試(二)-requests.get()

環境搭建好后,接下來我們先來了解一下requests的一些簡單使用,主要包括: requests常用請求方法使用,包括:get,postrequests庫中的Session、Cookie的使用其它高級部分:認證、代理、證書驗證、超時…

從一個Android碼農視角回顧2018GDD大會

兩天的GDD大會結束了,很開心,可以看得出,這次Google真的很用心。不但分享的內容質量很高。而且又有得吃又有得玩,還有許多好看的小姐姐,真不妄我請了兩天年假來參加這個大會。先來幾張圖鎮樓 哈哈,跑題了。…

Python3.x和Python2.x的區別[轉]

Python3.x和Python2.x的區別 1.性能 Py3.0運行 pystone benchmark的速度比Py2.5慢30%。Guido認為Py3.0有極大的優化空間,在字符串和整形操作上可 以取得很好的優化結果。 Py3.1性能比Py2.5慢15%,還有很大的提升空間。 2.編碼 Py3.X源碼文件默認使用utf-8…

數字圖像處理——圖像銳化

圖像增強是圖像處理的一個重要環節,早期的圖像處理就是從圖像增強開始的,人們研究對質量低的圖像進行處理以獲得改善質量后的圖像。現今的圖像增強還為后續的圖像處理,如圖像信息提取、圖像識別等,提供更高識別度的圖像。 從圖像處理技術來看,圖像的攝取、編碼、傳輸和處理…

DAVINCI DM365-DM368開發攻略——U-BOOT-2010.12及UBL的移植

從盛夏走到深秋,我們繼續DAVINCI DM365-DM368的開發。說來慚愧,人家51CTO熱情支持本博客,而本人卻一直沒有像其他博客之星一樣頻繁更新博客,心里確實說不過去。管理公司確實很累,有更急的客戶的項目要做,我…

陳天藝1636050045假設跑步者1小時40分鐘35秒跑了24英里。編寫一個程序顯示每小時以公里為單位的平均速度值...

public class AverageSpeed{ public static void main(String[]args){ double speedkm 60/(45.5/14); double speedm speedkm /1.6; system.out.println(“averagespeed ”speedm "m/h") } }轉載于:https://www.cnblogs.com/Archon-Cty/p/7…

EMVA 1288 測試標準

一、概述 如果要對比兩臺相機的性能,我們應該關注哪些參數呢,是焦距、像素、還是光圈大小?這些參數通常廣為人知,并且很容易做出對比。但在一些專業領域,例如機器視覺、自動駕駛等行業,計算機算法對圖像有著獨特的要求,這些標準有些已經跟不上數字成像的發展步伐,而且其…

Spring Boot - 修改Tomcat默認的8080端口

前言 默認情況下,Spring Boot內置的Tomcat服務會使用8080端口啟動,我們可以使用以下任何技巧去更改默認的Tomcat端口; 注:我們可以通過server.port0配置,去自動配置一個未被占用的http端口,由操作系統實現。…

2017年度目標

語言:python,lisp,js,html5技術:android,hadoop數學:復變函數,代數,概率,數論英語:reading其他:金融/經濟/股票,歷史/史記…