<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > NANDFlashd的讀寫(基于s3c2440)

          NANDFlashd的讀寫(基于s3c2440)

          作者: 時間:2016-11-20 來源:網絡 收藏

          本文引用地址:http://www.ex-cimer.com/article/201611/318935.htm
          1. #ifndef__TEST_H__
          2. #define__TEST_H__
          3. #include"def.h"
          4. #defineMAX_NAND_BLOCK2048//一共2048塊
          5. #defineNAND_PAGE_SIZE2048//每塊main區(qū)2k字節(jié)=2048
          6. typedefstructnand_id_info//芯片的ID信息
          7. {
          8. U8IDm;//廠商ID
          9. U8IDd;//設備ID
          10. U8ID3rd;
          11. U8ID4th;
          12. U8ID5th;
          13. }nand_id_info;
          14. typedefstructbad_block_info//登記壞塊
          15. {
          16. U8area[MAX_NAND_BLOCK];//0表示非壞塊,1表示壞塊
          17. U32sum;//壞塊的總數
          18. }bad_block_info;
          19. //NAND操作指令
          20. #defineNAND_CMD_READ_1st0x00
          21. #defineNAND_CMD_READ_2st0x30
          22. #defineNAND_CMD_RANDOM_WRITE0x85//隨機寫
          23. #defineNAND_CMD_RANDOM_READ_1st0x05
          24. #defineNAND_CMD_RANDOM_READ_2st0xe0
          25. #defineNAND_CMD_READ_CB_1st0x00//將NAND里一塊內容寫進另一塊
          26. #defineNAND_CMD_READ_CB_2st0x35
          27. #defineNAND_CMD_READ_ID0x90
          28. #defineNAND_CMD_RES0xff//復位命令
          29. #defineNAND_CMD_WRITE_PAGE_1st0x80
          30. #defineNAND_CMD_WRITE_PAGE_2st0x10
          31. #defineNAND_CMD_BLOCK_ERASE_1st0x60//擦除命令
          32. #defineNAND_CMD_BLOCK_ERASE_2st0xd0
          33. #defineNAND_CMD_READ_STATUS0x70
          34. //NAND中斷向量
          35. #defineINT_NFCON24
          36. //NFCONFHCLK=100MHZ
          37. #defineS3C2440_NFCONF_TACLS_init(1<<12)
          38. #defineS3C2440_NFCONF_TWRPH0_init(4<<8)
          39. #defineS3C2440_NFCONF_TWRPH1_init(0<<4)
          40. #defineS3C2440_NFCONF_BusWidth_init(0)
          41. #defineS3C2440_NFCONF_init()(rNFCONF=S3C2440_NFCONF_TACLS_init|/
          42. S3C2440_NFCONF_TWRPH0_init|/
          43. S3C2440_NFCONF_TWRPH1_init|/
          44. S3C2440_NFCONF_BusWidth_init)
          45. //NFCONT
          46. #defineS3C2440_NFCONT_LockTight_init(0<<13)
          47. #defineS3C2440_NFCONT_SoftLock_init(0<<12)
          48. #defineS3C2440_NFCONT_EnbIllegalAccINT_init(1<<10)
          49. #defineS3C2440_NFCONT_EnbRnBINT_init(0<<9)
          50. #defineS3C2440_NFCONT_RnB_TransMode_init(0<<8)
          51. #defineS3C2440_NFCONT_SpareECCLock_init(1<<6)
          52. #defineS3C2440_NFCONT_MainECCLock_init(1<<5)
          53. #defineS3C2440_NFCONT_InitECC_init(1<<4)
          54. #defineS3C2440_NFCONT_Reg_nCE_init(1<<1)//初始配置片選無效
          55. #defineS3C2440_NFCONT_MODE_init(0)
          56. #defineS3C2440_NFCONT_init()(rNFCONT=S3C2440_NFCONT_LockTight_init|/
          57. S3C2440_NFCONT_SoftLock_init|/
          58. S3C2440_NFCONT_EnbIllegalAccINT_init|/
          59. S3C2440_NFCONT_EnbRnBINT_init|/
          60. S3C2440_NFCONT_RnB_TransMode_init|/
          61. S3C2440_NFCONT_SpareECCLock_init|/
          62. S3C2440_NFCONT_MainECCLock_init|/
          63. S3C2440_NFCONT_InitECC_init|/
          64. S3C2440_NFCONT_Reg_nCE_init|/
          65. S3C2440_NFCONT_MODE_init)
          66. //NFSTAT
          67. #defineS3C2440_NFSTAT_init()(rNFSTAT&=0x3)
          68. //NFESTAT0
          69. #defineS3C2440_NFESTAT0_init()(rNFESTAT0=0)
          70. //NFESTAT1
          71. #defineS3C2440_NFESTAT1_init()(rNFESTAT1=0)
          72. //
          73. #defineselect_nand()(rNFCONT&=~(1<<1))
          74. #definedis_select_nand()(rNFCONT|=1<<1)
          75. #definecontroller_enable()(rNFCONT|=1)
          76. #definecontroller_disable()(rNFCONT&=~1)
          77. //
          78. voidnand_flash_init(void);//初始化
          79. voidnand_read_id(void);
          80. externintnand_block_erase(U32num);//num要刪除的塊號
          81. externintnand_page_write(U32addr,U8*buffer,U32size);//addr要寫的起始頁地址,buffer要寫的緩存,size要寫的字節(jié)大小最大為4G
          82. externintnand_page_read(U32addr,U8*buffer,U32size);//addr開始頁地址,從每頁00地址開始讀
          83. externintnand_random_read(U32paddr,U32offset,U8*data);//隨機讀數據paddr頁地址,offset頁內偏移地址
          84. externintnand_random_write(U32paddr,U32offset,U8data);//隨機寫,paddr頁地址,offset頁內區(qū)最后一個地偏移地址
          85. externvoidnand_test_bad_block(void);//測試壞塊函數,并標記在nand_bbi變量里和spare里(如果非0xff則為壞塊)
          86. #endif
          87. #include"2440addr.h"
          88. #include"test.h"
          89. #include"def.h"
          90. #defineNAND_DEBUG1//打印一些串口調試信息
          91. #defineUSE_ECC1//使用ECC驗證
          92. nand_id_infonand_id;//定義登記芯片ID的全局變量
          93. bad_block_infonand_bbi;//定義來登記壞的全局變量
          94. voidinit_nand_bbi(void)//初始化變量
          95. {
          96. U32i;
          97. nand_bbi.sum=0;
          98. for(i=0;i
          99. nand_bbi.area[i]=0;//全部初始化為0
          100. }
          101. voidnand_mask_bad_block(U32n)//標志壞塊,n是壞塊的塊號
          102. {
          103. #ifdefNAND_DEBUG
          104. Uart_Printf("NANDfoundandmaskabadblock=%d.",n);
          105. #endif
          106. if(nand_bbi.area[n]!=1)
          107. {
          108. nand_bbi.area[n]=1;
          109. nand_bbi.sum++;
          110. nand_random_write(n*64,2048+64-1,0);//每塊的第一個spare的最后一個字節(jié),標志本塊是否為壞塊,非0xff為壞塊
          111. }
          112. }
          113. intdetect_nand_busy(void)//檢測是否忙
          114. {
          115. U32a;
          116. a=0;
          117. while(!(rNFSTAT&(1<<2)))
          118. {
          119. a++;
          120. if(a==5000000)//等待超時
          121. {
          122. Uart_Printf("/r/nError:DetectNandBusytimeout!!!/r/n");
          123. rNFSTAT|=(1<<2);//清忙標志
          124. return-1;//錯誤返回-1
          125. }
          126. }
          127. rNFSTAT|=(1<<2);//清忙標志
          128. return1;
          129. }
          130. voidnand_reset(void)//NAND復位
          131. {
          132. rNFCMD=NAND_CMD_RES;
          133. detect_nand_busy();//檢測忙
          134. }
          135. voidcontrol_start(void)//芯片開啟
          136. {
          137. select_nand();
          138. controller_enable();
          139. rNFSTAT|=(1<<2);//清忙標志
          140. nand_reset();
          141. }
          142. voidcontrol_end(void)//芯片關閉
          143. {
          144. dis_select_nand();
          145. controller_disable();
          146. }
          147. voidecc_main_init(void)//初始化ECC值
          148. {
          149. rNFCONT|=1<<4;//initEcc
          150. }
          151. voidecc_main_start(void)//開鎖mainECC
          152. {
          153. rNFCONT&=~(1<<5);//unlock
          154. }
          155. voidecc_main_end(void)//鎖定mainECC
          156. {
          157. rNFCONT|=1<<5;//lock
          158. }
          159. voidecc_spare_start(void)//開鎖spareECC
          160. {
          161. rNFCONT&=~(1<<6);//unlock
          162. }
          163. voidecc_spare_end(void)//鎖定spareECC
          164. {
          165. rNFCONT|=1<<6;//lock
          166. }
          167. void__irqnandINT(void)//NAND中斷函數
          168. {
          169. //此處寫處理代碼
          170. #ifdefNAND_DEBUG
          171. Uart_Printf("/r/nNandError...Ininterruptnow!!!");//只有錯誤才會進入中斷
          172. #endif
          173. rSRCPND|=0x1<
          174. rINTPND|=0x1<
          175. }
          176. voidnand_read_id(void)//讀取芯片ID信息
          177. {
          178. control_start();//開控制
          179. rNFCMD=NAND_CMD_READ_ID;
          180. rNFADDR=0;
          181. //讀芯片ID
          182. nand_id.IDm=(U8)rNFDATA8;
          183. nand_id.IDd=(U8)rNFDATA8;
          184. nand_id.ID3rd=(U8)rNFDATA8;
          185. nand_id.ID4th=(U8)rNFDATA8;
          186. nand_id.ID5th=(U8)rNFDATA8;
          187. //打印ID信息
          188. #ifdefNAND_DEBUG
          189. Uart_Printf("/r/nReadNANDFlashID:");
          190. Uart_Printf("/r/nNANDMarkcode:0x%x",nand_id.IDm);
          191. Uart_Printf("/r/nNANDDevicecode:0x%x",nand_id.IDd);
          192. Uart_Printf("/r/nNAND3rdIDcode:0x%x",nand_id.ID3rd);
          193. Uart_Printf("/r/nNAND4thIDcode:0x%x",nand_id.ID4th);
          194. Uart_Printf("/r/nNAND5thIDcode:0x%x",nand_id.ID5th);
          195. #endif
          196. control_end();//關控制
          197. }
          198. //擦出時只要給定塊所在頁的地址,就能擦除整個塊
          199. intnand_block_erase(U32num)//num要刪除的塊號
          200. {
          201. num=num*64;//每塊的第一頁
          202. control_start();//開控制
          203. nand_reset();//復位
          204. rNFCMD=NAND_CMD_BLOCK_ERASE_1st;
          205. rNFADDR=num&0xff;
          206. rNFADDR=(num>>8)&0xff;
          207. rNFADDR=(num>>16)&0xff;
          208. rNFCMD=NAND_CMD_BLOCK_ERASE_2st;
          209. detect_nand_busy();
          210. rNFCMD=NAND_CMD_READ_STATUS;//讀狀態(tài)
          211. if(rNFDATA8&1)//最低位可以判斷擦除和寫是否成功
          212. {
          213. #ifdefNAND_DEBUG
          214. Uart_Printf("/r/nError:nanderaseerror...block=0x%x",num/64);
          215. #endif
          216. control_end();//關控制
          217. nand_mask_bad_block(num/64);//登記為壞塊
          218. return-1;//刪除錯誤返回0
          219. }
          220. control_end();//關控制
          221. #ifdefNAND_DEBUG
          222. Uart_Printf("/r/nNANDblock%derasecompleted.",num/64);
          223. #endif
          224. return1;//擦除成功
          225. }
          226. intnand_page_write(U32addr,U8*buffer,U32size)//addr要寫的起始頁地址,buffer要寫的緩存,size要寫的字節(jié)大小最大為4G
          227. {
          228. U32i,n,p,temp,ecc;
          229. U8*bu;
          230. bu=buffer;
          231. temp=0;
          232. n=size/2048+(((size%2048)==0)?0:1);//計算出要寫的頁數,小于一頁的部分當作一頁
          233. for(i=0;i
          234. {
          235. control_start();//開控制
          236. nand_reset();//復位
          237. #ifdefUSE_ECC
          238. ecc_main_init();
          239. ecc_main_start();//可以產生main區(qū)ECC
          240. #endif
          241. rNFCMD=NAND_CMD_WRITE_PAGE_1st;
          242. rNFADDR=0;//從每頁的0地址開始
          243. rNFADDR=0;//從每頁的0地址開始
          244. rNFADDR=(addr)&0xff;
          245. rNFADDR=(addr>>8)&0xff;
          246. rNFADDR=(addr>>16)&0xff;
          247. for(p=0;p<2048;p++)//寫入一頁
          248. {
          249. temp=temp+1;
          250. if(temp>size)
          251. {
          252. rNFDATA8=0xff;//多余的填寫0xff
          253. }
          254. else
          255. {
          256. rNFDATA8=*(bu+p);
          257. }
          258. }
          259. //delay_lhg(100,100);//
          260. #ifdefUSE_ECC
          261. ecc_main_end();//鎖定main區(qū)ecc
          262. ecc=rNFMECC0;
          263. ecc_spare_start();//解鎖spare區(qū)ECC
          264. //mainECC值寫入備用區(qū)的頭0~4個地址內
          265. rNFDATA8=ecc&0xff;
          266. rNFDATA8=(ecc>>8)&0xff;
          267. rNFDATA8=(ecc>>16)&0xff;
          268. rNFDATA8=(ecc>>24)&0xff;
          269. ecc_spare_end();//鎖定spare區(qū)ECC
          270. //delay_lhg(100,100);//
          271. ecc=rNFSECC;//spareECC值寫入備用區(qū)的5~6兩個地址內
          272. rNFDATA8=ecc&0xff;
          273. rNFDATA8=(ecc>>8)&0xff;
          274. #endif
          275. bu=bu+2048;//頁增量
          276. addr++;
          277. rNFCMD=NAND_CMD_WRITE_PAGE_2st;
          278. detect_nand_busy();//檢測忙
          279. rNFCMD=NAND_CMD_READ_STATUS;//讀狀態(tài)
          280. if(rNFDATA8&1)
          281. {
          282. #ifdefNAND_DEBUG
          283. Uart_Printf("/r/nnandwritepageerror:pageaddr=0x%d",addr-1);//寫入失敗,以后改進
          284. #endif
          285. control_end();//關控制
          286. nand_mask_bad_block((addr-1)/64);//登記為壞塊
          287. return-1;//寫入錯誤返回-1
          288. }
          289. control_end();//關控制
          290. }
          291. return1;//成功返回1
          292. }
          293. intnand_page_read(U32addr,U8*buffer,U32size)//addr開始頁地址,從每頁00地址開始讀,size為需要讀的字節(jié)數
          294. {
          295. U32i,n,p,temp,ecc;
          296. U8*bu,no;
          297. bu=buffer;
          298. temp=0;
          299. n=size/2048+(((size%2048)==0)?0:1);//計算出要讀的頁數,小于一頁的部分當作一頁
          300. for(i=0;i
          301. {
          302. control_start();//開控制
          303. nand_reset();//復位
          304. #ifdefUSE_ECC
          305. rNFESTAT0=0;//復位錯誤標志位
          306. ecc_main_init();
          307. ecc_main_start();//可以產生main區(qū)ECC
          308. #endif
          309. rNFCMD=NAND_CMD_READ_1st;
          310. rNFADDR=0;
          311. rNFADDR=0;
          312. rNFADDR=addr&0xff;
          313. rNFADDR=(addr>>8)&0xff;
          314. rNFADDR=(addr>>16)&0xff;
          315. rNFCMD=NAND_CMD_READ_2st;
          316. detect_nand_busy();
          317. for(p=0;p<2048;p++)
          318. {
          319. temp=temp+1;
          320. if(temp>size)
          321. {
          322. no=rNFDATA8;//多余的讀出來扔掉
          323. }
          324. else
          325. {
          326. *(bu+p)=rNFDATA8;
          327. }
          328. }
          329. #ifdefUSE_ECC
          330. rNFESTAT0=0;
          331. ecc_main_end();//鎖定main區(qū)ECC
          332. //delay_lhg(100,100);//
          333. ecc_spare_start();//解鎖spare區(qū)ecc
          334. ecc=rNFDATA8;//從flash讀出main區(qū)ECC,四個字節(jié)
          335. no=rNFDATA8;
          336. ecc|=((U32)no)<<8;
          337. no=rNFDATA8;
          338. ecc|=((U32)no)<<16;
          339. no=rNFDATA8;
          340. ecc|=((U32)no)<<24;
          341. rNFMECCD0=((ecc&0xff00)<<8)|(ecc&0xff);//硬件檢驗mainECC
          342. rNFMECCD1=((ecc&0xff000000)>>8)|((ecc&0xff0000)>>16);
          343. ecc_spare_end();//鎖定spare區(qū)ecc
          344. //delay_lhg(100,100);//
          345. ecc=rNFDATA8;//從flash讀出spare區(qū)ECC的值
          346. no=rNFDATA8;
          347. ecc|=((U32)no)<<8;
          348. rNFSECCD=((ecc&0xff00)<<8)|(ecc&0xff);//硬件檢驗spareECC
          349. //delay_lhg(100,100);//延時一會
          350. ecc=rNFESTAT0&0xffffff;//ecc只是臨時用一下錯誤狀態(tài),并非ecc內容
          351. if(ecc!=0)//有錯誤
          352. {
          353. //以后再優(yōu)化
          354. #ifdefNAND_DEBUG
          355. Uart_Printf("/r/nNandecccheckerror...pageaddr=0x%x,NFESTAT0=0x%x",addr,ecc);
          356. #endif
          357. nand_mask_bad_block((addr+i)/64);//登記為壞塊
          358. return-1;
          359. }
          360. #endif
          361. bu=bu+2048;
          362. addr++;
          363. control_end();//關控制
          364. }
          365. return1;
          366. }
          367. intnand_random_read(U32paddr,U32offset,U8*data)//隨機讀數據paddr頁地址,offset頁內偏移地址
          368. {
          369. control_start();//開控制
          370. nand_reset();//復位
          371. rNFCMD=NAND_CMD_READ_1st;
          372. rNFADDR=0;
          373. rNFADDR=0;
          374. rNFADDR=paddr&0xff;
          375. rNFADDR=(paddr>>8)&0xff;
          376. rNFADDR=(paddr>>16)&0xff;
          377. rNFCMD=NAND_CMD_READ_2st;
          378. detect_nand_busy();
          379. rNFCMD=NAND_CMD_RANDOM_READ_1st;
          380. rNFADDR=offset&0xff;//寫入頁內偏移地址
          381. rNFADDR=(offset>>8)&0xff;
          382. rNFCMD=NAND_CMD_RANDOM_READ_2st;
          383. *data=rNFDATA8;
          384. control_end();
          385. return1;
          386. }
          387. intnand_random_write(U32paddr,U32offset,U8data)//隨機寫,paddr頁地址,offset頁內偏移地址
          388. {
          389. control_start();//開控制
          390. nand_reset();//復位
          391. rNFCMD=NAND_CMD_WRITE_PAGE_1st;
          392. rNFADDR=0;
          393. rNFADDR=0;
          394. rNFADDR=paddr&0xff;
          395. rNFADDR=(paddr>>8)&0xff;
          396. rNFADDR=(paddr>>16)&0xff;
          397. rNFCMD=NAND_CMD_RANDOM_WRITE;
          398. rNFADDR=offset&0xff;//寫入頁內偏移地址
          399. rNFADDR=(offset>>8)&0xff;
          400. rNFDATA8=data;
          401. rNFCMD=NAND_CMD_WRITE_PAGE_2st;
          402. detect_nand_busy();//檢測忙
          403. rNFCMD=NAND_CMD_READ_STATUS;//讀狀態(tài)
          404. if(rNFDATA8&1)
          405. {
          406. #ifdefNAND_DEBUG
          407. Uart_Printf("/r/nError:nandrandomwriteerror...paddr=0x%x,offset=0x%x",paddr,offset);
          408. #endif
          409. return-1;//刪除錯誤返回0
          410. }
          411. control_end();
          412. return1;//成功返回1
          413. }
          414. voidnand_test_bad_block(void)//測試壞塊函數,并標記spare區(qū)最后一個地址,如果非0xff則為壞塊
          415. {
          416. U8dest[64*2048];//一個塊的main區(qū)容量
          417. U8src[64*2048];
          418. U32i,k;
          419. #ifdefNAND_DEBUG
          420. Uart_Printf("/r/ntestandmaskbadblockisbegain./r/n");
          421. #endif
          422. //main區(qū)檢測
          423. for(i=0;i<64*2048;i++)
          424. {
          425. dest[i]=0xff;//初始化緩沖區(qū)
          426. src[i]=0;
          427. }
          428. //刪除所有塊
          429. for(i=0;i
          430. {
          431. nand_block_erase(i);
          432. }
          433. for(i=0;i
          434. {
          435. nand_page_write(i*64,src,64*2048);
          436. nand_page_read(i*64,dest,64*2048);//使用了ecc校驗讀出來即可登記壞塊信息
          437. }
          438. for(i=0;i<64*2048;i++)
          439. {
          440. dest[i]=0;//初始化緩沖區(qū)
          441. src[i]=0xff;
          442. }
          443. //刪除所有塊
          444. for(i=0;i
          445. {
          446. nand_block_erase(i);
          447. }
          448. for(i=0;i
          449. {
          450. nand_page_write(i*64,src,64*2048);
          451. nand_page_read(i*64,dest,64*2048);//使用了ecc校驗讀出來即可登記壞塊信息
          452. }
          453. //
          454. //spare區(qū)檢測
          455. for(i=0;i<64;i++)
          456. {
          457. dest[i]=0xff;//初始化緩沖區(qū)
          458. src[i]=0;
          459. }
          460. //刪除所有塊
          461. for(i=0;i
          462. {
          463. nand_block_erase(i);
          464. }
          465. for(i=0;i
          466. {
          467. if(nand_bbi.area[i/64]==1)//如果是壞塊則跳過
          468. continue;
          469. for(k=0;k<64;k++)
          470. {
          471. nand_random_write(i,2048+k,src[k]);
          472. nand_random_read(i,2048+k,&dest[k]);
          473. if(dest[k]!=src[k])//不相等則登記為壞塊
          474. {
          475. nand_mask_bad_block(i/64);
          476. break;
          477. }
          478. }
          479. }
          480. for(i=0;i<64;i++)
          481. {
          482. dest[i]=0x0;//初始化緩沖區(qū)
          483. src[i]=0xff;
          484. }
          485. //刪除所有塊
          486. for(i=0;i
          487. {
          488. nand_block_erase(i);
          489. }
          490. for(i=0;i
          491. {
          492. if(nand_bbi.area[i/64]==1)//如果是壞塊則跳過
          493. continue;
          494. for(k=0;k<64;k++)
          495. {
          496. nand_random_write(i,2048+k,src[k]);
          497. nand_random_read(i,2048+k,&dest[k]);
          498. if(dest[k]!=src[k])//不相等則登記為壞塊
          499. {
          500. nand_mask_bad_block(i/64);
          501. break;
          502. }
          503. }
          504. }
          505. #ifdefNAND_DEBUG
          506. Uart_Printf("/r/ntestandmaskbadblockisover./r/n");
          507. #endif
          508. }
          509. voidnand_flash_init(void)//初始化
          510. {
          511. #ifdefNAND_DEBUG
          512. Uart_Printf("/r/nNANDFLASHinit");//
          513. #endif
          514. //中斷入口地址
          515. pISR_NFCON=(U32)nandINT;
          516. //配置GPIO
          517. rGPGUP|=0x7<<13;//GPG13~15關閉上位
          518. rGPGCON&=~((U32)0x3f<<26);//GPG13~15為輸入
          519. //初始化各寄存器
          520. S3C2440_NFCONF_init();
          521. S3C2440_NFCONT_init();
          522. S3C2440_NFSTAT_init();
          523. S3C2440_NFESTAT0_init();
          524. S3C2440_NFESTAT1_init();
          525. //關于中斷
          526. rINTMSK&=~(0x1<
          527. rINTMOD&=~(0x1<
          528. rSRCPND|=0x1<
          529. rINTPND|=0x1<
          530. //init_nand_bbi();//初始化全局變量
          531. nand_read_id();//讀ID
          532. //nand_test_bad_block();//測試并登記壞塊
          533. }




          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();