历史上的今天

今天是:2024年10月10日(星期四)

正在发生

2020年10月10日 | 单片机flash通用读写库:TZFlash

发布者:玉立风华 来源: eefocus关键字:单片机  flash  通用读写库  TZFlash 手机看文章 扫描二维码
随时随地手机看文章

说明

本文发布单片机flash通用读写库TZFlash,有两个优点:


TZFlash将flash的读写抽象成文件读写,更易于使用。

flash写入需要4字节对齐,TZFlash增加cache机制,可以将任意长度的写入flash。


源码

tzflash.h

// Copyright 2019-2019 The TZIOT Authors. All rights reserved.

// flash管理模块头文件


#ifndef TZFLASH_H

#define TZFLASH_H


#include "tzbasedef.h"


// TZFlashEraseFunc 函数类型:擦除flash

// addr:起始地址.size:擦除字节数

// 成功返回true,失败返回false

typedef bool (*TZFlashEraseFunc)(int addr, int size);


// TZFlashWriteFunc 函数类型:写入flash

// addr:起始地址.bytes:待写入的字节流.size:写入字节数

// 成功返回true,失败返回false

typedef bool (*TZFlashWriteFunc)(int addr, uint8_t* bytes, int size);


// TZFlashReadFunc 函数类型:读取flash

// addr:起始地址.bytes:读取的字节流存放的缓存.size:读取的字节数

// 成功返回true,失败返回false

typedef bool (*TZFlashReadFunc)(int addr, uint8_t* bytes, int size);


// TZFlashOpenMode 打开模式

typedef enum {

    TZFLASH_READ_ONLY = 0,

    TZFLASH_WRITE_ONLY

} TZFlashOpenMode;


// TZFlashLoad 模块载入

void TZFlashLoad(int pageSize, TZFlashEraseFunc eraseFunc, TZFlashWriteFunc writeFunc, TZFlashReadFunc readFunc);


// TZFlashOpen 打开flash文件.

// 注意:打开时会擦除flash.要保证打开的flash大小是页的整数倍,否则会打开失败

// 返回值为0表示打开失败

intptr_t TZFlashOpen(int addrStart, int size, TZFlashOpenMode mode);


// TZFlashWrite 向flash写入数据

// 成功返回写入的字节数,失败返回-1

int TZFlashWrite(intptr_t fd, uint8_t* bytes, int size);


// TZFlashRead 从flash中读取数据

// 成功返回读取的字节数,失败返回-1

int TZFlashRead(intptr_t fd, uint8_t* bytes, int size);


// TZFlashClose 关闭

void TZFlashClose(intptr_t fd);


#endif


tzflash.c

// Copyright 2019 The TZIOT Authors. All rights reserved.

// flash管理模块主文件


#include "tzflash.h"


#define CACHE_SIZE 64


#pragma pack(1)


// tFlashInterface flash管理接口

typedef struct {

    int pageSize;

    TZFlashEraseFunc erase;

    TZFlashWriteFunc write;

    TZFlashReadFunc read;

} tFlashInterface;


// tFlashFile flash文件类型

typedef struct {

    int addrStart;

    int addrStop;

    int offset;

    TZFlashOpenMode mode;

    uint8_t cache[CACHE_SIZE];

    int cacheLen;

} tFlashFile;


#pragma pack()


static tFlashInterface gInterface;


// TZFlashLoad 模块载入

void TZFlashLoad(int pageSize, TZFlashEraseFunc eraseFunc, TZFlashWriteFunc writeFunc, TZFlashReadFunc readFunc) {

    gInterface.pageSize = pageSize;

    gInterface.erase = eraseFunc;

    gInterface.write = writeFunc;

    gInterface.read = readFunc;

}


// TZFlashOpen 打开flash文件.

// 注意:只写模式打开时会擦除flash.要保证打开的flash大小是页的整数倍,否则会打开失败

// 返回值为0表示打开失败

