BANK_BASE(i)的理解

本文解释了BANK_BASE宏的含义与用法,通过将其转换为数组索引形式,便于理解不同Flash银行地址的获取方式。适用于嵌入式系统的开发者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typedef unsigned long phys_addr_t;
#define CONFIG_SYS_MAX_FLASH_BANKS      1
# define CFI_MAX_FLASH_BANKS CONFIG_SYS_MAX_FLASH_BANKS
#define CONFIG_SYS_FLASH_BASE      0x10000000
#define CONFIG_SYS_FLASH_BANKS_LIST  { CONFIG_SYS_FLASH_BASE}
#define BANK_BASE(i)	(((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])



刚开始看到这段代码的时候很疑惑,这个BANK_BASE(i)表示什么,以前没见过这样的代码啊。经过一番推敲,它的意思是这样的:

typedef unsigned long phys_addr_t;
#define CONFIG_SYS_MAX_FLASH_BANKS      1
# define CFI_MAX_FLASH_BANKS CONFIG_SYS_MAX_FLASH_BANKS
#define CONFIG_SYS_FLASH_BASE      0x10000000
static phys_addr_t bankList[CONFIG_SYS_MAX_FLASH_BANKS] = { CONFIG_SYS_FLASH_BASE};
#define BANK_BASE(i)  bankList[i]



其它就是取得一个数组变量的索引值。



举一个例子,假如有两片FLASH:
常用的写法是:

#define CONFIG_SYS_MAX_FLASH_BANKS      2  
# define CFI_MAX_FLASH_BANKS CONFIG_SYS_MAX_FLASH_BANKS   
#define CONFIG_SYS_FLASH1_BASE      0x10000000   
#define CONFIG_SYS_FLASH2_BASE      0x20000000   
static phys_addr_t bankList[CONFIG_SYS_MAX_FLASH_BANKS] = { CONFIG_SYS_FLASH1_BASE, CONFIG_SYS_FLASH2_BASE};  
#define BANK_BASE(i)  bankList[i]

BANK_BASE(i)就是第i片falsh的地址。

在uboot中:

typedef unsigned long phys_addr_t;
#define CONFIG_SYS_MAX_FLASH_BANKS      2
# define CFI_MAX_FLASH_BANKS CONFIG_SYS_MAX_FLASH_BANKS
#define CONFIG_SYS_FLASH1_BASE      0x10000000
#define CONFIG_SYS_FLASH2_BASE      0x20000000
#define CONFIG_SYS_FLASH_BANKS_LIST  { CONFIG_SYS_FLASH1_BASE, CONFIG_SYS_FLASH2_BASE}
#define BANK_BASE(i)	(((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])


(1) (phys_addr_t [CFI_MAX_FLASH_BANKS])是一个类型,它是一个数组类型;

(2) CONFIG_SYS_FLASH_BANKS_LIST这个宏展开就是“{ CONFIG_SYS_FLASH1_BASE, CONFIG_SYS_FLASH2_BASE}”;

