page256_or_1_byte_write

发表在 SFUD2020-2-14 21:02 [复制链接] 0 64

有个关于page256_or_1_byte_write 这个函数的问题
+ O& Q% ~/ c1 z代码如下- O& D3 K; j$ M" d" D
  1. static sfud_err page256_or_1_byte_write(const sfud_flash *flash, uint32_t addr, size_t size, uint16_t write_gran,
    7 c  T# P/ A! F/ L# h/ H- S
  2.         const uint8_t *data) {: K' H5 \6 E% z8 q& {+ W1 r
  3. 1 F) f$ h6 D$ y% q
  4.     sfud_err result = SFUD_SUCCESS;8 s" H$ Y% Y  K! J4 l
  5.     const sfud_spi *spi = &flash->spi;
    # R: p- c3 E( x7 M/ F3 Z
  6.     static uint8_t cmd_data[5 + SFUD_WRITE_MAX_PAGE_SIZE];
    3 @: f  o3 a8 k. d$ B& m4 `) u
  7.     uint8_t cmd_size;- p1 b- F3 p2 c. N* R
  8.     size_t data_size;
    * z: I8 J9 j$ u7 E  u5 [0 Q

  9. + j) m5 X- a4 p  m2 @, h
  10.     SFUD_ASSERT(flash);) L2 Z1 y0 L" `' ]2 j
  11.     /* only support 1 or 256 */
    ! z. Y5 M' D% i6 C+ Z
  12.     SFUD_ASSERT(write_gran == 1 || write_gran == 256);. n  c& {; d$ s9 I% N. @$ r
  13.     /* must be call this function after initialize OK */
    ! Y5 I/ [1 K& N1 l% @' ~. u- o# f
  14.     SFUD_ASSERT(flash->init_ok);& @/ H* T+ H% `
  15.     /* check the flash address bound */
    * o3 d/ ~9 X+ t/ H& t; J7 v
  16.     if (addr + size > flash->chip.capacity) {
    # o( m. l  |4 i7 M- {( A
  17.         SFUD_INFO("Error: Flash address is out of bound.");
    . }! Y! ]# A/ ~, k; @- {6 V
  18.         return SFUD_ERR_ADDR_OUT_OF_BOUND;
    " ~4 y" o7 B" r' s: k# G
  19.     }
    * f2 b& t7 U7 R% J# A
  20.     /* lock SPI */
    / W( s0 D& S0 V- G( @$ e
  21.     if (spi->lock) {
    * ~* s% T6 e+ a5 T
  22.         spi->lock(spi);7 P; |4 k7 @/ u$ u* [2 [
  23.     }
    4 _/ `% r* F5 j/ _/ ?
  24. 5 ^' v& x( R0 P& Z
  25.     /* loop write operate. write unit is write granularity */9 _6 {0 a- j$ Y7 G' m7 m5 t
  26.     while (size) {
    . K/ D% v, |) \0 f+ v$ _
  27.         /* set the flash write enable */9 r: R1 X6 E: H3 t( r' w( r3 w
  28.         result = set_write_enabled(flash, true);! H# E7 b' Q2 A1 C% J" O
  29.         if (result != SFUD_SUCCESS) {
    . ~- s/ c' [1 h: V' d  o3 m
  30.             goto __exit;! c8 q3 Y& C& e5 O* [3 `  @6 n
  31.         }
    0 A* k4 {. l4 i" n. M5 L8 c, _
  32.         cmd_data[0] = SFUD_CMD_PAGE_PROGRAM;
    ( ?' o7 _" f/ z$ s$ o8 I( e
  33.         make_adress_byte_array(flash, addr, &cmd_data[1]);
    . U2 Z3 e( C6 ]
  34.         cmd_size = flash->addr_in_4_byte ? 5 : 4;
    ( K4 |! a( |5 E. ]# B; ^! d
  35. : E" O" b% X8 A
  36.         /* make write align and calculate next write address */
    * k0 s# W1 X+ s4 e
  37.         SFUD_INFO("addr=%d ",addr);7 Y* {! O& d+ d: W# G; g3 E
  38.         if (addr % write_gran != 0) {
    5 g$ r* ~$ t2 M
  39.             if (size > write_gran - (addr % write_gran)) {
    . a/ y+ J3 r; k
  40.                 data_size = write_gran - (addr % write_gran);
    8 O; W1 F' d" z) r5 b8 }9 B: \
  41.             } else {
    4 l" T" ]! A5 e4 O
  42.                 data_size = size;
    3 A& e& S- t7 R
  43.             }. _: U* N7 \% A3 D' H
  44.         } else {
    ( V3 S2 \3 d3 l. c% Q1 R
  45.             if (size > write_gran) {1 s+ @9 G+ |4 z/ @
  46.                 data_size = write_gran;
    . e, t. |3 z9 N4 Z
  47.             }else {
    , }( v1 r$ W) g; s
  48.                 data_size = size;
    . C1 ]/ U/ v. z$ p( x3 A! d& S
  49.             }* Z0 S2 v2 J7 h; E
  50.         }& ?/ {+ ^  F. i' _' `$ U
  51.         size -= data_size;
    ) h7 B, e& h, ~7 f
  52.         addr += data_size;; M0 R+ t) l) E$ z1 J

  53. . p/ W" {+ Q4 o2 m7 w% S
  54.         memcpy(&cmd_data[cmd_size], data, data_size);6 |, g1 m" L* Z- E" q9 u0 l9 g6 ]
  55.         result = spi->wr(spi, cmd_data, cmd_size + data_size, NULL, 0);  u9 v5 h6 f3 K2 s- }
  56.         if (result != SFUD_SUCCESS) {6 z: g2 v- c* G0 a, M! s
  57.             SFUD_INFO("Error: Flash write SPI communicate error.");
    6 }+ r& r# z1 B4 J/ E
  58.             goto __exit;" n1 ?' C9 G* p9 J8 q1 o/ [. B
  59.         }( _+ P* m1 N: K% _% T: j5 a* i
  60.         result = wait_busy(flash);
    7 d5 I# u* r5 |, h- D# e; l
  61.         if (result != SFUD_SUCCESS) {
    0 k/ H: @* R, P0 a! n7 ?
  62.             goto __exit;
    ' K. p* T/ K$ C1 A+ @3 |
  63.         }
    7 a& Z7 {/ H: K
  64.         data += data_size;
    : L9 K% V5 Y. ?  H3 ]2 m* Y
  65.     }
    3 F* y# I$ ]3 o1 d; u6 k6 P% q
  66. $ Z2 |+ Q: p4 P$ w( b* v
  67. __exit:
    4 v& _5 H8 e+ \  `% X5 i: O
  68.     /* set the flash write disable */9 K% c( Y' X: p  ~$ X: _' e
  69.     set_write_enabled(flash, false);
      e5 m+ H2 n# _# K2 n" l. w
  70.     /* unlock SPI */
    + ^5 w* |% l  V- E: \3 l' ^
  71.     if (spi->unlock) {
    7 D( H+ P4 F1 P: P1 L
  72.         spi->unlock(spi);5 n6 ^4 L. m1 i6 e9 }
  73.     }
    9 N( k) s$ S  a5 q/ n( l0 m
  74. * L1 E* M  S; x6 i; V3 J
  75.     return result;
    " i  A5 G4 ~* u
  76. }  L$ m/ [# u2 K/ s, o
复制代码
最终是调用result = spi->wr(spi, cmd_data, cmd_size + data_size, NULL, 0); 将数据写入flash
& ~" V3 G  v% r/ E$ ]' X在执行之前可以看到data_size的值并不等于入参size,会根据page的大小和地址做改变,flash 每次写入应该写入一个page
+ z5 a( Y0 G& e: V& B1 j9 I那么若地址为page的起始地址,长度小于page,是不是应该先读取一个page的内容,然后在memcpy写入的数据,然后在写入page,
' ^6 e6 a# F, T, b$ n1 C% s8 a/ F若地址不为page的起始地址,那么要考虑写入的长度是否在两个page内。
% T% J- y$ j* I2 K+ b+ @不知道我这样的理解对不对,但是这个函数并没有读取的操作。4 C2 S, ?/ P6 j( d% \
% f5 O$ h4 Q: R) I5 L) S; e0 A
还是说flash可以不以page进行写操作的么?
; a( b3 A. `1 F$ B5 f1 S0 p
6 ~" T% ^+ p9 G4 V- r% h: {1 n4 m% @" h; r2 z! R+ Y% {! Z
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|RT-Thread开发者社区 ( 沪ICP备13014002号-1

有害信息举报电话:021-31165890 手机:18930558079

© 2006-2019 上海睿赛德电子科技有限公司

Powered by RT-Thread

快速回复 返回顶部 返回列表