intptr_t TZFlashOpen(int addrStart, int size, TZFlashOpenMode mode) {

    if (mode == TZFLASH_WRITE_ONLY) {

        if (size % gInterface.pageSize != 0) {

            return 0;

        }

        if (gInterface.erase(addrStart, size) == false) {

            return 0;

        }

    }


    tFlashFile* file = malloc(sizeof(tFlashFile));

    if (file == NULL) {

        return 0;

    }

    file->addrStart = addrStart;

    file->addrStop = addrStart + size - 1;

    file->mode = mode;

    file->offset = file->addrStart;

    file->cacheLen = 0;

    return (intptr_t)file;

}


// TZFlashWrite 向flash写入数据

// 成功返回写入的字节数,失败返回-1

int TZFlashWrite(intptr_t fd, uint8_t* bytes, int size) {

    tFlashFile* file = (tFlashFile*)fd;

    if (file->mode == TZFLASH_READ_ONLY) {

        return -1;

    }

    if (file->offset + file->cacheLen + size > file->addrStop) {

        return -1;

    }


    int delta = 0;

    int writeNum = 0;

    for (;;) {

        delta = CACHE_SIZE - file->cacheLen;

        // 比cache可写入空间小则直接写入

        if (size < delta) {

            memcpy(file->cache + file->cacheLen, bytes, (size_t)size);

            file->cacheLen += size;

            writeNum += size;

            break;

        }


        // 写满cache,再全部写入flash

        memcpy(file->cache + file->cacheLen, bytes, (size_t)delta);

        file->cacheLen += delta;

        gInterface.write(file->offset, file->cache, file->cacheLen);

        file->offset += file->cacheLen;

        file->cacheLen = 0;

        size -= delta;

        writeNum += delta;

    }

    return writeNum;

}


// TZFlashRead 从flash中读取数据

// 成功返回读取的字节数,失败返回-1

int TZFlashRead(intptr_t fd, uint8_t* bytes, int size) {

    tFlashFile* file = (tFlashFile*)fd;

    if (file->mode == TZFLASH_WRITE_ONLY) {

        return -1;

    }

    if (file->offset > file->addrStop) {

        return 0;

    }

    int delta = file->addrStop - file->offset + 1;

    int readSize = delta > size ? size : delta;

    gInterface.read(file->offset, bytes, readSize);

    file->offset += readSize;

    return readSize;

}


// TZFlashClose 关闭

void TZFlashClose(intptr_t fd) {

    tFlashFile* file = (tFlashFile*)fd;

    gInterface.write(file->offset, file->cache, file->cacheLen);

    free(file);

}


测试

#include "test_tzflash.h"

#include "tzflash.h"


#define PAGE_SIZE 1024

#define FLASH_SIZE 10240


static uint8_t gFlash[FLASH_SIZE] = {0};


static bool erase(int addr, int size);

static bool write(int addr, uint8_t* bytes, int size);

static bool read(int addr, uint8_t* bytes, int size);

static void testCase0(void);

static void testCase1(void);

static void testCase2(void);


void TestTZFlashRun(void) {

    printf("-------------------->test tz flashn");

    TZFlashLoad(PAGE_SIZE, erase, write, read);

    testCase0();

    testCase1();

    testCase2();

    printf("-------------------->test endn");

}


static bool erase(int addr, int size) {

    if (size % PAGE_SIZE != 0) {

        return false;

    }

    memset(gFlash + addr, 0, (size_t)size);

    return true;

}


static bool write(int addr, uint8_t* bytes, int size) {

    if (addr + size > FLASH_SIZE) {

        return false;

    }

    memcpy(gFlash + addr, bytes, (size_t)size);

    return true;

}


static bool read(int addr, uint8_t* bytes, int size) {

    if (size > FLASH_SIZE - addr) {

        return false;

    }

    memcpy(bytes, gFlash + addr, (size_t)size);

    return true;

}


static void testCase0(void) {

    printf("-------------------->testCase0n");


    intptr_t fd = TZFlashOpen(0, PAGE_SIZE, TZFLASH_WRITE_ONLY);


    int writeNum = 0;

    writeNum = TZFlashWrite(fd, "i am jdh!", strlen("i am jdh"));

    printf("write:%s", "i am jdh!n");

    writeNum += TZFlashWrite(fd, "123456789", strlen("123456789"));

    printf("write:%s", "123456789n");

    writeNum += TZFlashWrite(fd, "abcde", strlen("abcde"));

    printf("write:%s", "abcden");


    TZFlashClose(fd);


    fd = TZFlashOpen(0, PAGE_SIZE, TZFLASH_READ_ONLY);

    char buf[100] = {0};

    int readNum = TZFlashRead(fd, buf, writeNum);


    TZFlashClose(fd);


    printf("write num:%d read num:%d read text:%sn", writeNum, readNum, buf);

}


static void testCase1(void) {

    printf("-------------------->testCase1n");


    intptr_t fd = TZFlashOpen(1024, PAGE_SIZE * 4, TZFLASH_WRITE_ONLY);


    uint8_t buf[255] = {0};

    for (int i = 0; i < 234; i++) {

        buf[i] = i;

    }


    int writeNum = 0;

    for (int i = 0; i < 10; i++) {

        writeNum += TZFlashWrite(fd, buf, 234);

    }

    printf("write num:%dn", writeNum);


    TZFlashClose(fd);


    fd = TZFlashOpen(1024, PAGE_SIZE, TZFLASH_READ_ONLY);


    uint8_t buf1[255] = {0};

    int readNum = 0;

    for (int i = 0; i < 5; i++) {

        readNum = TZFlashRead(fd, buf1, 10);

        printf("read num:%dn", readNum);

        for (int i = 0; i < 10; i++) {

            printf("%d ", buf1[i]);

        }

        printf("n");

    }


    TZFlashClose(fd);

}


static void testCase2(void) {

    printf("-------------------->testCase2n");


    intptr_t fd = TZFlashOpen(2048, PAGE_SIZE * 4, TZFLASH_WRITE_ONLY);


    uint8_t buf[1] = {0};

    int writeNum = 0;

    for (int i = 0; i < 1024; i++) {

        buf[0] = i;

        writeNum += TZFlashWrite(fd, buf, 1);

        if (i < 5 || i > 1020) {

            printf("write:%d:%dn", i, buf[0]);

        }

    }

    printf("write num:%dn", writeNum);


    TZFlashClose(fd);


    fd = TZFlashOpen(2048, PAGE_SIZE, TZFLASH_READ_ONLY);


    int readNum = 0;

    for (int i = 0; i < 1024; i++) {

        readNum += TZFlashRead(fd, buf, 1);

        if (i < 5 || i > 1020) {

[1] [2]
关键字:单片机  flash  通用读写库  TZFlash 引用地址:单片机flash通用读写库:TZFlash

上一篇:STM32待机模式测试
下一篇:驱动字库芯片GT23L24M0140

推荐阅读

BlackBerry近日宣布推出,抗量子代码签名服务器,进一步扩充其加密工具产品线。这一全新解决方案将为软件配备难以为量子计算机所攻破的数字签名机制。 “量子计算将在医疗、交通、天体物理、政府等众多领域解决突破性问题;然而,与此同时,它也将给心怀不轨的黑客可乘之机,用于破解公钥加密系统,进而盗取它们保护下的底层数据,”BlackBerry首席技术官C...
  随着全球暖化与气候变迁日益加剧,再生能源产业已成为必然的趋势,而台湾也无法置身事外。在台湾当局的光伏中长期规划中,目标设定在 2020 年完成装设 6.5GW 光伏, 2025 年装设 3GW 屋顶型、17 GW 地面型共 20GW 的光伏容量。累积至2018年,全台的光伏安装容量已超过 1GW,正式迈向了 GW 级市场。看好台湾地区光伏市场,在台已深根 ...
环境:主机:WIN8开发环境:MDK5.13mcu: stm32f407VGIGH6字库芯片:GT23L24M0140说明:GT23L24M0140是一款支持GB18030标准的字库芯片,有多种大小的字体可供选择。本文驱动了其中常用的字体。源代码:drv_font.h/********************************************************************** 字库芯片驱动层头文件* (c)copyright 2013,jdh* ...
从1947年第一个晶体管问世算起,半导体技术一直在迅猛发展,现在它仍保持着强劲的发展态势,继续遵循摩尔定律指明的方向前进,大尺寸、细线宽、高精度、高效率、低成本的IC生产,正在对半导体产业链带来前所未有的挑战。集成电路在制造过程中经历了材料制备、掩膜、光刻、清洗、刻蚀、掺杂、化学机械抛光等多个工序,其中尤以光刻工艺最为关键,决定着制造...

史海拾趣

问答坊 | AI 解惑

如何改善单片机通讯中光耦输出的波形

电路如下,测得TXD和TXA的波形如图中所示,TXD接单片机TXD,TXA为光耦输出波形,TXD波形还算理想,但TXA波形上升沿上升缓慢,请问各位大虾如何改善TXA波形? …

查看全部问答∨

矩阵键盘程序汇总

最简单矩阵键盘扫描程序 key:mov p0,#00001111b;上四位和下四位分别为行和列,所以送出高 低电压检查有没有按键按下 jmp k10;跳到K10处开始扫描,这里可以改成其它条件转移指令来决 定本次扫描是否要继续,例如减1为0转移或者位为1或0才转移,这 ...…

查看全部问答∨

请问各位老师有否400M丙类功率放大器制作方面的资料吗

请问各位老师有否400M丙类功率放大器制作方面的资料吗?…

查看全部问答∨

监测点电路图

本帖最后由 paulhyde 于 2014-9-15 09:39 编辑 自己到处查资料,拼的一份原理图,希望大家喜欢  …

查看全部问答∨

请教:AD8337的增益范围到底是多少,请用过的回答一下,多谢!

芯片资料上写的是0-24dB,但是我在一篇文章上看到是-6dB~18dB,见下图,搞不懂怎么来的。 …

查看全部问答∨

请教一个关于wm_command消息的问题

我在一个窗口中添加一个button, 在WM_COMMAND中, 点击这个button, button处于按下的状态, 松开鼠标的时候, 弹出一个窗口, 关闭这个弹出的窗口之后, button才被弹起来, 我想要的是松开鼠标的同时, button进入弹起的状态, 也就是说, 这个弹出窗口被关 ...…

查看全部问答∨

Window ce.net 4.0 如何开发屏幕保护程序,并指定快捷键Ctrl+Alt+Q

Window ce.net 4.0 如何开发屏幕保护程序,并指定快捷键Ctrl+Alt+Q 是一台设备上的系统,我想按下快捷键显示屏幕保护程序,并在中间显示几行字 知道的请帮助我一下…

查看全部问答∨

tchar字符串转换为十进制的方法

请教一个问题: 在WinCE环境下,使用eVC编程 定义了2个字节的数据 TCHAR buf1[3]=_T("7A"); SetDlgItemText(IDC_EDIT3,buf1); 显示的ASCII 现在我想用十进制显示出来,怎么转换呢?…

查看全部问答∨

请教关于FPGA和PC机之间的通信接口问题

用RS232串口实现最简单,但是速度慢; 用EPP/ECP并口传输数据和用USB总线传输数据两种方案从开发难易程度、通信速度方面各有哪些优势呢? 开发难易程度需要考虑FPGA端的开发以及PC端软件的开发两方面; 谢谢各位,目前正在方案选择中,希望大家 ...…

查看全部问答∨

看不到每天的新帖数了

貌似论坛改版了, 以前在论坛首页,每个板块有多少新帖都直接显示出来了,现在怎么没有了,感觉有必要还是添加上这个功能…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved