---
title: "[W7500] mbed Flash Memory 관련 문의"
url: "https://maker.wiznet.io/forum/12363"
markdown_url: "https://maker.wiznet.io/forum/12363/md"
type: "Forum topic"
category: "MCU & Boards"
author: "Gyu Wan Kim"
created: "2017-07-12T06:58:41+09:00"
last_activity: "2017-07-13T10:20:36+09:00"
language: "ko"
views: 1555
replies: 8
source: "WIZnet Makers forum (https://maker.wiznet.io/forum/)"
---

# [W7500] mbed Flash Memory 관련 문의

## Question

Asked by Gyu Wan Kim on 2017-07-12 in MCU & Boards.

W7500 mbed 컴파일러로 개발하고 있는 개발자입니다.

인터넷 접근이 너무 간단해서 많이 놀랐네요~~
지금 저희가 flash memory에 사용자 환경(Setup)값을 저장하고 싶습니다.
Keil 버전용 Firmware에서 DO_IAP 함수를 이용하여 DATA0, DATA1영역에 접근할 수 있구요.
문제는 보드 Reset버튼 재부팅시 플래쉬메모리 영역에 값들이 지워지는걸 확인했습니다.
혹시 플래쉬영역 일부를 저희가 임의로 사용할 수 있는지요?
없다면 칩을 별도로 추가해야 되는지요??
답변 부탁 드리겠습니다.

## Replies

### Reply 1 by Kei, 2017-07-12

Gyu_Wan_Kim:

> Keil 버전용 Firmware에서 DO_IAP 함수를 이용하여 DATA0, DATA1영역에 접근할 수 있구요.
> 문제는 보드 Reset버튼 재부팅시 플래쉬메모리 영역에 값들이 지워지는걸 확인했습니다.

