๐ English Abstract
This article explores technical strategies for recovering from metadata corruption and optimizing wear leveling in LittleFS running on STM32 QSPI NOR flash memory during sudden power-off (SPO) events. It covers the root causes of QSPI write failures, LittleFS metadata pair mechanics, and HAL-level driver optimizations. Embedded software engineers will learn how to fine-tune LittleFS parameters and low-level flash drivers to guarantee high data integrity and extend device lifespan in industrial IoT environments.
์๋ฒ ๋๋ ์์คํ (Embedded System) ํ๊ฒฝ์์ ๊ณ ์ฑ๋ฅ ๋๋ฐ์ด์ค ์ ์ด๋ฅผ ์ํด STM32 ๋ง์ดํฌ๋ก์ปจํธ๋กค๋ฌ์ ์ฟผ๋ SPI(QSPI, Quad Serial Peripheral Interface) NOR ํ๋์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์กฐํฉํ๋ ์ค๊ณ๋ ๋งค์ฐ ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉ๋ฉ๋๋ค. ๋ฐ์ดํฐ ๋ณด์์ฑ๊ณผ ๋ฌด๊ฒฐ์ฑ์ด ํต์ฌ์ธ IoT ๋ฐ ์ฐ์ ์ฉ ๊ธฐ๊ธฐ์์๋ ์ ์ ๊ณต๊ธ์ด ๋ถ์์ ์ค๋จ๋๋ ๋๋ฐ ์ ์ ์ฐจ๋จ(SPO, Sudden Power Off) ์ํฉ์์๋ ํ์ผ ์์คํ ์ด ํ์๋์ง ์๊ณ ๋ณต๊ตฌ๋๋ ์ฑ๋ฅ์ด ํ์์ ์ผ๋ก ์๊ตฌ๋ฉ๋๋ค.
์ด๋ฌํ ์๊ตฌ์ฌํญ์ ์ถฉ์กฑํ๊ธฐ ์ํด ์ ์ ๋๋น ๋ด๊ตฌ์ฑ(Power-loss Resilience)๊ณผ ์ ์ RAM ์๋น๋์ ์๋ํ๋ LittleFS ํ์ผ ์์คํ ์ด ๋ง์ด ์ฑํ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ค์ ํ์ฅ์์ STM32์ QSPI ๋๋ผ์ด๋ฒ ๋ ์ด์ด์ LittleFS๋ฅผ ๊ฒฐํฉํ์ฌ ์ฅ์๊ฐ ์ด์ฉํ๋ค ๋ณด๋ฉด, ํน์ ์ฃ์ง ์ผ์ด์ค(Edge Cases)์์ ๋ฉํ๋ฐ์ดํฐ ๋ธ๋ก(Metadata Block)์ด ์์๋์ด ๋ง์ดํธ ์คํจ(Mount Failure)๊ฐ ๋ฐ์ํ๊ฑฐ๋, ํน์ ํ๋์ ๋ธ๋ก์ ์ฐ๊ธฐ ์์ ์ด ์ง์ค๋์ด ์๋ช ์ด ๊ธ๊ฒฉํ ๋จ์ถ๋๋ ๋ฌธ์ ๊ฐ ๋ณด๊ณ ๋๊ณค ํฉ๋๋ค.
๋ณธ ํฌ์คํ ์์๋ STM32 ๋ง์ดํฌ๋ก์ปจํธ๋กค๋ฌ์ QSPI NOR ํ๋์ ๋ ์ด์ด ์์์ LittleFS ์ด์ฉ ์ค ๋ฐ์ํ๋ ๋ฉํ๋ฐ์ดํฐ ์์ ์์ธ์ ์ฌ์ธต ๋ถ์ํ๊ณ , ์ด๋ฅผ ์๋ฒฝํ ๋ณต๊ตฌํจ๊ณผ ๋์์ ์จ์ด ๋ ๋ฒจ๋ง(Wear Leveling) ์ฑ๋ฅ์ ์ต์ ํํ๋ ํ๋์จ์ด/์ํํธ์จ์ด ํตํฉ ํธ๋ฌ๋ธ์ํ ๊ฐ์ด๋๋ฅผ ๊ณต์ ํฉ๋๋ค.
1. LittleFS ๋ฉํ๋ฐ์ดํฐ ๊ตฌ์กฐ์ QSPI NOR ํ๋์์ ๋งค์ปค๋์ฆ ๋ถ์
LittleFS๊ฐ ๋๋ฐ ์ ์ ์ฐจ๋จ์ ๊ฐํ ์ด์ ๋ ๊ธฐ๋ณธ์ ์ผ๋ก CoW(Copy-on-Write) ๋ฐฉ์๊ณผ ๋ฉํ๋ฐ์ดํฐ ํ์ด(Metadata Pair) ๊ตฌ์กฐ๋ฅผ ์ฑํํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ํ์ง๋ง ํ์ ๋ฌผ๋ฆฌ ๋ ์ด์ด์ธ QSPI NOR ํ๋์ ๋ฉ๋ชจ๋ฆฌ์ ํน์ฑ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ดํดํ์ง ๋ชปํ๋ฉด ์ ์ด ํ์ด๋ฐ์์ ๊ฒฐํจ์ด ์๊ธธ ์ ์์ต๋๋ค.
๊ฐ. ๋ฉํ๋ฐ์ดํฐ ํ์ด(Metadata Pair) ๋์ ๋ฐฉ์
LittleFS์ ๋ชจ๋ ๋๋ ํฐ๋ฆฌ์ ์์คํ ์ํ ์ ๋ณด๋ ๋ ๊ฐ์ ๋ธ๋ก์ผ๋ก ๊ตฌ์ฑ๋ ๋ฉํ๋ฐ์ดํฐ ํ์ด์ ์ ์ฅ๋ฉ๋๋ค. ์๋ก์ด ๋ฐ์ดํฐ ์ ๋ฐ์ดํธ๊ฐ ๋ฐ์ํ๋ฉด ๊ธฐ์กด ๋ธ๋ก์ ๋ฎ์ด์ฐ๋ ๋์ , ๋น ๋ธ๋ก์ ์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ณ ๋ฆฌ๋น์ ํฌ์ธํฐ(Revision Pointer)์ ์ฒดํฌ์ฌ(CRC32)์ ์ ๋ฐ์ดํธํฉ๋๋ค. ์ ๋ฐ์ดํธ๊ฐ ์๋ฃ๋ ํ ์ด์ ๋ธ๋ก์ ์ญ์ (Erase)ํ๋ ์ ๊ธฐ์ ์ธ ์์๋ฅผ ๊ฑฐ์นฉ๋๋ค.
๋. QSPI NOR ํ๋์์ ๋ฌผ๋ฆฌ์ ํ๊ณ
NOR ํ๋์๋ ๋นํธ ๋จ์์ ์ฝ๊ธฐ๊ฐ ๊ฐ๋ฅํ์ง๋ง ์ฐ๊ธฐ(Program)๋ ๊ธฐ๋ณธ ๋จ์(๋ณดํต 256 Byte Page), ์ง์ฐ๊ธฐ(Erase)๋ ๋ ํฐ ๋จ์(๋ณดํต 4KB Sector ๋๋ 64KB Block)๋ก ์ํ๋ฉ๋๋ค. ํนํ Erase ์์ ๋์ค ์ ์์ด ์ฐจ๋จ๋๋ฉด ํ๋์ ์ ์ ์ ํ ์ํ๊ฐ ๋ถํ์คํ ๋ฉํ์คํ ์ด๋ธ(Metastable) ์ํ๋ก ๋จ์, ์ดํ ์ฝ๊ธฐ ์ ๋นํธ ์๋ฌ(Bit Flip)๋ฅผ ์ ๋ฐํฉ๋๋ค.
STM32์ QSPI ์ปจํธ๋กค๋ฌ๊ฐ Direct Mode ๋๋ Memory-Mapped Mode๋ก ์๋ํ๋ ๊ณผ์ ์์, ๋ฒํผ๋ง๋ ๋ฐ์ดํฐ๊ฐ ํ๋์์ ์์ ํ ๊ธฐ๋ก๋๊ธฐ ์ ์ ํ๋์จ์ด ์ ์์ด ํ๊ฐ ์ ์ ์๊ณ์น(Power-down Threshold) ๋ฐ์ผ๋ก ๋จ์ด์ง๋ฉด ๋ฉํ๋ฐ์ดํฐ ํค๋๋ ์ ์์ฒ๋ผ ๋ณด์ด๋ ๋ด์ฉ๋ฌผ์ด ์ ํจํ์ง ์์ ์ฌ๊ฐํ ์ํ์ ๋น ์ง ์ ์์ต๋๋ค.
2. ๋๋ฐ ์ ์ ์ฐจ๋จ(SPO) ์ ๋ฉํ๋ฐ์ดํฐ ์์ ์์ธ ๋ถ์
LittleFS ํ๊ฒฝ์์ `lfs_mount()` ํจ์๊ฐ `LFS_ERR_CORRUPT` ์ค๋ฅ๋ฅผ ๋ฐํํ๊ฒ ๋ง๋๋ ๊ทผ๋ณธ ์์ธ์ ๋จ์ํ ํ์ผ ์์คํ ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ๋ผ๊ธฐ๋ณด๋ค MCU-ํ๋์ ๋ฉ๋ชจ๋ฆฌ ์ธํฐํ์ด์ค ๊ฐ ํ์ด๋ฐ ๋ถ์ผ์น์์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋๋ถ๋ถ์ ๋๋ค.
- QSPI FIFO ๋ฒํผ ๋ฐ ํ๋์ ๋ด๋ถ Program Time ์ง์ฐ: NOR ํ๋์์ Page Program ๋์ ์๊ฐ(tPP)์ ์คํ์ ๋ณดํต 0.2ms~3ms๊ฐ ์์๋ฉ๋๋ค. MCU๋ ์ด๋ฏธ ๋ฐ์ดํฐ ์ ์ก ๋ช ๋ น์ ๋ง์ณค์ผ๋, ํ๋์ ๋ด๋ถ ํ์จ์ด๊ฐ ๋ฌผ๋ฆฌ ์ ์ ๊ธฐ๋ก์ ์งํํ๋ ์ค๊ฐ์ ์ ์์ด ์์ค๋๋ฉด ํค๋๋ง ํ์๋๊ฑฐ๋ ์ฒดํฌ์ฌ ๋ฏธ์ค๋งค์น๊ฐ ๋ฐ์ํฉ๋๋ค.
- WIP(Write In Progress) ๋นํธ ์ฒดํฌ ๋ฏธํก: STM32 HAL ๋๋ผ์ด๋ฒ์ QSPI ์ ์ก ์๋ฃ ์ฝ๋ฐฑ ์ดํ, ํ๋์ ๋ฉ๋ชจ๋ฆฌ์ Status Register-1 ๋ด WIP ๋นํธ๊ฐ 0(Ready)์ด ๋ ๋๊น์ง ์๋ฒฝํ๊ฒ ํด๋ง(Polling)ํ์ง ์๊ณ ๋ค์ ๋ฃจํด์ผ๋ก ๋์ด๊ฐ๋ฉด ์ ์ ์ฐจ๋จ ์ ์ง์ ์ฐ๊ธฐ ์์ ์ด ์ค๊ฐ์ ๋๊ธฐ๊ฒ ๋ฉ๋๋ค.
- Lookahead Buffer ๋ถ์ผ์น: LittleFS๋ ๋ธ๋ก ํ ๋น ์ํ๋ฅผ ๋น ๋ฅด๊ฒ ํ์ ํ๊ธฐ ์ํด RAM ๋ด๋ถ์ Lookahead Buffer๋ฅผ ์ ์งํฉ๋๋ค. RAM ์์ ๋นํธ๋งต ์ํ์ ๋ฌผ๋ฆฌ ํ๋์ ๋ฉ๋ชจ๋ฆฌ์ ์ค์ ์ง์์ง ์ํ(Erased State)๊ฐ ์ผ์นํ์ง ์๋ ์๊ฐ ์ ์์ด ๊บผ์ง๋ฉด, ์ฌ๋ถํ ์ ๋ฉํ๋ฐ์ดํฐ ๋ธ๋ก ๊ฐ ์ฒด์ธ ํฌ์ธํฐ(Chain Pointer)๊ฐ ์ ์ค๋๋ ํ์์ด ์ ๋ฐ๋ฉ๋๋ค.
3. ๋ฉํ๋ฐ์ดํฐ ์์ ๋ณต๊ตฌ ํธ๋ฌ๋ธ์ํ ๊ธฐ๋ฒ
๋ฉํ๋ฐ์ดํฐ ์์์ผ๋ก ์ธํ์ฌ ์์คํ ์ด ๋ถํ ๋ถ๋ฅ ์ํ์ ๋น ์ง๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ์ํํธ์จ์ด ๋ ์ด์ด์ ํ๋์จ์ด ๋๋ผ์ด๋ฒ ๋ ์ด์ด ์์ชฝ์์ ์ด์ค ๋ณต๊ตฌ ์์คํ ์ ๊ตฌํํด์ผ ํฉ๋๋ค.
๊ฐ. ํ๋์จ์ด ํ์ด๋ฐ ๋ฐ QSPI Polling ๋ณด์
์ฐ๊ธฐ ๋ฐ ์ง์ฐ๊ธฐ ์์ ์งํ ํ๋์ ์ํ๋ฅผ ๋๊ธฐ์์ผ๋ก ๊ฒ์ฆํ๋ `QSPI_AutoPolling` ๋ฃจํด์ ํ์์ ์ผ๋ก ํฌํจํด์ผ ํฉ๋๋ค. ์๋๋ STM32 HAL ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ธฐ์ค ํ์ค ์ฒ๋ฆฌ ์์์ ๋๋ค.
/* QSPI NOR Flash Write In Progress(WIP) Polling function */
HAL_StatusTypeDef QSPI_WaitForReady(QSPI_HandleTypeDef *hqspi, uint32_t Timeout) {
QSPI_CommandTypeDef s_command = {0};
QSPI_AutoPollingTypeDef s_config = {0};
s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;
s_command.Instruction = READ_STATUS_REG1_CMD; // 0x05
s_command.DataMode = QSPI_DATA_1_LINE;
s_command.AddressMode = QSPI_ADDRESS_NONE;
s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE;
s_command.DummyCycles = 0;
s_config.Match = 0x00; // Bit 0 (WIP) must be 0
s_config.Mask = 0x01; // Read Status Register Bit 0
s_config.MatchMode = QSPI_MATCH_MODE_AND;
s_config.StatusBytesSize = 1;
s_config.Interval = 0x10;
s_config.AutomaticStop = QSPI_AUTOMATIC_STOP_ENABLE;
return HAL_QSPI_AutoPolling(hqspi, &s_command, &s_config, Timeout);
}
๋. LittleFS mount ์คํจ ์ ์๋ ๋กค๋ฐฑ ๋ฐ ๋ณต๊ตฌ ๋งค์ปค๋์ฆ
`lfs_mount()`๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ ๊ณง๋ฐ๋ก ์ ์ฒด ํฌ๋งท(`lfs_format()`)์ ์ํํ๋ฉด ๊ธฐ์กด ์ค์ ๋ก๊ทธ ๋ฐ ํ๊ฒฝ์ค์ ์ด ๋ชจ๋ ๋ ์๊ฐ๋๋ค. ๋ฐ๋ผ์ ๋จ๊ณ๋ณ ๋ณต๊ตฌ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํด์ผ ํฉ๋๋ค.
- 1๋จ๊ณ: `lfs_mount()` ์๋. ์คํจ ์ `LFS_ERR_CORRUPT` ๊ฐ์ง.
- 2๋จ๊ณ: ์ ์์ค(Low-level) Flash Read๋ฅผ ํตํด ๋ฉํ๋ฐ์ดํฐ ํ์ด Block 0๊ณผ Block 1์ CRC32๋ฅผ ์๋ ๊ฒ์ฆ.
- 3๋จ๊ณ: ์์๋ ๋ฉํ๋ฐ์ดํฐ ๋ธ๋ก์ ๊ฒฉ๋ฆฌ(Bad Block Marking)ํ๊ณ , ์ ํจํ ๋ฆฌ๋น์ ์ ๊ฐ์ง ๋ค๋ฅธ ๋ธ๋ก์ผ๋ก ํธ๋ ์ด์ฑํ์ฌ ํฌ์ธํฐ ๊ฐ์ ๋ณต์ ์๋.
- 4๋จ๊ณ: ์ํํธ์จ์ด ๋ณต๊ตฌ ๋ถ๊ฐ ํ์ ์, ํน์ ๋ฐ์ดํฐ ๊ตฌ์ญ๋ง ๋ฐฑ์ (RAM ์์ ๋ณต์ฌ) ํ ์์คํ ์ค์ ์์ญ์ ์ ์ธํ ๋๋จธ์ง ์นํฐ๋ง ๋ถ๋ถ ๋ฆฌ์ .
4. ์จ์ด ๋ ๋ฒจ๋ง(Wear Leveling) ๋ฐ ์ฑ๋ฅ ์ต์ ํ
LittleFS๋ ๋์ ์จ์ด ๋ ๋ฒจ๋ง(Dynamic Wear Leveling) ์๊ณ ๋ฆฌ์ฆ์ ๊ธฐ๋ณธ ์ ๊ณตํ์ง๋ง, ๋ฌผ๋ฆฌ NOR ํ๋์์ ๋ธ๋ก ํฌ๊ธฐ ๋ฐ `block_cycles` ์ค์ ๊ฐ์ด ์ต์ ํ๋์ง ์์ ๊ฒฝ์ฐ ํน์ ์นํฐ์ Endurance(์ฐ๊ธฐ ์ ํ ํ์, ๋ณดํต 10๋ง ํ)๊ฐ ๋น ๋ฅด๊ฒ ์๋ชจ๋ฉ๋๋ค.
๊ฐ. `struct lfs_config` ํต์ฌ ํ๋ผ๋ฏธํฐ ํ๋
STM32 QSPI NOR ํ๋์(์: W25Q128JW, MX25R6435F) ํ๊ฒฝ์์ ์ต์์ ์ฐ๊ธฐ ๋ด๊ตฌ์ฑ๊ณผ ์๋๋ฅผ ํ๋ณดํ๊ธฐ ์ํ ์ค์ ๊ธฐ์ค์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
| ํ๋ผ๋ฏธํฐ ํญ๋ชฉ | ๊ถ์ฅ ์ค์ ๊ฐ | ๊ธฐ์ ์ ๊ทผ๊ฑฐ ๋ฐ ํจ๊ณผ |
|---|---|---|
| read_size | 16 ~ 256 Byte | QSPI FIFO ๋ฐ DMA ๋ฒํผ ํฌ๊ธฐ์ ๋ง์ถ์ด ์ ๋ ฌ. ์ฝ๊ธฐ ์ค๋ฒํค๋ ์ต์ํ. |
| prog_size | 256 Byte | NOR ํ๋์์ ๋ฌผ๋ฆฌ์ Page Program ํฌ๊ธฐ์ 1:1 ์ ๋ ฌํ์ฌ ์ฐ๊ธฐ ํจ์จ ์ฆ๋. |
| block_size | 4096 Byte (4KB) | ํ๋์์ ์ต์ ์ญ์ ๋จ์์ธ Sector Erase ๋จ์์ ์์ ํ ์ผ์น์ํด. |
| block_cycles | 100 ~ 500 | ํต์ฌ ๊ฐ: ๋ฉํ๋ฐ์ดํฐ ๋ง์ด๊ทธ๋ ์ด์ ์ฃผ๊ธฐ. ๊ฐ์ด ์์์๋ก ์จ์ด ๋ ๋ฒจ๋ง์ ๊ณ ๋ฅด๊ฒ ๋ถ์ฐ๋๋ ์ง์ฐ๊ธฐ ํ์๊ฐ ์ฆ๊ฐํจ. 100~500 ์ฌ์ด๊ฐ ๊ฐ์ฅ ์ด์์ ์. |
| lookahead_size | 64 ~ 128 (Bit ๋จ์) | RAM ์๋น๋ ์กฐ์ ๋ฐ ๋น ๋ธ๋ก ์ค์บ ํ์ ์๋ ์ต์ ํ (8๋ฐ์ดํธ ๋จ์ ์ ๋ ฌ ํ์). |
๋. BVD(Brown-Out Reset) ๋ฐ ์ ์ ๋ ฅ ๊ฐ์ง ์ฐ๋
์ํํธ์จ์ด์ ๋ณต๊ตฌ ์ ๋ต๊ณผ ๋๋ถ์ด ์ ์ ํ๊ฐ์ ํ๋์จ์ด์ ์ผ๋ก ์ฆ๊ฐ ๊ฐ์งํ๋ BOR(Brown-Out Reset) ๊ธฐ๋ฅ ์ค์ ์ด ๋ณํ๋์ด์ผ ํฉ๋๋ค. STM32์ Option Byte ์ค์ ์ ํตํด BOR Level์ 2.7V ์ด์์ผ๋ก ์ํฅ ์กฐ์ ํ๋ฉด, VDD ์ ์์ด ๋ค์ด๋ ๋ QSPI ์ธํฐํ์ด์ค์ ์ฐ๊ธฐ ์์ ์ด ๋ฌด์์๋ก ๊ณ์ ์งํ๋๋ ํ์์ ํ๋์จ์ด ์ฐจ์์์ ๋ฌด์กฐ๊ฑด ์ค๋จ์ํต๋๋ค.
๊ฒฐ๋ก : ์์คํ ์์ ์ฑ ๊ฒ์ฆ์ ์ํ ๊ถ์ฅ ์ฌํญ
STM32์ QSPI NOR ํ๋์ ์กฐํฉ์์ LittleFS ํ์ผ ์์คํ ์ ๋งค์ฐ ๋์ ์ ๋ขฐ์ฑ์ผ๋ก ์ด์ฉํ๊ธฐ ์ํด์๋ ์ํํธ์จ์ด, ํ์จ์ด ๋๋ผ์ด๋ฒ, ํ๋์จ์ด ์ ์ ๋ชจ๋ํฐ๋ง ์ผ๋ฐ์๊ฐ ์๋ฒฝํ๊ฒ ๋ง๋ฌผ๋ ค์ผ ํฉ๋๋ค.
์์ฐ ๊ฒ์ฆ ๋จ๊ณ์์๋ ๋ค์๊ณผ ๊ฐ์ ์ค๋ฌด ํ ์คํ ๊ธฐ๋ฒ์ ํ์์ ์ผ๋ก ์ ์ฉํด์ผ ํฉ๋๋ค:
- Power-Cut Injection Test: QSPI Page Program ๋ฐ Sector Erase ์ํ ์ค Relay ๋ชจ๋์ ์ด์ฉํ์ฌ 1,000ํ ์ด์์ ๋ฌด์์ ์ ์ ์ฐจ๋จ ํ ์คํธ ์งํ ํ Mount ๋ฐ Integrity Check ๊ฒ์ฆ.
- Endurance Burn-in Test: `block_cycles` ํ๋ผ๋ฏธํฐ๊ฐ ์ ์ฉ๋ ์ํ์์ ๊ฐ์์ผ๋ก 10๋ ์น ์ฐ๊ธฐ/์ง์ฐ๊ธฐ ์๋๋ฆฌ์ค๋ฅผ ๊ณ ์ ์ํํ์ฌ ํน์ ๋ธ๋ก์ ํธ์ค ์ฐ๊ธฐ๊ฐ ์๋์ง ๋ชจ๋ํฐ๋ง.
๋ณธ ๊ฐ์ด๋์์ ๋ค๋ฃฌ QSPI AutoPolling ์ง์ฐ ์ฒ๋ฆฌ, `lfs_config` ๋งค๊ฐ๋ณ์์ ๋ฌผ๋ฆฌ ์นํฐ ํฌ๊ธฐ ์ ๋ ฌ, BOR ํ๋์จ์ด ์ฐจ๋จ ์ ๋ต์ ์ ์ฉํ๋ค๋ฉด, ๊ทนํ์ ์ฐ์ ํ์ฅ ํ๊ฒฝ์์๋ ๋๋ฐ ์ ์ ์ฐจ๋จ์ผ๋ก ์ธํ ํ์ผ ์์คํ ์์ ์ฌ๊ณ ๋ฅผ ์๋ฒฝํ๊ฒ ์๋ฐฉํ ์ ์์ ๊ฒ์ ๋๋ค.