Files
banban/ql-application/threadx/interface/fs/example_nand_flash.c

502 lines
14 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @file example_nand_flash.c
* @author august.yang
* @version V1.0.0
* @date 2020/10/13
******************************************************************************
*/
#include <stdio.h>
#include "ql_fs.h"
#include "ql_application.h"
#include "ql_rtos.h"
//#include "ql_spi_nor.h"
enum{
QL_SPI_DEV0 = 0,
QL_SPI_DEV2 = 2
};
enum{
QL_PIN_16_19 ,
QL_PIN_33_36 ,
QL_PIN_12_15
};
enum{
SPI_CLOCK_13M = 0x0,
SPI_CLOCK_26M = 0x1,
SPI_CLOCK_52M = 0x2,
};
typedef struct file {
unsigned int cnt;
unsigned char buf[64];
} file_contex;
static void list_dir(const char *path)
{
FILE_ID dp = NULL;
NandFs_info info = {0};
int ret;
dp = ql_nand_opendir(path);
if(dp == NULL)
{
printf("[FS] *** dir open fail: %s ***\r\n", path);
return;
}
printf("[FS] dir opened: %s\r\n", path);
printf("[FS] ----- start dir list -----\r\n");
printf("[FS] type\tsize\tname\r\n");
while(1)
{
ret = ql_nand_readddir(dp, &info);
if(ret < 0)
{
printf("[FS] *** dir read fail: %s ***\r\n", path);
break;
}
else if(ret == 0)
{
printf("[FS] ----- end of dir list -----\r\n");
break;
}
else
{
printf("[FS] %-4d\t%-4d\t%s\r\n", info.type, info.size, info.name);
}
}
if(dp)
{
ql_nand_closedir(dp);
printf("[FS] dir closed: %s\r\n", path);
}
}
unsigned int crc32_test(const unsigned char *buf, int length)
{
unsigned int crc = 0xFFFFFFFF;
for (int i = 0; i < length; i++)
{
crc ^= buf[i];
for (int j = 0; j < 8; j++)
{
if (crc & 1)
crc = (crc >> 1) ^ 0xEDB88320;
else
crc >>= 1;
}
}
return crc ^ 0xFFFFFFFF;
}
#define TEST_ADDR 0x00000000
#define TEST_SIZE 4096 /* must equal page/block multiple */
#define TEST_PATTERN 0x5A
/*����4�ֽڶ���*/
__attribute__((aligned(32))) static uint8_t g_write_buf[4096];
static unsigned char g_read_buf[4096];
void nand_flash_api_test_task(void *argv)
{
int ret = 0,loop_count = 0;
unsigned int test_addr = 0, test_block_num = 0;
ql_spi_nand_flash_hndl_t hndl = NULL;
ql_spi_nand_flash_hw_info_t info = {0};
ql_rtos_task_sleep_s(10);
printf("nand flash api test task start\r\n");
for (unsigned int i = 0; i < sizeof(g_write_buf); i++) {
g_write_buf[i] = (unsigned char)(i & 0xFF); // 0,1,2,...,255,0,1,...
}
while (1)
{
int ret;
/* 1. �� NAND */
ret = ql_spi_nand_flash_open( QL_SPI_DEV2,
QL_PIN_12_15,
SPI_CLOCK_26M,
0,
&hndl);
if (ret != 0 || hndl == NULL) {
printf("[NAND] open failed (%d)\r\n", ret);
return;
}
/* 2. ��ѯӲ����Ϣ */
ret = ql_spi_nand_flash_get_hw_info(hndl, &info);
if (ret == 0) {
printf("[NAND] model=%s manufacturer=%s block_size=%u page_size=%u total=%u\r\n",
info.model_name,
info.manufacturer_name,
info.block_size,
info.page_size,
info.total_size);
}
/* 3. ��ѯ���� */
int blocks = ql_spi_nand_flash_get_block_num(hndl);
printf("[NAND] total blocks = %u\r\n", blocks);
test_addr = test_block_num * info.block_size;
if (test_addr >= info.total_size) {
test_addr = 0;
test_block_num = 0;
}
/* 4. ׼��д������ */
for (unsigned int i = 0; i < TEST_SIZE; i++)
g_write_buf[i] = TEST_PATTERN;
/* 5. �Ȳ���Ŀ�����򣨰�����룩 */
ret = ql_spi_nand_flash_erase(hndl, test_addr, info.block_size);
if (ret != 0) {
printf("[NAND] erase failed (%d)\r\n", ret);
goto exit;
}
/* 6. ����������������� spare�� */
ret = ql_spi_nand_flash_write(hndl,
test_addr,
g_write_buf,
TEST_SIZE,
QL_SPI_NAND_AREA_MAIN_ONLY);
if (ret != 0) {
printf("[NAND] write failed (%d)\r\n", ret);
goto exit;
}
/* 7. ��ȡ�������� */
memset(g_read_buf, 0, sizeof(g_read_buf));
ret = ql_spi_nand_flash_read(hndl,
test_addr,
g_read_buf,
TEST_SIZE,
QL_SPI_NAND_AREA_MAIN_ONLY);
if (ret != 0) {
printf("[NAND] read failed (%d)\r\n", ret);
goto exit;
}
/* 8. ������ */
if (memcmp(g_write_buf, g_read_buf, TEST_SIZE) == 0)
printf("[NAND] read-back OK\r\n");
else
printf("[NAND] data mismatch!\r\n");
exit:
ql_spi_nand_flash_close(hndl);
ql_rtos_task_sleep_ms(5000);
loop_count++;
test_block_num++;
if (test_block_num * info.block_size >= info.total_size)
{
test_block_num = 0;
}
printf("nand flash api test task loop count=%d\r\n",loop_count);
}
}
ql_task_t ql_test_task_ref;
int ql_nand_test_init(void *arg)
{
QlOSStatus status;
status =ql_rtos_task_create(&ql_test_task_ref, 4096, 100, "nandTest_task", nand_flash_api_test_task, NULL);
return 0;
}
void nand_flash_dir_test(void *argv)
{
int ret = 0;
FILE_ID filep;
size_t status = 0;
file_contex write_buffer={0};
ql_rtos_task_sleep_s(5);
ql_spi_nand_init(QL_SPI_DEV0, QL_PIN_33_36,SPI_CLOCK_26M);
ret = ql_nand_mkdir("quectel");
printf("ql_nand_mkdir %d\n",ret);
filep =ql_nand_fopen("quectel/TEST1.TXT", "wb");
write_buffer.cnt = 30965;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
}
status = ql_nand_fsync(filep);
if (status != 0)
{
printf("ql_nand_fsync is failede.!!\n");
}
int cnt = 0;
char buf = 0;
file_contex read_buffer={0};
ql_nand_frewind(filep);
status = ql_nand_fread(&cnt,1,4,filep);
if(status != 4)
{
printf("ql_nand_fread.failed status = %d\r\n",status);
}
printf("ql_nand_fread.cnt= %d\r\n",cnt);
buf = ql_nand_fgetc(filep);
printf("ql_nand_fgetc.buf= %c\r\n",buf);
ql_nand_frewind(filep);
printf("ql_nand_feof = %d\r\n",ql_nand_feof(filep,"quectel/TEST1.TXT"));
if(ql_nand_fgets(&read_buffer,68,filep) != NULL);
{
printf("ql_nand_fgets.read_buffer.cnt= %d,read_buffer.buf = %s\r\n",read_buffer.cnt,read_buffer.buf);
}
printf("ql_nand_feof = %d\r\n",ql_nand_feof(filep,"quectel/TEST1.TXT"));
ql_nand_fclose(filep);
filep =ql_nand_fopen("quectel/TEST2.TXT", "wb");
write_buffer.cnt = 30966;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
}
ql_nand_fclose(filep);
filep =ql_nand_fopen("quectel/TEST3.TXT", "wb");
write_buffer.cnt = 30967;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
}
ql_nand_fclose(filep);
ret = ql_nand_mkdir("quectel/pony");
printf("ql_nand_mkdir1 %d\n",ret);
filep =ql_nand_fopen("quectel/pony/TEST4.TXT", "wb");
write_buffer.cnt = 30968;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
}
ql_nand_fclose(filep);
filep =ql_nand_fopen("quectel/pony/TEST5.TXT", "wb");
write_buffer.cnt = 30969;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
}
ql_nand_fclose(filep);
filep =ql_nand_fopen("quectel/pony/TEST6.TXT", "wb");
write_buffer.cnt = 30970;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
}
ql_nand_fclose(filep);
list_dir("quectel");
ql_rtos_task_sleep_ms(50);
list_dir("quectel/pony");
}
void nand_flash_test(void *argv)
{
int ret = 0 ;
FILE_ID filep;
size_t status = 0;
file_contex local_buffer={0};
file_contex write_buffer={0};
unsigned int cnt = 35;
ql_rtos_task_sleep_s(5);
ql_spi_nand_init(QL_SPI_DEV0, QL_PIN_33_36,SPI_CLOCK_26M);
while(1)
{
ret = ql_nand_access("TEST.TXT");
if(ret != 1){//����ļ������ڿ�ס
filep = ql_nand_fopen("TEST.TXT", "wb");
ql_nand_fseek(filep, 0, SEEK_SET);
/* Write a string to the test file. */
memset(&write_buffer,0,sizeof(write_buffer));
write_buffer.cnt = 30965;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
break;
}
/* Close the test file. */
status = ql_nand_fclose(filep);
if (status != NULL)
{
/* Error deleting the file, break the loop. */
printf("fx_file remove is failede.!!\n");
break;
}
printf("file is not exists");
break;
}
else
{
printf("file exists");
filep = ql_nand_fopen("TEST.TXT", "rb+");
if (filep == NULL)
{
printf("fx_file_create is failede.!!\n");
/* Create error, break the loop. */
break;
}
ql_nand_fseek(filep, 0, SEEK_SET);
/* Read the first 28 bytes of the test file. */
status = ql_nand_fread(&local_buffer, 1, 68, filep);
printf("fx_file Reading[%d].!!\n", status);
/* Check the file read status. */
if (status != 68)
{
printf("fx_file checking is failede.!!\n");
}
else
{
cnt = local_buffer.cnt;
cnt++;
}
printf("File Context.[%d_%s].!!\n",local_buffer.cnt,local_buffer.buf );
/* Seek to the beginning of the test file. */
ql_nand_fseek(filep, 0, SEEK_SET);
/* Write a string to the test file. */
memset(&write_buffer,0,sizeof(write_buffer));
write_buffer.cnt = cnt;
sprintf(write_buffer.buf,"QUECTEL_BUILED_A_SMARTER_WORLD");
status = ql_nand_fwrite( &write_buffer, 1, 68, filep);
/* Check the file write status. */
if (status != 68)
{
printf("fx_file_write is failede.!!\n");
/* Error writing to a file, break the loop. */
break;
}
/* Close the test file. */
status = ql_nand_fclose(filep);
if (status != NULL)
{
/* Error deleting the file, break the loop. */
printf("fx_file remove is failede.!!\n");
break;
}
}
ql_rtos_task_sleep_ms(1);
}
}
#define QL_PCM_STATUS_FG_01 0x01
#define QL_PCM_STATUS_FG_02 0x02
#define QL_PCM_TASK_MASK_FG (QL_PCM_STATUS_FG_01|QL_PCM_STATUS_FG_02)
#define LOG_FILE "867862055278381-02-211124105928" //��־�ļ�
#define LOG_MANAGE_FILE "artc_manage.txt" //�����ļ�
ql_flag_t save_log_flag_ref = NULL; //������־��flag
ql_mutex_t log_rd_wr_mutex_lock; // ��дlog��־�Ļ�����
static void test_log_thread(void *argv)
{
unsigned int save_log_flag = 0;
while(1)
{
ql_rtos_flag_wait(save_log_flag_ref, QL_PCM_TASK_MASK_FG, QL_FLAG_OR_CLEAR, &save_log_flag, QL_WAIT_FOREVER);
ql_rtos_mutex_lock(log_rd_wr_mutex_lock,QL_WAIT_FOREVER); //������
log_write_file(); //ģ�ⵥ�ļ�׷��д��־
ql_rtos_mutex_unlock(log_rd_wr_mutex_lock); //����
ql_rtos_task_sleep_ms(30);
}
}
void start_test_log_task(void) //����������־������
{
ql_task_t test_log_task = NULL;
ql_rtos_task_create(&test_log_task, 1024*10, 100, "save_log_task", test_log_thread, NULL);
}
void log_write_file()
{
FILE_ID fp_test;
char test_str[51] = "hardware03211124203908Terminal self-test completed";
if(ql_nand_access(LOG_FILE) == 1)
{
printf("before write log, file size:%d\r\n", ql_nand_fsize(LOG_FILE));
fp_test = ql_nand_fopen(LOG_FILE, "rb+");
if(fp_test == NULL)
{
printf("open LOG_FILE fail");
return;
}
ql_nand_fseek(fp_test, 0, SEEK_END); //ƫ�Ƶ��ļ�ĩ
ql_nand_fwrite(test_str, 1, strlen(test_str), fp_test);
ql_nand_fclose(fp_test);
printf("after write log, file size:%d\r\n", ql_nand_fsize(LOG_FILE));
}
else
{
printf("LOG_FILE NO EXIST AND CREATE\r\n");
fp_test = ql_nand_fopen(LOG_FILE, "wb");
ql_nand_fclose(fp_test);
}
printf("write log file end\r\n");
}
static void demo_main(void * argv)
{
ql_autosleep_enable(1);
}
//application_init(demo_main, "demo_main", 10, 1);
// application_init(nand_flash_dir_test, "nand_flash_test", 10, 6);
application_init(ql_nand_test_init, "ql_nand_test_init", 2, 6);