⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flash.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================////      flash.c////      Flash programming////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2003 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    gthomas// Contributors: gthomas// Date:         2000-07-26// Purpose:      // Description:  //              //####DESCRIPTIONEND####////==========================================================================#include <pkgconf/system.h>#include <pkgconf/io_flash.h>#include <cyg/hal/hal_arch.h>#include <cyg/hal/hal_intr.h>#include <cyg/hal/hal_cache.h>#include <string.h>#define  _FLASH_PRIVATE_#include <cyg/io/flash.h>// When this flag is set, do not actually jump to the relocated code.// This can be used for running the function in place (RAM startup only),// allowing calls to diag_printf() and similar.#undef RAM_FLASH_DEV_DEBUG#if !defined(CYG_HAL_STARTUP_RAM) && defined(RAM_FLASH_DEV_DEBUG)# warning "Can only enable the flash debugging when configured for RAM startup"#endifstruct flash_info flash_info;// These are the functions in the HW specific driver we need to call.typedef void code_fun(void*);externC code_fun flash_query;externC code_fun flash_erase_block;externC code_fun flash_program_buf;externC code_fun flash_read_buf;externC code_fun flash_lock_block;externC code_fun flash_unlock_block;intflash_init(_printf *pf){    int err;    if (flash_info.init) return FLASH_ERR_OK;    flash_info.pf = pf; // Do this before calling into the driver    if ((err = flash_hwr_init()) != FLASH_ERR_OK) {        return err;    }    flash_info.block_mask = ~(flash_info.block_size-1);    flash_info.init = 1;    return FLASH_ERR_OK;}// Use this function to make function pointers anonymous - forcing the// compiler to use jumps instead of branches when calling driver// services.static void* __anonymizer(void* p){  return p;}// FIXME: Want to change all drivers to use this function. But it may// make sense to wait till device structure pointer arguments get// added as well.voidflash_dev_query(void* data){    typedef void code_fun(void*);    code_fun *_flash_query;    int d_cache, i_cache;    _flash_query = (code_fun*) __anonymizer(&flash_query);    HAL_FLASH_CACHES_OFF(d_cache, i_cache);    (*_flash_query)(data);    HAL_FLASH_CACHES_ON(d_cache, i_cache);}intflash_verify_addr(void *target){    if (!flash_info.init) {        return FLASH_ERR_NOT_INIT;    }    if (((CYG_ADDRESS)target >= (CYG_ADDRESS)flash_info.start) &&        ((CYG_ADDRESS)target <= ( ((CYG_ADDRESS)flash_info.end) - 1) )) {        return FLASH_ERR_OK;    } else {        return FLASH_ERR_INVALID;    }}intflash_get_limits(void *target, void **start, void **end){    if (!flash_info.init) {        return FLASH_ERR_NOT_INIT;    }    *start = flash_info.start;    *end = flash_info.end;    return FLASH_ERR_OK;}intflash_get_block_info(int *block_size, int *blocks){    if (!flash_info.init) {        return FLASH_ERR_NOT_INIT;    }    *block_size = flash_info.block_size;    *blocks = flash_info.blocks;    return FLASH_ERR_OK;}intflash_erase(void *addr, int len, void **err_addr){    unsigned short *block, *end_addr;    int stat = 0;    typedef int code_fun(unsigned short *, unsigned int);    code_fun *_flash_erase_block;    int d_cache, i_cache;    if (!flash_info.init) {        return FLASH_ERR_NOT_INIT;    }#ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT    if (plf_flash_query_soft_wp(addr,len))        return FLASH_ERR_PROTECT;#endif     _flash_erase_block = (code_fun*) __anonymizer(&flash_erase_block);    block = (unsigned short *)((CYG_ADDRESS)addr & flash_info.block_mask);    end_addr = (unsigned short *)((CYG_ADDRESS)addr+len);    /* Check to see if end_addr overflowed */    if( (end_addr < block) && (len > 0) ){        end_addr = (unsigned short *) ((CYG_ADDRESS) flash_info.end - 1);    }#ifdef CYGSEM_IO_FLASH_CHATTER    (*flash_info.pf)("... Erase from %p-%p: ", (void*)block, (void*)end_addr);#endif    HAL_FLASH_CACHES_OFF(d_cache, i_cache);    FLASH_Enable(block, end_addr);    while (block < end_addr) {        // Supply the blocksize for a gross check for erase success        unsigned short *tmp_block;#if !defined(CYGSEM_IO_FLASH_READ_INDIRECT)        int i;        unsigned char *dp;        bool erased = true;        dp = (unsigned char *)block;        for (i = 0;  i < flash_info.block_size;  i++) {            if (*dp++ != (unsigned char)0xFF) {                erased = false;                break;            }        }#else        bool erased = false;#endif        if (!erased) {            stat = (*_flash_erase_block)(block, flash_info.block_size);            stat = flash_hwr_map_error(stat);        }        if (stat) {            *err_addr = (void *)block;            break;        }        // Check to see if block will overflow        tmp_block = block + flash_info.block_size / sizeof(*block);        if(tmp_block < block){            // If block address overflows, set block value to end on this loop            block = end_addr;        }        else{            block = tmp_block;        }#ifdef CYGSEM_IO_FLASH_CHATTER        (*flash_info.pf)(".");#endif    }    FLASH_Disable(block, end_addr);    HAL_FLASH_CACHES_ON(d_cache, i_cache);#ifdef CYGSEM_IO_FLASH_CHATTER    (*flash_info.pf)("\n");#endif    return (stat);}intflash_program(void *_addr, void *_data, int len, void **err_addr){    int stat = 0;    int size;    typedef int code_fun(void *, void *, int, unsigned long, int);    code_fun *_flash_program_buf;    unsigned char *addr = (unsigned char *)_addr;    unsigned char *data = (unsigned char *)_data;    CYG_ADDRESS tmp;    int d_cache, i_cache;    if (!flash_info.init) {        return FLASH_ERR_NOT_INIT;    }#ifdef CYGSEM_IO_FLASH_SOFT_WRITE_PROTECT    if (plf_flash_query_soft_wp(addr,len))        return FLASH_ERR_PROTECT;#endif    _flash_program_buf = (code_fun*) __anonymizer(&flash_program_buf);#ifdef CYGSEM_IO_FLASH_CHATTER    (*flash_info.pf)("... Program from %p-%p at %p: ", (void*)data,                      (void*)(((CYG_ADDRESS)data)+len), (void*)addr);#endif    HAL_FLASH_CACHES_OFF(d_cache, i_cache);    FLASH_Enable((unsigned short*)addr, (unsigned short *)(addr+len));    while (len > 0) {        size = len;        if (size > flash_info.block_size) size = flash_info.block_size;        tmp = (CYG_ADDRESS)addr & ~flash_info.block_mask;        if (tmp) {                tmp = flash_info.block_size - tmp;                if (size>tmp) size = tmp;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -