کار با ایسی های حافظه (spi flash) در STM32 با littleFS (بخش دوم)

0
246
کار با ایسی های حافظه (spi flash) در STM32 با littleFS (بخش دوم)
کار با ایسی های حافظه (spi flash) در STM32 با littleFS (بخش دوم)

در بخش قبل به معرفی Spi Flash و کاربرد هایش پرداختیم همچنین با راه اندازی و نحوه ارتباط با آن اشنا شدیم همچنین به صورت کوتاه به lfs و مزیت آن نسبت به بقیه fileSystem ها پرداختیم. در این بخش کار با ایسی های حافظه در STM32 با littleFS را آموزش داده و با کانفیگ و راه اندازی آن آشنا می‌شویم.

 

کتابخانه LittleFS

ابتدا کتابخانه littleFS را دانلود کنید، سورس فایل‌ها و هدر آن را به پروژه اضافه کنید.

#include “lfs.h”

کتابخانه LittleFS

  • LFS_YES_TRACE  فعال کردن TRACE برای دیباگ کردن
  • LFS_NO_MALLOC  غیر فعال کردن استفاده از حافظه پویا

 

استراکچرها و بافرهای littleFS

 

lfs_t lfs; 
lfs_file_t file;

static uint8_t lfs_read_cache_buf[256]; 
static uint8_t lfs_prog_cache_buf[256]; 
static uint8_t lfs_lookahead_buf[16]; // 128/8=16

 

آرایه‌ها برای نوشتن و خواندن در فایل‌ها

char WriteBuf[def_num_lfs_ram] = {"Hi,Budy! if you get this Message......Congratulations!You have succeeded!!"};

char ReadBuf[def_num_lfs_ram];

 

ایجاد ارتباط بین توابع spi flash و littleFS

به کمک کد زیر توابعی که برای w25q نوشتیم را به lfs معرفی می‌کنیم.

اگر به جای w25q قصد داشتید از Fhash داخلی میکرو (یا spiFlash دیگری) استفاده کنید، کافی است توابع erase, read, write مربوطه را قرار دهید.

static int user_provided_block_device_read(const struct lfs_config *lfsc, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
{

W25Q_ReadPage((uint8_t *)buffer,(block * lfsc->block_size + off),size);
return LFS_ERR_OK;
}

static int user_provided_block_device_prog(
const struct lfs_config *lfsc, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
{

W25Q_WritePage((uint8_t*)buffer,(block * lfsc->block_size + off),size);
return LFS_ERR_OK;
}

static int user_provided_block_device_erase(const struct lfs_config *lfsc, lfs_block_t block)
{
W25Q_EraseSector4KB(block);
return LFS_ERR_OK;
}
static int user_provided_block_device_sync(const struct lfs_config *lfsc)
{
return LFS_ERR_OK;
}

 

کانفیگ کردن lfs

  •     read_size  (سایز صفحات ایسی) = 256
  •     prog_size (سایز صفحات ایسی) = 256
  •     block_size  (سایز سکتور ایسی(تعداد بایت)) = 4096
  •     block_ count تعداد سکتور موجود در ایسی مثلا w25q16 تعداد بلاک‌ها 512 می‌باشد
  •     cache_size برابر است با read_size
  •     lookahead_size حاصل block_ count /8
const struct lfs_config cfg = {

.context = NULL,

.read = user_provided_block_device_read, 
.prog = user_provided_block_device_prog, 
.erase = user_provided_block_device_erase,
.sync = user_provided_block_device_sync,

.read_size = 256,
.prog_size = 256,
.block_size = 4096,
.block_count = 512,

.cache_size = 256,
.block_cycles = 200,

.lookahead_size = 64,

.read_buffer = lfs_read_cache_buf,
.prog_buffer = lfs_prog_cache_buf,
.lookahead_buffer = lfs_lookahead_buf,

};

 

دیباگ در littleFS

جهت استفاده از قابلیت دیباگ lfs باید تابع printf را به uart میکروکنترلر ریدایرکت کنیم  زیرا trace ها در lfs از printf استفاده می‌کنند.

دیباگ در littleFS

برای اینکار ابتدا uart سخت افزاری را کانفیگ می‌کنیم.

void USART_ini(){ 

CLEAR_BIT(USART1->CR1,USART_CR1_UE );

SET_BIT(RCC->APB2ENR,RCC_APB2ENR_USART1EN );
CLEAR_BIT(USART1->CR1,USART_CR1_OVER8 );

SET_BIT(USART1->CR1,USART_CR1_TE ); 
SET_BIT(USART1->CR1,USART_CR1_RE );

USART1->BRR = 0XD0;

SET_BIT(USART1->CR1,USART_CR1_UE ); 
SET_BIT(USART1->CR1,USART_CR1_TCIE ); 
SET_BIT(USART1->CR1,USART_CR1_RXNEIE );

}

 

برای ارسال یک بایت دیتا از ریجستر tdr استفاده می‌کنیم

نحوه ریدایرکت کردن printf در keil

در پنجره اصلی برنامه Keil، گزینه Project را انتخاب می‌کنیم و از بخش Manage زیر منو Run-Time Environment را کلیک می‌کنیم. در پنجره باز شده از زیرمنوی Compiler پارامتر STDOUT را تغییر می‌دهیم:

نحوه ریدایرکت کردن printf در keil

سپس یک عدد template جدید ایجاد می‌کنیم:

نحوه ریدایرکت کردن printf در keil

کد زیر را در آن قرار میدهیم

int stdout_putchar (int ch) {

USART1->TDR = (uint8_t)ch;
while( !READ_BIT(USART1->ISR,USART_ISR_TC) ){}
SET_BIT(USART1->ICR,USART_ICR_TCCF );
return (ch);

}

اکنون توانسیم ریجستر trd را به printf اتصال دهیم و از قابلیت‌های آن استفاده کنیم.

 

کد تست littleFS

کد زیر را در داخل فایل main قرار دهید، و برنامه را کامپایل کنید.

int err = lfs_mount(&lfs, &cfg);
if (err)
{
lfs_format(&lfs, &cfg);
lfs_mount(&lfs, &cfg);
}


lfs_file_open(&lfs, &file, "my_file", LFS_O_RDWR | LFS_O_CREAT);
lfs_file_read(&lfs, &file, &ReadBuf, sizeof(ReadBuf));
lfs_file_close(&lfs, &file);
lfs_unmount(&lfs);

ReadBuf[0]='*';
printf("%s",ReadBuf);

اکنون در صورتی که تمام کانفیگ‌ها درست باشند، Little پیغام زیر را میدهد.

تست littleFS

نمونه کد برای خواندن فایلی که ایجاد کردیم:

 

lfs_file_open(&lfs, &file, "my_file", LFS_O_RDWR | LFS_O_CREAT);

lfs_file_read(&lfs, &file, &ReadBuf, sizeof(ReadBuf));

lfs_file_close(&lfs, &file);

lfs_unmount(&lfs);

printf("****************your DATA///////////////////-\n");

printf("*\n");printf("*\n");printf("*\n");printf("*\n");printf("*\n");

ReadBuf[0]='*';

printf("%s",ReadBuf);

printf("*\n");printf("*\n");printf("*\n");printf("*\n");printf("*\n");

 

 

به این صورت کار با ایسی های حافظه در STM32 با littleFS را یاد گرفتیم.

 

 

منبع: سیسوگ

مطلب قبلیآموزش STM32 با توابع LL قسمت سی‌ و یکم: راه‌اندازی و استفاده از کارت‌ حافظه SD
مطلب بعدیکار با ایسی های حافظه (spi flash) در STM32 با littleFS (بخش اول)

پاسخ دهید

لطفا نظر خود را وارد کنید!
لطفا نام خود را در اینجا وارد کنید