国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Openwrt讀取spi-nand協(xié)議Flash芯片UniqueID(華邦為例)

這篇具有很好參考價值的文章主要介紹了Openwrt讀取spi-nand協(xié)議Flash芯片UniqueID(華邦為例)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Flash芯片一般都有一個出廠時由制造商設(shè)定的Unique ID,唯一ID。獲取到可以用來進行各類加密識別認(rèn)證,作為設(shè)備唯一ID的一種。
本文以華邦品牌的flash芯片為例(W25N01GV、W25M02GV),如何在Linux下讀取該ID。

閱讀芯片手冊,了解讀取步驟

一般Unique ID信息都存放在otp區(qū)域里,otp區(qū)域是芯片上一塊特殊的區(qū)域,讀取前需要進行模式切換,具體切換流程需要閱讀芯片手冊,每個廠家都不一樣。
flash uid,OpenWrt,嵌入式硬件,c語言,硬件工程,物聯(lián)網(wǎng)
在目錄里,找到讀取的相關(guān)頁面
flash uid,OpenWrt,嵌入式硬件,c語言,硬件工程,物聯(lián)網(wǎng)
閱讀文檔可以得知,winbond這款芯片otp區(qū)域有十頁,其中第一頁就存放的Unique ID。
讀取需要修改狀態(tài)寄存器的OTP-E位,且讀取完成后需要復(fù)位。否則會影響正常區(qū)域的讀寫。

下面給出patch

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
old mode 100644
new mode 100755
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -48,6 +48,33 @@ static int spinand_read_status(struct spinand_device *spinand, u8 *status)
 	return spinand_read_reg_op(spinand, REG_STATUS, status);
 }
 