(3) “((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)”就是将(2)中的两个大括号之间的内容强制转换成(1)所述的数组类型;

(4) “[i]”的意思就是取这个数组的索引值。

 

GCC竟然支持这样的语法,写出这种语句的作者一定对GCC了解很深。但个人觉得在实际项目中真写很多类似这样的代码,维护代码的同事可要受苦了!

/******************************************************************************* * Copyright (c) 2013, SHENZHEN SEMITEK Co.,LTD. * All rights reserved. * * 文件名称: Flash_process.c * * 功能明: * 修改明: *******************************************************************************/ #include <string.h> #include <stdint.h> #include <stdbool.h> #include "om_driver.h" #include "led.h" #include "sensor.h" #include "main.h" #include <flash.h> #include "flash_process.h" //-----------------------------------------------------------------------------; // 常量定义区 // //-----------------------------------------------------------------------------; // 变量定义区 // bool bsave_status; bool bsave_cfg_dpi; bool bsave_ble_id; __ALIGNED(4) uint8_t flash_fifo[256]; __ALIGNED(4) uint8_t dpi_value_tbl[8]; __ALIGNED(4) uint8_t def_key_dat[24]; __ALIGNED(4) uint8_t fire_led_dat[8]; uint8_t para_cfg_dat[5]; uint8_t report_dpi[4]; uint8_t ble_id[4]; uint8_t key_mode; uint8_t rgb_ctrl; uint8_t logo_rgb_index; uint8_t sleep_time_24g; uint8_t sleep_time_ble; uint8_t report_usb; uint8_t report_24g; uint8_t mouse_lod_set; uint8_t key_delay_set; uint16_t adv_cfg_value; uint8_t device_status_base; uint8_t cfg_dpi_base; //---------------------------------------------------------------------------- //表格定义区 // unsigned char const default_cfg_tbl[] = { 0xFF, // X灵敏度 0xFF, // Y灵敏度 0xFF, // 狙击DPI+ // 对应最高DPI 0xFF, // 狙击DPI- // 对应最低DPI 小于400DPI的以400为准 0x01, // 组合连发延时 0xFF, // 保留 0xFF, // 保留 0xFF, // 保留 //---------------------------------------------- 0xF3,0x00,0x11,0x00,0xFF,0x00,0x00,0xFF, // 火力键LED 红色狂闪 //---------------------------------------------- // 0x10 0xE2,0x08,0x22,0x00,0xFF,0x00,0x00,0xFF, // DPI0 LED 红色闪4次 0xE2,0x08,0x22,0x00,0x00,0xFF,0x00,0xFF, // DPI1 LED 绿色闪4次 0xE2,0x08,0x22,0x00,0x00,0x00,0xFF,0xFF, // DPI2 LED 蓝色闪4次 0xE2,0x08,0x22,0x00,0xFF,0x00,0xFF,0xFF, // DPI3 LED 紫色闪4次 0xE2,0x08,0x22,0x00,0xFF,0xFF,0x00,0xFF, // DPI4 LED 橙色闪4次 0xE2,0x08,0x22,0x00,0x00,0xFF,0xFF,0xFF, // DPI5 LED 青色闪4次 0xE2,0x08,0x22,0x00,0xFF,0xFF,0xFF,0xFF, // DPI6 LED 白色闪4次 0xE2,0x08,0x22,0x00,0xFF,0x3F,0x7F,0xFF, // DPI7 LED 黄色闪4次 //---------------------------------------------- // 0x50 0xF2,0x00,0xF0,0x00,0xFF,0xFF,0xFF,0xFF, // 常亮 0xF2,0x00,0x22,0x00,0xFF,0xFF,0xFF,0xFF, // 闪烁 0xF3,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, // 呼吸 0xF4,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF, // 霓虹 //---------------------------------------------- }; unsigned char const default_key_tbl[]={ 0x81,0x41, // 0 mouse r 0x82,0x41, // 1 mouse l 0x84,0x41, // 2 mouse m 0x88,0x41, // 3 mouse 4 0x90,0x41, // 4 mouse 5 0xFF,0xFF, // 5 0xFF,0xFF, // 6 0x02,0x48, // 7 dpi+ 0x01,0x42, // 8 wheel+ 0xFF,0x42, // 9 wheel- 0xFF,0xFF, // 10 保留 0xFF,0xFF, // 11 保留 }; unsigned char const s205_dpi_ini[] = { 800/50, 1200/50, 1600/50, 2400/50, 3200/50, 4000/50, 5000/50, 6400/50, }; uint32_t const ble_sleep_1_time_tbl[] = { mMS_TO_TICK(10*1000), // 10s mMS_TO_TICK(30*1000), // 30s mMS_TO_TICK(60*1000), // 60s mMS_TO_TICK(120*1000), // 2min mMS_TO_TICK(180*1000), // 3min mMS_TO_TICK(300*1000), // 5min mMS_TO_TICK(600*1000), // 10min mMS_TO_TICK(600*1000), // 10min }; uint32_t const ble_sleep_2_time_tbl[] = { mMS_TO_TICK(5*60*1000), // 5min mMS_TO_TICK(10*60*1000), // 10min mMS_TO_TICK(15*60*1000), // 15min mMS_TO_TICK(20*60*1000), // 20min mMS_TO_TICK(30*60*1000), // 30min mMS_TO_TICK(40*60*1000), // 40min mMS_TO_TICK(60*60*1000), // 60min mMS_TO_TICK(60*60*1000), // 60min }; //============================================================================; // 代码区 ; //============================================================================; /******************************************************************************* * 函数名称: checksum_flash() * 功能描述: * 输入参数:无 * 输出参数:无 * 明: *******************************************************************************/ unsigned char checksum_flash(unsigned char lenght, unsigned char *ptr) { unsigned char i, check; check = 0x5A; for(i=0; i<lenght; i++) check ^= ptr[i]; return check; } /******************************************************************************* * 函数名称: laod_mouse_status() * 功能描述: * 输入参数:无 * 输出参数:无 * 明: *******************************************************************************/ void laod_mouse_status(void) { uint8_t i; //---------------------------------------------- // 读取状态数据 鼠标自身状态:当前DPI,LED模式灯 // flash_read(iSTATUS_BANK_ADDR, 256); device_status_base = 0xF8; i = 0xF8; while(1) { if(iSTATUS_DATA_TYPE == (flash_fifo[i+0])) { device_status_base = i; key_mode = (flash_fifo[i+6]&0x03); bt_index = ((flash_fifo[i+6]>>2)&0x03); device_type = ((flash_fifo[i+6]>>4)&0x07); // 按键切换模式情况下才能打开 !!!!!!!! report_dpi[0] = flash_fifo[i+1]; report_dpi[1] = flash_fifo[i+2]; report_dpi[2] = flash_fifo[i+3]; report_dpi[3] = flash_fifo[i+4]; led_mode = (flash_fifo[i+5]&0x0F); bled_bright_en = false; if(flash_fifo[i+5]&(1<<7)) bled_bright_en = true; dpi_grade = (report_dpi[key_mode]&0x07); report_24g = ((report_dpi[key_mode]>>4)&0x03); report_usb = ((report_dpi[key_mode]>>6)&0x03); if(0 == i) break; } else { if(0 == i) { key_mode = 0; report_dpi[0] = ((iREPORT_1000<<6)|(iREPORT_1000<<4)|2); // usb:1000Hz;24g:250Hz; DPI1 report_dpi[1] = ((iREPORT_1000<<6)|(iREPORT_1000<<4)|2); // usb:1000Hz;24g:250Hz; DPI1 report_dpi[2] = ((iREPORT_1000<<6)|(iREPORT_1000<<4)|2); // usb:1000Hz;24g:250Hz; DPI1 report_dpi[3] = ((iREPORT_1000<<6)|(iREPORT_1000<<4)|2); // usb:1000Hz;24g:250Hz; DPI1 bt_index = iDEVICE_TYPE_BT0; device_type = iDEVICE_TYPE_BT0; dpi_grade = 2; report_24g = iREPORT_1000; report_usb = iREPORT_1000; led_mode = iLOGO_NH; bled_bright_en = true; } break; } i -= 0x08; } } /******************************************************************************* * 函数名称: laod_cfg_dpi() * 功能描述: * 输入参数:无 * 输出参数:无 * 明: *******************************************************************************/ void laod_cfg_dpi(void) { uint8_t i; //---------------------------------------------- // 系统配置数据 APP下发的相关配置数据 // flash_read(iFLASH_CFG_DPI_ADDR, 256); cfg_dpi_base = 0xF0; i = 0xF0; while(1) { if(iCFG_DPI_TYPE == (flash_fifo[i+0])) { cfg_dpi_base = i; led_light_lev = (flash_fifo[i+1]&0x07); led_speed_lev = ((flash_fifo[i+1]>>4)&0x07); rgb_ctrl = (flash_fifo[i+2]&0x07); sleep_time_24g = flash_fifo[i+3]; sleep_time_ble = flash_fifo[i+4]; adv_cfg_value = ((flash_fifo[i+6]<<8)|flash_fifo[i+5]); mouse_lod_set = ((flash_fifo[i+5]>>0)&0x03); key_delay_set = ((flash_fifo[i+5]>>2)&0x03); memcpy(dpi_value_tbl, flash_fifo+i+8, 8); if(0 == i) break; } else { if(0xF0 == i) { led_light_lev = iLED_LEV_3; led_speed_lev = iSPEED_LEV_2; rgb_ctrl = iPWM_RGB; // 全彩 sleep_time_24g = 0x12; // 24g:1分钟一级休眠,10分钟深度休眠 sleep_time_ble = 0x44; // ble:3分钟一级休眠,30分钟深度休眠 adv_cfg_value = 0x0001; mouse_lod_set = 1; // 静默高度 key_delay_set = 0; // 去抖延时 memcpy(dpi_value_tbl, s205_dpi_ini, 8); } break; } i -= 0x10; } } /******************************************************************************* * 函数名称: laod_mode_data() * 功能描述: * 输入参数:无 * 输出参数:无 * 明: *******************************************************************************/ void laod_flash_cfg(void) { uint8_t i; drv_flash_init(); laod_mouse_status(); laod_cfg_dpi(); //---------------------------------------------- // 读取按键配置0 // flash_read(iKEY_MODE0_ADDR, 32); i = checksum_flash(31, flash_fifo); if(flash_fifo[iKEY_DATA_CS_ADDR] != i) { memset(flash_fifo, 0xFF, 31); memcpy(flash_fifo, default_key_tbl, sizeof(default_key_tbl)); flash_fifo[iKEY_DATA_CS_ADDR] = checksum_flash(31, flash_fifo); flash_erase(iKEY_MODE0_BANK); flash_write(iKEY_MODE0_ADDR, 32); } if(iKEY_MODE_0 == key_mode) memcpy(def_key_dat, flash_fifo, 24); // //---------------------------------------------- // 读取按键配置1 // flash_read(iKEY_MODE1_ADDR, 32); if(flash_fifo[iKEY_DATA_CS_ADDR] != checksum_flash(31, flash_fifo)) { memset(flash_fifo, 0xFF, 31); memcpy(flash_fifo, default_key_tbl, sizeof(default_key_tbl)); flash_fifo[iKEY_DATA_CS_ADDR] = checksum_flash(31, flash_fifo); flash_erase(iKEY_MODE1_BANK); flash_write(iKEY_MODE1_ADDR, 32); } if(iKEY_MODE_1 == key_mode) memcpy(def_key_dat, flash_fifo, 24); // //---------------------------------------------- // 读取按键配置2 // flash_read(iKEY_MODE2_ADDR, 32); if(flash_fifo[iKEY_DATA_CS_ADDR] != checksum_flash(31, flash_fifo)) { memset(flash_fifo, 0xFF, 31); memcpy(flash_fifo, default_key_tbl, sizeof(default_key_tbl)); flash_fifo[iKEY_DATA_CS_ADDR] = checksum_flash(31, flash_fifo); flash_erase(iKEY_MODE2_BANK); flash_write(iKEY_MODE2_ADDR, 32); } if(iKEY_MODE_2 == key_mode) memcpy(def_key_dat, flash_fifo, 24); // //---------------------------------------------- // 读取按键配置3 // flash_read(iKEY_MODE3_ADDR, 32); if(flash_fifo[iKEY_DATA_CS_ADDR] != checksum_flash(31, flash_fifo)) { memset(flash_fifo, 0xFF, 31); memcpy(flash_fifo, default_key_tbl, sizeof(default_key_tbl)); flash_fifo[iKEY_DATA_CS_ADDR] = checksum_flash(31, flash_fifo); flash_erase(iKEY_MODE3_BANK); flash_write(iKEY_MODE3_ADDR, 32); } if(iKEY_MODE_3 == key_mode) memcpy(def_key_dat, flash_fifo, 24); // //---------------------------------------------- // 读取配置 // flash_read(iCFG_BANK_ADDR, 256); if(iCFG_DATA_TYPE_VALULE != flash_fifo[iCFG_DATA_TYPE_ADDR]) { memset(flash_fifo, 0xFF, 254); memcpy(flash_fifo, default_cfg_tbl, sizeof(default_cfg_tbl)); flash_fifo[iCFG_DATA_CS_ADDR] = checksum_flash(254, flash_fifo); flash_fifo[iCFG_DATA_TYPE_ADDR] = iCFG_DATA_TYPE_VALULE; flash_erase(iCFG_BANK); flash_write(iCFG_BANK_ADDR, 256); } memcpy(para_cfg_dat, flash_fifo, 5); memcpy(fire_led_dat, flash_fifo+8, 5); } extern bool bkey_mode_change; /******************************************************************************* * 函数名称: flash_save_mode_dpi() * 功能描述: * 输入参数: index * 输出参数: 无 * 明: *******************************************************************************/ void flash_save_status(void) { bool bflash_erase=false; uint8_t i, dat_temp[8]; dat_temp[0] = iSTATUS_DATA_TYPE; dat_temp[1] = report_dpi[0]; dat_temp[2] = report_dpi[1]; dat_temp[3] = report_dpi[2]; dat_temp[4] = report_dpi[3]; dat_temp[5] = (led_mode&0x0F); if(true == bled_bright_en) dat_temp[5] |= (1<<7); dat_temp[6] = (key_mode&0x03); dat_temp[6] |= ((bt_index<<2)&0x0C); dat_temp[6] |= ((device_type<<4)&0x70); dat_temp[7] = 0xFF; flash_read(iSTATUS_BANK_ADDR, 256); for(i=1; i<7; i++) { if(dat_temp[i] != flash_fifo[device_status_base + i]) { goto flash_save_device_status; } } return; flash_save_device_status: device_status_base = 0xF8; while(1) { for(i=0; i<7; i++) { if(0xFF != flash_fifo[device_status_base+i]) { goto device_status_null_bank; } } memcpy(flash_fifo, dat_temp, 8); flash_write(iSTATUS_BANK_ADDR+device_status_base, 8); if(true == bkey_mode_change) laod_flash_cfg(); else laod_mouse_status(); bkey_mode_change = false; return; device_status_null_bank: if(0x00 == device_status_base) { if(true == bflash_erase) return; bflash_erase = true; flash_erase(iFLASH_STATUS_BANK); goto flash_save_device_status; } device_status_base -= 8; } } /******************************************************************************* * 函数名称: flash_save_mode_dpi() * 功能描述: * 输入参数: index * 输出参数: 无 * 明: *******************************************************************************/ void flash_save_cfg_dpi(void) { bool bflash_erase=false; uint8_t i, dat_temp[16]; dat_temp[0] = iCFG_DPI_TYPE; dat_temp[1] = (led_light_lev&0x07); dat_temp[1] |= ((led_speed_lev<<4)&0x70); dat_temp[2] = (rgb_ctrl&0x07); dat_temp[3] = sleep_time_24g; dat_temp[4] = sleep_time_ble; dat_temp[5] = ((adv_cfg_value>>0)&0xFF); dat_temp[6] = ((adv_cfg_value>>8)&0xFF); dat_temp[7] = 0xFF; memcpy(dat_temp+8, dpi_value_tbl, 8); flash_read(iFLASH_CFG_DPI_ADDR, 256); for(i=1; i<16; i++) { if(dat_temp[i] != flash_fifo[cfg_dpi_base + i]) { goto flash_save_cfg_dpi; } } return; flash_save_cfg_dpi: cfg_dpi_base = 0xF0; while(1) { for(i=0; i<16; i++) { if(0xFF != flash_fifo[cfg_dpi_base+i]) { goto m_id_check_none_bank; } } memcpy(flash_fifo, dat_temp, 16); flash_write(iFLASH_CFG_DPI_ADDR+cfg_dpi_base, 16); laod_cfg_dpi(); return; m_id_check_none_bank: if(0x00 == cfg_dpi_base) { if(true == bflash_erase) return; bflash_erase = true; flash_erase(iFLASH_CFG_DPI_BANK); goto flash_save_cfg_dpi; } cfg_dpi_base -= 16; } } extern bool bble_conn_en; /******************************************************************************* * 函数名称: flash_save_mode_dpi() * 功能描述: * 输入参数: index * 输出参数: 无 * 明: *******************************************************************************/ void flash_load_ble_addr(void) { //---------------------------------------------- // 读取BLE ID // flash_read(iFLASH_BLE_ID_ADDR, 8); if(iBLE_ID_TPYE == flash_fifo[0]) { if(flash_fifo[7] == checksum_flash(7, flash_fifo)) { ble_id[0] = flash_fifo[iBLE_ID_0_INDEX]; ble_id[1] = flash_fifo[iBLE_ID_1_INDEX]; ble_id[2] = flash_fifo[iBLE_ID_2_INDEX]; return; } } flash_read(iFLASH_BLE_ID_ADDR_BAK_0, 8); if(iBLE_ID_TPYE == flash_fifo[0]) { if(flash_fifo[7] == checksum_flash(7, flash_fifo)) { ble_id[0] = flash_fifo[iBLE_ID_0_INDEX]; ble_id[1] = flash_fifo[iBLE_ID_1_INDEX]; ble_id[2] = flash_fifo[iBLE_ID_2_INDEX]; return; } } flash_read(iFLASH_BLE_ID_ADDR_BAK_1, 8); if(iBLE_ID_TPYE == flash_fifo[0]) { if(flash_fifo[7] == checksum_flash(7, flash_fifo)) { ble_id[0] = flash_fifo[iBLE_ID_0_INDEX]; ble_id[1] = flash_fifo[iBLE_ID_1_INDEX]; ble_id[2] = flash_fifo[iBLE_ID_2_INDEX]; return; } } flash_read(iFLASH_BLE_ID_ADDR_BAK_2, 8); if(iBLE_ID_TPYE == flash_fifo[0]) { if(flash_fifo[7] == checksum_flash(7, flash_fifo)) { ble_id[0] = flash_fifo[iBLE_ID_0_INDEX]; ble_id[1] = flash_fifo[iBLE_ID_1_INDEX]; ble_id[2] = flash_fifo[iBLE_ID_2_INDEX]; return; } } ble_id[0] = 0xFF; ble_id[1] = 0xFF; ble_id[2] = 0xFF; } /******************************************************************************* * 函数名称: flash_save_mode_dpi() * 功能描述: * 输入参数: index * 输出参数: 无 * 明: *******************************************************************************/ void flash_save_ble_addr(void) { if(iDEVICE_TYPE_BT2 < device_type) return; // 非BLE模式不存储ID memset(flash_fifo, 0xFF, 64); flash_fifo[0x00+0] = iBLE_ID_TPYE; flash_fifo[0x00+1] = ble_id[0]; flash_fifo[0x00+2] = ble_id[1]; flash_fifo[0x00+3] = ble_id[2]; flash_fifo[0x00+7] = checksum_flash(7, flash_fifo); flash_fifo[0x30+0] = iBLE_ID_TPYE; flash_fifo[0x30+1] = ble_id[0]; flash_fifo[0x30+2] = ble_id[1]; flash_fifo[0x30+3] = ble_id[2]; flash_fifo[0x30+7] = flash_fifo[7]; flash_erase(iFLASH_BLE_ID_BANK); flash_write_ble_addr(0x000); flash_erase(iFLASH_BLE_ID_BANK_BAK); flash_write_ble_addr(0x100); flash_load_ble_addr(); } 给代码打上完整详细注释,不修改原代码
最新发布
08-23
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值