[W7500 flash Link](http://wizwiki.net/wiki/doku.php?id=products:w7500:peripherals:flash)를 확인해보셨나요?
정확한 현상을 파악하기 위해 질문 드리자면, IAP_PROG로 저장을 하셨는데, 리셋시 초기화된다는 말씀이신가요?

Gyu_Wan_Kim:

> 혹시 플래쉬영역 일부를 저희가 임의로 사용할 수 있는지요?

일반적인 Flash이기 때문에, 사용법은 일반적인 내용과 동일합니다.
주로 메모리 관리를 위해 DATA0 과 DATA1만을 저장용으로 이용하시는 것이 좋습니다.

### Reply 2 by Gyu Wan Kim, 2017-07-12 (in reply to reply 1)

Kei:

> W7500 flash Link를 확인해보셨나요?
> 정확한 현상을 파악하기 위해 질문 드리자면, IAP_PROG로 저장을 하셨는데, 리셋시 초기화된다는 말씀이신가요?

넵 맞습니다. IAP_PROG로 저장하였으며 초기 부팅시 저장된 값을 확인하는 소스코드를 추가하여 확인하였습니다.
mbed 에서 Test 중입니다.

### Reply 3 by Kei, 2017-07-12

Gyu_Wan_Kim:

> 넵 맞습니다. IAP_PROG로 저장하였으며 초기 부팅시 저장된 값을 확인하는 소스코드를 추가하여 확인하였습니다.

사용하신 소스코드를 공유해주실 수 있을까요?

### Reply 4 by Gyu Wan Kim, 2017-07-12

```
#include "mbed.h"
#include "EthernetInterface.h"


#define ECHO_SERVER_PORT   15000
//#define ENABLE_DHCP



/********************************************************************************/
//  Define
/********************************************************************************/
#define IAP_ENTRY                                       0x1FFF1001            // Because Thum code
#define IAP_ERAS                                        0x010
#define IAP_ERAS_DAT0                                   (IAP_ERAS + 0)
#define IAP_ERAS_DAT1                                   (IAP_ERAS + 1)
#define IAP_ERAS_SECT                                   (IAP_ERAS + 2)              
#define IAP_ERAS_BLCK                                   (IAP_ERAS + 3)  
#define IAP_ERAS_CHIP                                   (IAP_ERAS + 4)  
#define IAP_ERAS_MASS                                   (IAP_ERAS + 5)  
#define IAP_PROG                                        0x022
#define DAT0_START_ADDR                                 0x0003FE00
#define DAT1_START_ADDR                                 0x0003FF00
#define CODE_TEST_ADDR                                  0x0001FF00
#define BLOCK_SIZE                                      4096
#define SECT_SIZE                                       256


typedef enum 
{ 
    FAILED = 0,
    PASSED = !FAILED
    
} TestStatus;


/********************************************************************************/
// Function Prototype Define
/********************************************************************************/
void Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);
void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size);



////////////////////////////////////////////////////////////////////////////////
//                      Init Global Valiable                                  //
////////////////////////////////////////////////////////////////////////////////
DigitalOut RLED(PC_8);
DigitalOut GLED(PC_9);
DigitalOut BLED(PC_5);
Serial Sensor(PA_13, PA_14);


uint8_t save_buff[SECT_SIZE];


uint8_t gMac_addr[6]    = {0x00, 0x08, 0xDC, 0x00, 0x01, 0x02};
char gIp_addr[]         = {"192.168.0.105"};
char gMask[]            = {"255.255.255.0"};
char gGateway_addr[]    = {"192.168.0.1"};
////////////////////////////////////////////////////////////////////////////////



int main (void)
{
    int nCnt = 0;
    //TestStatus result;
    printf("Wait a second...\r\n");
    
    memset(save_buff, 0x00, SECT_SIZE);
    // Make Init Symbol Flash Write
    save_buff[nCnt++] = 'M';
    save_buff[nCnt++] = 'T';
    save_buff[nCnt++] = 'E';
    save_buff[nCnt++] = 'C';
    
    //DO_IAP(IAP_ERAS_DAT0, DAT0_START_ADDR, 0, 0);
    //DO_IAP(IAP_PROG, DAT0_START_ADDR, save_buff, SECT_SIZE);
    Buffercmp((uint8_t*)&save_buff[0], ((uint8_t *)(DAT0_START_ADDR)), SECT_SIZE);
    printf("%s\r\n", save_buff);
                    
    EthernetInterface eth;
    
 #ifdef ENABLE_DHCP
    printf("DHCP IP Mode\r\n");
    eth.init(gMac_addr); //Use DHCP
    eth.connect();
    printf("Server IP Address is %s\r\n", eth.getIPAddress());
 #else
    printf("Static IP Mode\r\n");
    eth.init(gMac_addr, gIp_addr, gMask, gGateway_addr);    
 #endif/* ENABLE_DHCP */
    
    TCPSocketServer server;
    server.bind(ECHO_SERVER_PORT);
    server.listen();
    
    RLED = 0;
    GLED = 1;
    BLED = 0;
    wait(0.2);
        
    while (true) 
    {
        printf("Wait for new connection...\r\n");
        TCPSocketConnection client;
        server.accept(client);
        client.set_blocking(false, 15000); // Timeout after (1.5)s
        
        printf("Connection from: %s\r\n", client.get_address());
        char buffer[256];
        
        RLED = 0;
        GLED = 0;
        BLED = 1;
        
        while (true) {
            
            int n = client.receive(buffer, sizeof(buffer));
            if (n <= 0) break;
            
            // print received message to terminal
            buffer[n] = '\0';
            printf("Received message from Client :'%s'\r\n",buffer);
            
            // reverse the message
            char temp;
            for(int f = 0, l = n-1; f<l; f++,l--){
                temp = buffer[f];
                buffer[f] = buffer[l];
                buffer[l] = temp;
                }
            
            // print reversed message to terminal
            printf("Sending message to Client: '%s'\r\n",buffer);
            
            // Echo received message back to client
            client.send_all(buffer, n);
            if (n <= 0) break;
        }
        client.close();
        RLED = 0;
        GLED = 1;
        BLED = 0;
    }
}



/********************************************************************************/
// This is DO_IAP.
/********************************************************************************/
void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size)
{
    // Disable interrupts before calling IAP
    __disable_irq();
    
    // Call IAP Function
    ((void(*)(uint32_t,uint32_t,uint8_t*,uint32_t))IAP_ENTRY)( id,dst_addr,src_addr,size);

    // Enable interrupts
    __enable_irq();
}



/********************************************************************************/
// This is Buffercmp.
/********************************************************************************/
void Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
    while(BufferLength--)
    {   
        (*pBuffer1) = (*pBuffer2);
    
        pBuffer1++;
        pBuffer2++;
    }
}
```

### Reply 5 by Kei, 2017-07-13

코드상에서는 DO_IAP를 사용하지 않으신데,
이전 코드에서 사용하시고, 현재 코드로 테스트하신 건가요?

일단 아래 코드를 한번 참조해 보시길 바랍니다.

```
#include "mbed.h"

#define IAP_ENTRY           0x1FFF1001            
#define IAP_ERAS            0x010
#define IAP_ERAS_DAT0       (IAP_ERAS + 0)
#define IAP_ERAS_SECT       (IAP_ERAS + 2)              
#define IAP_ERAS_BLCK       (IAP_ERAS + 3)  
#define IAP_ERAS_CHIP       (IAP_ERAS + 4)  
#define IAP_ERAS_MASS       (IAP_ERAS + 5)  
#define IAP_PROG            0x022
#define DAT0_START_ADDR     0x0003FE00
#define BLOCK_SIZE          4096
#define SECT_SIZE           256


struct data{
    char something1[5];
    int something2;
} test;

void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size);

Serial pc(USBTX,USBRX);

int main()
{ 
    uint8_t save_buff[BLOCK_SIZE];

    pc.baud(115200);

    /* Set dummy data */
    strcpy(test.something1, "abcd");
    test.something2 = 1000;
    memcpy(save_buff, (const char*)&test, sizeof(data) );
    
    /* Load stored data */
    memcpy(save_buff,(uint8_t *)(DAT0_START_ADDR),sizeof(data));
    data *p = (data*)save_buff;
    pc.printf("Something1: %s, Something2: %d \r\n",p->something1, p->something2);
    
    /* Store different data */
    strcpy(test.something1 ,"hello");
    test.something2 = 20000;
    memcpy(save_buff, (const char*)&test, sizeof(data) );
    
    DO_IAP(IAP_ERAS_DAT0,0,0,0);
    DO_IAP(IAP_PROG,DAT0_START_ADDR,save_buff,SECT_SIZE);
}

void DO_IAP( uint32_t id, uint32_t dst_addr, uint8_t* src_addr, uint32_t size)
{
    uint32_t temp_interrupt;

    // Backup Interrupt Set Pending Register
    temp_interrupt = (NVIC->ISPR[0]);
    (NVIC->ISPR[0]) = (uint32_t)0xFFFFFFFF;
    
    // Call IAP Function
    ((void(*)(uint32_t,uint32_t,uint8_t*,uint32_t))IAP_ENTRY)( id,dst_addr,src_addr,size);

    // Restore Interrupt Set Pending Register
    (NVIC->ISPR[0]) = temp_interrupt;
}
```

### Reply 6 by Gyu Wan Kim, 2017-07-13

제가 보내준 소스 DO_IAP에서 __disable_irq(); / __enable_irq(); Keil에서만 해당되는
코드인가 보군요!! Error 안나길레 ~~!!

보내주신 DO_IAP함수를 사용하니 잘 되는걸 확인하였습니다.
답변 고맙습니다.

아 혹시 mbed 컴파일 환경에서 Timer Interrupt를 구현할 수 있는 소스가 있으시다면
공유해주시면 고맙겠습니다.
Keil 환경으로 Code를 꾸미고 있는데 mbed환경이 너무 좋아서 위 Timer Interrupt 소스만
있다면 계속 mbed 컴파일로 진행해도 될거 같아서 입니다.
그럼 부탁 드립니다.

### Reply 7 by Kei, 2017-07-13

Gyu_Wan_Kim:

> 아 혹시 mbed 컴파일 환경에서 Timer Interrupt를 구현할 수 있는 소스가 있으시다면

W7500에 대한 mbed용 Timer Interrupt 예제는 보유하고 있지 않습니다.
우선, mbed의 기본적인 룰에 따라 포팅 되어 있는 것이기 때문에, mbed의 사용법을 따라서 코드 작성하시면 될 것 같습니다.
마찬가지로, mbed 내에서 검색을 통해 유사한 소스코드를 활용하시는것도 하나의 방법이 되겠습니다.

간단하게 찾아본 결과, [mbed Timers and interrupts](https://developer.mbed.org/media/uploads/robt/mbed_course_notes_-_timers_and_interrupts.pdf)를 참조하시면 도움이 되시리라 판단됩니다.

### Reply 8 by Gyu Wan Kim, 2017-07-13

넵 고맙습니다. 참고하겠습니다.
그럼 수고하세요~

---

Source: https://maker.wiznet.io/forum/12363
