#define _IN_NORPARAS_C #include "norparas.h" #if (MAX_PARA_BLOCK > 0) #include "norflash.h" #include "inout.h" #include "shell.h" #include "delay.h" //---------------------------------------------------- #define NORPARA_BEG_ADDR (SNF_PARAS_BEGIN) // 参数块起始地址,每个参数块占一个扇区,最大共16个参数块 #define NP_BLOCK_BYTES SNF_BYTES_PER_PAGE // 每个参数页大小(一页) #define NP_SAVE_BYTES_PER_BLOCK SNF_BYTES_PER_SEC // 每个参数块大小(一个扇区) #define NP_SAVE_BLOCKS_PER_SEC 16 // 每个参数块页数,第一页存储参数页有效标志,实际共15个页用于存储参数 #define GET_NORPARA_BLOCK_ADDR(bidx) (NORPARA_BEG_ADDR+(bidx)*NP_SAVE_BYTES_PER_BLOCK) // 获取参数块起始地址 //---------------------------------------------------- typedef struct { int paraEn; // 参数块有效标志 NorParaBlock norParaBlock; // 参数块数据 s32 * pParaList; // 参数列表(包含参数类型,最小最大值和默认值) char * pParasName; // 参数名称列表 // 存储 u32 pageFlag[NP_SAVE_BLOCKS_PER_SEC]; // 参数页标志 }NorParaBlockCtrl; NorParaBlockCtrl g_norParaBlockList[MAX_PARA_BLOCK]; //---------------------------------------------------- const char * SHOWP_STR = "\t" " 显示或加载参数 " "\r\n" "\t" " p1 p2" "\r\n" "\t" " 0 0 显示全部参数 " "\r\n" "\t" " b001 0 显示参数块b " "\r\n" "\t" " b002 0 参数块b加载默认参数 " "\r\n" "\t" " b003 0 参数块b重新加载参数 " "\r\n" ; void ShowPara(char * para1, char * para2); const char * SETP_STR = "\t" "设置参数 " "\r\n" "\t" " p1 p2" "\r\n" "\t" " b00x val 设置参数块b, 参数ID x, 参数值 val " "\r\n" "\t" " 10b000 0 保存参数块b " "\r\n" ; void SetPara(char * para1, char * para2); //---------------------------------------------------- void InitNorParas(void) { static int g_inited = 0; if (g_inited == 0) { g_inited = 1; InitNorSpi(); // 初始化 nor flash 访问 SPI SNFlashInit(SetNorSpiNssOn, SetNorSpiNssOff, NorSpiReadByte, NorSpiWriteByte); // 初始化nor flash 并注册读写函数 // 参数块初始化 for(int i = 0; i < MAX_PARA_BLOCK; i++) { memset(&g_norParaBlockList[i], 0, sizeof(NorParaBlockCtrl)); LoadNorParas(i); } AddShellCmd("SHOWPARA", SHOWP_STR, ShowPara); AddShellCmd("SETPARA", SETP_STR, SetPara); } } // 获取参数块有效标志 int GetNorParaEn(int bIdx) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return -1; } return g_norParaBlockList[bIdx].paraEn; } // 加载参数页有效标志 int LoadParaPageFlag(int bIdx) { NorParaBlockCtrl * pCtrl; if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return -1; } pCtrl = &g_norParaBlockList[bIdx]; return DatFlashRdData(GET_NORPARA_BLOCK_ADDR(bIdx), (u8 *)(&pCtrl->pageFlag[0]), NP_SAVE_BLOCKS_PER_SEC*sizeof(u32)); } // 保存参数页有效标志 int SaveParaPageFlag(int bIdx) { NorParaBlockCtrl * pCtrl; if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return -1; } pCtrl = &g_norParaBlockList[bIdx]; return DatFlashWrData(GET_NORPARA_BLOCK_ADDR(bIdx), (u8 *)(&pCtrl->pageFlag[0]), NP_SAVE_BLOCKS_PER_SEC*sizeof(u32)); } // 设置参数页有效标志 int SetParaPageFlagValue(int bIdx, int pIdx, int enFlag) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || pIdx < 0 || pIdx >= NP_SAVE_BLOCKS_PER_SEC) { return -1; } if (enFlag == 0) { g_norParaBlockList[bIdx].pageFlag[pIdx] = 0; // 失效,0xffffffff未使用页 } else { g_norParaBlockList[bIdx].pageFlag[pIdx] = PARA_VALID+pIdx; // 有效 } return 0; } // 从参数页标志得到当前有效参数页 int GetSaveIdxFromPageFlag(int bIdx) { int i; NorParaBlockCtrl * pCtrl; if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return -1; } pCtrl = &g_norParaBlockList[bIdx]; for(i = 1; i < NP_SAVE_BLOCKS_PER_SEC; i++) { if (pCtrl->pageFlag[i] == PARA_VALID+i) { return i; } } return -2; } // 得到下一个未使用页 int GetNextSaveIdxFromPageFlag(int bIdx) { int i; NorParaBlockCtrl * pCtrl; if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return -1; } pCtrl = &g_norParaBlockList[bIdx]; for (i = 1; i < NP_SAVE_BLOCKS_PER_SEC; i++) { if (pCtrl->pageFlag[i] == 0xffffffff) { return i; } } return -2; } // 读取参数 // bIdx:参数块ID // return: -1:参数加载错误,所有参数页都被废弃,未找到有效参数 // 0:正确返回值 int LoadNorParas(int bIdx) { u32 addr; // NorParaBlockCtrl * pCtrl; int idx, rslt; if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return -1; } pCtrl = &g_norParaBlockList[bIdx]; memset(pCtrl, 0, sizeof(NorParaBlockCtrl)); // 读入扇区存储参数有效标志 rslt = LoadParaPageFlag(bIdx); if (rslt < 0) { return -1; } idx = GetSaveIdxFromPageFlag(bIdx); // 得到当前有效参数页id if (idx < 0) { printf("load nor para error, code=%d\r\n", idx); return -1; } printf("load nor para block %d, page is %d\r\n", bIdx, idx); addr = GET_NORPARA_BLOCK_ADDR(bIdx) + (idx * NP_BLOCK_BYTES); DatFlashRdData(addr, (u8*)&pCtrl->norParaBlock, sizeof(NorParaBlock)); g_norParaBlockList[bIdx].paraEn = PARA_VALID; // 参数有效 return 0; } // 保存参数 //bIdx 定义的参数块ID int SaveNorParas(int bIdx) { u32 addr; int cidx, nidx; if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return -1; } cidx = GetSaveIdxFromPageFlag(bIdx); nidx = GetNextSaveIdxFromPageFlag(bIdx); if (cidx < 0) { cidx = 0; } if (nidx < 0) // 超出扇区 { printf("overflow, erase 4k\r\n"); DatFlash4kErase(GET_NORPARA_BLOCK_ADDR(bIdx), 1); // 擦除整个扇区 LoadParaPageFlag(bIdx); cidx = 0; nidx = GetNextSaveIdxFromPageFlag(bIdx); } if (nidx < 0) // { printf("SaveNorParas error\r\n"); return -2; } // 将参数存储在之后的页中 addr = GET_NORPARA_BLOCK_ADDR(bIdx) + ((nidx) * NP_BLOCK_BYTES); DatFlashWrDataWithErase(addr, (u8 *)&g_norParaBlockList[bIdx].norParaBlock, sizeof(NorParaBlock)); SetParaPageFlagValue(bIdx, nidx, 1); // 设置新参数存储页有效 SetParaPageFlagValue(bIdx, cidx, 0); // 废弃旧的参数存储页 SaveParaPageFlag(bIdx); // 保存参数页标志 g_norParaBlockList[bIdx].paraEn = PARA_VALID; // 参数有效 printf("save nor para successful, page is %d \r\n", nidx); return 0; } // 获取并返回参数块 NorParaBlock * GetNorParaBlock(int bIdx) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK) { return NULL; } return &g_norParaBlockList[bIdx].norParaBlock; } // 设置参数名称 void SetNorParaNameString(int bIdx, void * pName) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK ) { return; } g_norParaBlockList[bIdx].pParasName = pName; } // 设置参数列表(参数类型,最小最大值默认值) void SetNorParaList(int bIdx, void * pPara) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK ) { return; } g_norParaBlockList[bIdx].pParaList = pPara; } // 加载默认参数 void LoadNorDefPara(int bIdx) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || g_norParaBlockList[bIdx].pParaList == NULL) { return; } for(int i = 0; i < PARA_NUM_PER_BLK; i++) { int offset = i * 4 + 3; g_norParaBlockList[bIdx].norParaBlock.buff[i] = * ( g_norParaBlockList[bIdx].pParaList + offset ); } } // 参数范围检测(检测参数块内的全部参数) void CheckParaRange(int bIdx) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || g_norParaBlockList[bIdx].pParaList == NULL) { return; } for(int i = 0; i < PARA_NUM_PER_BLK; i++) { int paratype, minOffset, maxOffset; // 参数类型,最小最大值指针偏移量 paratype = (i * 4); minOffset = (i * 4 + 1); maxOffset = (i * 4 + 2); if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_S) { if (g_norParaBlockList[bIdx].norParaBlock.buff[i] < (*(g_norParaBlockList[bIdx].pParaList + minOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + minOffset)); printf("less than min, equal min, block %d, id is %d\r\n", bIdx, i+1); } else if (g_norParaBlockList[bIdx].norParaBlock.buff[i] > (*( g_norParaBlockList[bIdx].pParaList + maxOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset)); printf("more than max, equal max, block %d, id is %d\r\n", bIdx, i+1); } } else if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_U) { if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[i] < (u32)(*(g_norParaBlockList[bIdx].pParaList + minOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + minOffset)); printf("less than min, equal min, block %d, id is %d\r\n", bIdx, i+1); } else if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[i] > (u32)(*( g_norParaBlockList[bIdx].pParaList + maxOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[i] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset)); printf("more than max, equal max, block %d, id is %d\r\n", bIdx, i+1); } } } } // 参数范围检测(检测参数块内的某个参数) void CheckAParaRange(int bIdx, int id) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK || g_norParaBlockList[bIdx].pParaList == NULL) { return; } if (id >= 0 && id < PARA_NUM_PER_BLK) { int paratype, minOffset, maxOffset; // 参数类型,最小最大值指针偏移量 paratype = (id * 4); minOffset = (id * 4 + 1); maxOffset = (id * 4 + 2); if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_S) { if (g_norParaBlockList[bIdx].norParaBlock.buff[id] < (*( g_norParaBlockList[bIdx].pParaList + minOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + minOffset)); printf("less than min, equal min\r\n"); } else if (g_norParaBlockList[bIdx].norParaBlock.buff[id] > (*( g_norParaBlockList[bIdx].pParaList + maxOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset)); printf("more than max, equal max\r\n"); } } else if ((*(g_norParaBlockList[bIdx].pParaList + paratype)) == PTYPE_U) { if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[id] < (u32)(*( g_norParaBlockList[bIdx].pParaList + minOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + minOffset)); printf("less than min, equal min\r\n"); } else if ((u32)g_norParaBlockList[bIdx].norParaBlock.buff[id] > (u32)(*( g_norParaBlockList[bIdx].pParaList + maxOffset)) ) { g_norParaBlockList[bIdx].norParaBlock.buff[id] = (*( g_norParaBlockList[bIdx].pParaList + maxOffset)); printf("more than max, equal max\r\n"); } } } } // 获取一个参数 s32 GetANorPara(int bIdx, int id) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK ) { return -1; } if (GetNorParaEn(bIdx) == PARA_VALID) { int idx = id - 1; if (idx >= 0 && idx < PARA_NUM_PER_BLK) { return g_norParaBlockList[bIdx].norParaBlock.buff[idx]; } } return 0; } // 设置一个参数 // 该函数不提供保存功能,需参数设置完成后手动保存 // 注:norflash不宜频繁写 void SetANorPara(int bIdx, int id, s32 val) { if (bIdx < 0 || bIdx >= MAX_PARA_BLOCK ) { return; } char * pInfo = NULL; int idx = id - 1; if (idx >= 0 && idx < PARA_NUM_PER_BLK) { if ((*(g_norParaBlockList[bIdx].pParaList + idx*4)) == PTYPE_S) { s32 old; pInfo = (g_norParaBlockList[bIdx].pParasName+(idx)*PARA_STR_LEN); printf("set para block %d\r\n", bIdx+1); old = g_norParaBlockList[bIdx].norParaBlock.buff[idx]; g_norParaBlockList[bIdx].norParaBlock.buff[idx] = val; CheckAParaRange(bIdx, idx); if (pInfo == NULL) { pInfo = ""; } printf("%d. (%s) = %d, oldvalue=%d\r\n", (id), pInfo, val, old); } else { u32 old; pInfo = (g_norParaBlockList[bIdx].pParasName+(idx)*PARA_STR_LEN); printf("set para block %d\r\n", bIdx+1); old = (u32)g_norParaBlockList[bIdx].norParaBlock.buff[idx]; g_norParaBlockList[bIdx].norParaBlock.buff[idx] = val; CheckAParaRange(bIdx, idx); if (pInfo == NULL) { pInfo = ""; } printf("%d. (%s) = %d, oldvalue=%d\r\n", (id), pInfo, (u32)val, old); } } } /* * p1 p2 * 1001 val // 设置参数块1,参数ID 1,参数值val * 1002 val // 设置参数块1,参数ID 2,参数值val ...... * 2001 val // 设置参数块2,参数ID 1,参数值val * 2002 val // 设置参数块2,参数ID 2,参数值val //不提供保存功能 ...... * 101000 // 保存参数块1 * 102000 // 保存参数块2 */ void SetPara(char * para1, char * para2) { int p1, p2, p3; if (para1 == NULL || para2 == NULL) { return; } printf("para1=%s, para2=%s\r\n", para1, para2); p1 = 0; p2 = 0; if (strcmp(para1, "") != 0) { p1 = atoi(para1); } if (strcmp(para2, "") != 0) { p2 = atoi(para2); } if (p1 == p2) { } p3 = p1 / 1000; // 参数块id p1 = p1 % 1000; // 参数id // p2:参数值 if (p3 > 0 && p3 <= MAX_PARA_BLOCK) { SetANorPara(p3-1, p1, p2); } else if (p3 > 100 && p3 <= 116) { p3 -= 101; printf("save block %d\r\n", p3+1); SaveNorParas(p3); } } /* * p1 p2 * // 显示全部参数 * 1001 // 显示参数块1 * 2001 // 显示参数块2 * 1002 // 参数块1加载默认参数 * 2002 // 参数块2加载默认参数 * 1003 // 参数块1重新加载参数 * 2003 // 参数块2重新加载参数 */ void ShowPara(char * para1, char * para2) { int p1, p2, p3; if (para1 == NULL || para2 == NULL) { return; } printf("para1=%s, para2=%s\r\n", para1, para2); p1 = 0; p2 = 0; if (strcmp(para1, "") != 0) { p1 = atoi(para1); } if (strcmp(para2, "") != 0) { p2 = atoi(para2); } if (p1 == p2) { } p3 = p1 / 1000; // 参数块id p1 = p1 % 1000; // 功能码 // p2: 参数ID if (p3 <= MAX_PARA_BLOCK) { switch(p1) { case 0: { // 显示全部块参数 for (int j = 0; j < MAX_PARA_BLOCK; j++) { printf("\r\npara block %d:\r\n", j+1); if (g_norParaBlockList[j].pParasName == NULL) { continue; } for(int i = 0; i < PARA_NUM_PER_BLK; i++) { char * pStr; pStr = g_norParaBlockList[j].pParasName + (i*PARA_STR_LEN); if (pStr == NULL) { pStr = ""; } if ( strcmp(pStr, "") != 0 ) { if ((*(g_norParaBlockList[j].pParaList+i*4)) == PTYPE_S) { printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr, GetANorPara(j, i+1), *(g_norParaBlockList[j].pParaList+ i*4+1), *(g_norParaBlockList[j].pParaList+ i*4+2), *(g_norParaBlockList[j].pParaList+ i*4+3) ); } else { printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr, (u32)GetANorPara(j, i+1), (u32)(*(g_norParaBlockList[j].pParaList+ i*4+1)), (u32)(*(g_norParaBlockList[j].pParaList+ i*4+2)), (u32)(*(g_norParaBlockList[j].pParaList+ i*4+3)) ); } } DelayMs(1); } } break; } case 1: { // 显示某个参数块 printf("\r\npara block %d:\r\n", p3); if (g_norParaBlockList[p3-1].pParasName != NULL) { for(int i = 0; i < PARA_NUM_PER_BLK; i++) { char * pStr; pStr = g_norParaBlockList[p3-1].pParasName + (i*PARA_STR_LEN); if (pStr == NULL) { pStr = ""; } if ( strcmp(pStr, "") != 0 ) { if ((*(g_norParaBlockList[j].pParaList+i*4)) == PTYPE_S) { printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr, GetANorPara(p3-1, i+1), *(g_norParaBlockList[p3-1].pParaList+ i*4+1), *(g_norParaBlockList[p3-1].pParaList+ i*4+2), *(g_norParaBlockList[p3-1].pParaList+ i*4+3) ); } else { printf("%d. (%s) val=%d, min=%d, max=%d, def=%d\r\n", i+1, pStr, (u32)GetANorPara(p3-1, i+1), (u32)(*(g_norParaBlockList[p3-1].pParaList+ i*4+1)), (u32)(*(g_norParaBlockList[p3-1].pParaList+ i*4+2)), (u32)(*(g_norParaBlockList[p3-1].pParaList+ i*4+3)) ); } } DelayMs(1); } } break; } case 2: { int bidx = p3 - 1; // 加载默认参数 if (bidx >= 0) { printf("load def para block %d:\r\n", p3); LoadNorDefPara(bidx); } break; } case 3: { int bidx = p3 - 1; if (bidx >= 0) { printf("load para block %d:\r\n", p3); // 重新加载参数 LoadNorParas(bidx); } break; } default: break; } } } #endif