+static int spinand_read_status_reg2(struct spinand_device *spinand, u8 *status)
+{
+	return spinand_read_reg_op(spinand, REG_CFG, status);
+}
+
+static int spinand_read_write_status_reg2(struct spinand_device *spinand, int otp_en_flag)
+{
+	u8 val = 0;
+
+	spinand_read_status_reg2(spinand, &val);
+
+	if (otp_en_flag == 0)
+		val &= CFG_OTP_DISABLE;
+	else
+		val |= CFG_OTP_ENABLE;
+
+	spinand_write_reg_op(spinand, REG_CFG, val);
+
+	// reset val
+	val = 0;
+	spinand_read_status_reg2(spinand, &val);
+
+	return 0;
+}
+
 static int spinand_get_cfg(struct spinand_device *spinand, u8 *cfg)
 {
 	struct nand_device *nand = spinand_to_nand(spinand);
@@ -1048,6 +1075,105 @@ static const struct mtd_ooblayout_ops spinand_noecc_ooblayout = {
 	.free = spinand_noecc_ooblayout_free,
 };
 
+static int spinand_unique_id_read(void *priv, u8 *buf, int readlen) {
+	int ret;
+	u8 status;
+	struct spinand_device *spinand = (struct spinand_device *)priv;
+	struct device *dev = &spinand->spimem->spi->dev;
+	u32 addr[5]= {0x00,0x00,0x00,0x00,0x00};
+	int addrlen = 5;
+
+	typedef struct nand_pos my_pos;
+	my_pos pos;
+	typedef struct nand_page_io_req my_req;
+	my_req req;
+
+	if(addrlen != sizeof(struct nand_addr)/sizeof(unsigned int)) {
+		dev_err(dev, "Must provide correct addr(length) for spinand calibration\n");
+		return -EINVAL;
+	}
+
+
+	if (ret)
+		return ret;
+
+	/* We should store our golden data in first target because
+	 * we can't switch target at this moment.
+	 */
+	pos = (my_pos){
+		.target = 0,
+		.lun = *addr,
+		.plane = *(addr+1),
+		.eraseblock = *(addr+2),
+		.page = *(addr+3),
+	};
+
+	req = (my_req){
+		.type = NAND_PAGE_READ,
+		.pos = pos,
+		.dataoffs = *(addr+4),
+		.datalen = readlen,
+		.databuf.in = buf,
+		.mode = MTD_OPS_AUTO_OOB,
+	};
+
+	ret = spinand_load_page_op(spinand, &req);
+	if (ret)
+		return ret;
+
+	ret = spinand_wait(spinand, &status);
+	if (ret < 0)
+		return ret;
+
+	{
+		//struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, buf, readlen);
+		struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, buf, readlen);
+		ret = spi_mem_exec_op(spinand->spimem, &op);
+	}
+
+	return 0;
+}
+
+static int spi_nand_unique_id(struct spinand_device *spinand)
+{
+	int ret = 0;
+	u8 *buf;
+	int readlen = 32;
+
+	buf = kzalloc(readlen, GFP_KERNEL);
+	if(!buf){
+		printk("%s-%d; ERROR - kzalloc func: Insufficient memory allocation failed;\n", __func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	// set Status Register-2, open OTP mode
+	spinand_read_write_status_reg2(spinand, 1);
+
+	spinand_unique_id_read(spinand, buf, readlen);
+
+	// copy spinand->uid from buf
+	memcpy(spinand->uid, buf, sizeof(spinand->uid));
+
+	// reset Status Register-2, close OTP mode
+	spinand_read_write_status_reg2(spinand, 0);
+
+	kfree(buf);
+
+	return 0;
+}
+
 static int spinand_init(struct spinand_device *spinand)
 {
 	struct device *dev = &spinand->spimem->spi->dev;
@@ -1094,6 +1220,16 @@ static int spinand_init(struct spinand_device *spinand)
 	if (ret)
 		goto err_free_bufs;
 
+	// init spinand->uid
+	memset(spinand->uid, 0, sizeof(spinand->uid));
+	// try read flash-chip unique ID
+	if(spi_nand_unique_id(spinand) == 0){
+		// sync uniqiue id
+		mtd->chip_uid = spinand->uid;
+	}
+
 	ret = spinand_upd_cfg(spinand, CFG_OTP_ENABLE, 0);
 	if (ret)
 		goto err_free_bufs;
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
old mode 100644
new mode 100755
index fabd98fe69ad2eeeed2e0b4bec0c5f39a7534320..61531db9ae2c4cd886a1e5863ed7146b8ed48337
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -155,6 +155,7 @@
 #define CFG_OTP_ENABLE		BIT(6)
 #define CFG_ECC_ENABLE		BIT(4)
 #define CFG_QUAD_ENABLE		BIT(0)
+#define CFG_OTP_DISABLE		(~(BIT(6)))
 
 /* status register */
 #define REG_STATUS		0xc0
@@ -361,6 +362,14 @@ struct spinand_dirmap {
 	struct spi_mem_dirmap_desc *rdesc;
 };
 
+/*
+ * SPINAND unique ID length and number of repetitions. The full unique ID is the
+ * manufacturer ID (1B) plus the unique device ID (16B). Also count the '-'
+ * between both IDs and the '\0' at the end in the 'STRING_LEN'.
+ */
+#define SPINAND_UNIQUEID_LEN       16
+
 /**
  * struct spinand_device - SPI NAND device instance
  * @base: NAND device instance
@@ -386,6 +395,7 @@ struct spinand_dirmap {
  *		the stack
  * @manufacturer: SPI NAND manufacturer information
  * @priv: manufacturer private data
+ * @uid: Unique ID of the flash chip (add by IKUAI)
  */
 struct spinand_device {
 	struct nand_device base;
@@ -414,6 +424,9 @@ struct spinand_device {
 	u8 *scratchbuf;
 	const struct spinand_manufacturer *manufacturer;
 	void *priv;
+	u8 uid[SPINAND_UNIQUEID_LEN];
 };
 
 /**

代碼存在優(yōu)化空間,且可以使用linux內(nèi)核原生的自帶寄存器更新函數(shù) spinand_upd_cfg 實現(xiàn),只是該函數(shù)傳參有坑,需要注意。文章來源地址http://www.zghlxwxcb.cn/news/detail-687129.html

到了這里,關(guān)于Openwrt讀取spi-nand協(xié)議Flash芯片UniqueID(華邦為例)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【小米路由器3】breed刷機救磚-nand flash硬改SPI flash-編程器救磚(解決ttl無法救磚問題)

    【小米路由器3】breed刷機救磚-nand flash硬改SPI flash-編程器救磚(解決ttl無法救磚問題)

    大家好,我是老子姓李!(gzh:楠瘦) 本博文帶來 【小米路由器3】變磚,ttl無法救磚,硬改焊接一塊SPI flash,使用編程器刷入小米路由器mini的breed最終成功救磚 。 1.引言 1.1 背景 個人嫌棄小米路由器的自帶固件不夠好用,覺得網(wǎng)速又慢、不夠穩(wěn)定,而且不能裝插件。本著

    2024年02月09日
    瀏覽(219)
  • 【FLASH存儲器系列五】SPI NOR FLASH芯片使用指導(dǎo)之一

    【FLASH存儲器系列五】SPI NOR FLASH芯片使用指導(dǎo)之一

    ??個人主頁: highman110 ??作者簡介:一名硬件工程師,持續(xù)學(xué)習(xí),不斷記錄,保持思考,輸出干貨內(nèi)容 ? 目錄 1芯片簡介 2引腳定義 3功能框圖 4器件操作 4.1操作框圖 4.2標(biāo)準(zhǔn)SPI 4.3DaulSPI 4.4QaudSPI 4.5QPI 4.6DTR(W25Q128不支持) 4.73-字節(jié)/4-字節(jié)地址模式(W25Q128只支持3字節(jié)) 4.8保持

    2023年04月19日
    瀏覽(51)
  • FPGA模塊——SPI協(xié)議(讀寫FLASH)

    FPGA模塊——SPI協(xié)議(讀寫FLASH)

    芯片引腳圖: 內(nèi)部結(jié)構(gòu)圖: 存儲區(qū)域總共分成了32塊,每塊64KB。每塊又分成了16個部分,每個部分4KB。方便進行讀取和局部操作。 電路設(shè)計 SPI的四種模式 這里使用這個模式: 主機和從機在時鐘上升沿放入要輸出的數(shù)據(jù),在時鐘下降沿讀取要輸入的數(shù)據(jù)。 8個時鐘后交換一個

    2024年02月05日
    瀏覽(21)
  • FPGA實現(xiàn)基于SPI協(xié)議的Flash驅(qū)動控制(全擦除、頁擦除、讀數(shù)據(jù)、頁寫、連續(xù)寫—地址寫)

    FPGA實現(xiàn)基于SPI協(xié)議的Flash驅(qū)動控制(全擦除、頁擦除、讀數(shù)據(jù)、頁寫、連續(xù)寫—地址寫)

    本論文使用Verilog HDL硬件描述語言,結(jié)合野火可以FPGA征途Pro開發(fā)板,實現(xiàn)了SPI通信協(xié)議的全擦除,扇區(qū)擦除,讀數(shù)據(jù),頁寫,連續(xù)寫的驅(qū)動設(shè)計。在 Altera Cyclone Ⅳ 芯片上采用“自頂向下”的模塊化設(shè)計思想及 Verilog HDL 硬件描述語言,設(shè)計并實現(xiàn)串行外設(shè)接口(SPI)。在 Qu

    2024年02月12日
    瀏覽(24)
  • 【STM32學(xué)習(xí)】——SPI通信協(xié)議&SPI時序&W25Q64存儲芯片&軟件SPI讀寫

    【STM32學(xué)習(xí)】——SPI通信協(xié)議&SPI時序&W25Q64存儲芯片&軟件SPI讀寫

    目錄 前言 一、SPI通信協(xié)議 1.概述? 2.硬件電路 ?3.移位示意圖 二、SPI時序 1.時序基本單元 2.完整時序波形 三、W25Q64存儲芯片 1.芯片簡介 ?2.硬件電路引腳定義 ?3.芯片框圖 4.Flash操作注意事項 四、軟件SPI讀寫W25Q64 五、SPI通信外設(shè) 總結(jié) 聲明:學(xué)習(xí)筆記來自江科大自化協(xié)B站教

    2024年02月09日
    瀏覽(20)
  • [NAND Flash 6.4] NAND FLASH基本讀操作及原理_NAND FLASH Read Operation源碼實現(xiàn)

    [NAND Flash 6.4] NAND FLASH基本讀操作及原理_NAND FLASH Read Operation源碼實現(xiàn)

    依公知及經(jīng)驗整理,原創(chuàng)保護,禁止轉(zhuǎn)載。 專欄 《深入理解NAND Flash》 返回總目錄 ?全文 6000 字 內(nèi)容摘要 NAND Flash 引腳功能 讀操作步驟 NAND Flash 中的特殊硬件結(jié)構(gòu) NAND Flash 讀寫時的數(shù)據(jù)流向 Read 操作時序 讀時序操作過程的解釋 Read 操作實戰(zhàn)流程設(shè)計 NAND Read 源碼 前言 上面

    2024年01月19日
    瀏覽(39)
  • DSP28335使用SPI從AD2S1210(旋變芯片)讀取位置

    DSP28335使用SPI從AD2S1210(旋變芯片)讀取位置

    精準(zhǔn)的轉(zhuǎn)子位置對于電機精確控制來說至關(guān)重要,利用旋轉(zhuǎn)變壓器獲取轉(zhuǎn)子位置角度是一種常見方案。因此在電控程序中只需要通過主控芯片(以 DSP28335 為例)與旋變解碼芯片(以 AD2S1210 為例)進行通信(以 SPI通信 為例)。 在實際操作中,通過SPI從旋變芯片讀取絕對位置時,讀取

    2024年02月13日
    瀏覽(54)
  • [NAND Flash 6.3] NAND FLASH基本編程(寫)操作及原理_NAND FLASH Program Operation 源碼實現(xiàn)

    依公知及經(jīng)驗整理,原創(chuàng)保護,禁止轉(zhuǎn)載。 專欄 《深入理解NAND Flash》 返回總目錄 全文 3244 字 ? 前言 使用的 NAND FLASH 的硬件原理圖,面對這些引腳,很難明白他們是什么含義,下面先來個熱身: 問1. 原理圖上 NAND FLASH 只有數(shù)據(jù)線,怎么傳輸?shù)刂罚?答1. 在 DATA0~DATA7 上既傳

    2024年01月19日
    瀏覽(29)
  • 【SDN】普通路由器刷OpenWrt+OpenFlow教程完美版_搭建SDN OpenFlow1.3協(xié)議的路由器(Flash<16M)

    【SDN】普通路由器刷OpenWrt+OpenFlow教程完美版_搭建SDN OpenFlow1.3協(xié)議的路由器(Flash<16M)

    Email:louis.yyj.dev@foxmail.com 刷機前請確認(rèn)你的路由器支持OpenWrt,并確定Flash大小,具體方法請進入下面的網(wǎng)址,在Model一欄中輸入

    2024年02月09日
    瀏覽(46)
  • STM32模擬SPI時序配置讀取雙路24位模數(shù)轉(zhuǎn)換(24bit ADC)芯片ADS1220采樣數(shù)據(jù)

    STM32模擬SPI時序配置讀取雙路24位模數(shù)轉(zhuǎn)換(24bit ADC)芯片ADS1220采樣數(shù)據(jù)

    TI公司的雙路24位模數(shù)轉(zhuǎn)換芯片ADS1220具有比較豐富的模式配置,雙路差分輸入采樣也可以配置為4路單端輸入信號采樣。有多種參考電壓源可選,內(nèi)部增益(從1倍到128倍)和輸出率(可達到2K/s)可配置,模擬電壓和數(shù)字電路電壓可單獨設(shè)置等等。這里介紹STM32訪問和讀取ADS12

    2023年04月09日
    瀏覽(119)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包