Linux进程间通信-杂项设备驱动buf共享的方式

2024-02-08 03:59

本文主要是介绍Linux进程间通信-杂项设备驱动buf共享的方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、前言

本文所介绍的内容主要是为了对cgi设置项管理项杂乱而优化的。本文中的实例是将设置项写入驱动中,支持多个进程共享。在开机初始化进入应用层=的时候需要把保存在/config/settings.txt文件中的设置项全部读出来,然后在写入到杂项设备驱动中,杂项设备中有一个全局数据buf用来保存这些设置项,这是初始化必须要做的。除此之外,当是首次使用的时候config/settings.txt文件是没有数据的,要先把应用层保存的设置项数组数据写入到文件中,才可以使用。此时驱动文件当用户对设置项进行变化的时候会将变化的数据写入到驱动中,这个时候应用层是没有保存的,因为应用层只有一个出厂设置的设置项数组,所以当用户要保存设置项的时候是先把驱动中的设置项数据读取出来,然后设置项数据会跟校验值一起写入进去,然后写入到/config/settings.txt文件中保存起来,当读取文件的设置项的校验值与实际保存的校验值不对应应的时候就应该读取另一个分区的内容在校验,如果这个分区的数据还是校验不过,就会恢复出厂设置。/config是单独分区,没有加写保护。当然可以做备份,即把/config/settings.txt备份到另一个分区上。

CRC8(循环冗余校验)的文章请参考下面这一篇文章:

CRC校验原理及代码实现_crc校验代码-CSDN博客

回到本文,本文中由于涉及多进程对驱动中的buf数据进行读写,所以需要做好进程间同步,这里使用的是信号量进行进程间的同步。

2、Linux内核信号量semaphore

Linux内核提供了若干函数用于操作信号量,例如:

sema_init(): 初始化一个新的信号量,并设置初始计数器值。
down(): 尝试获取信号量。如果信号量计数器大于0,则将其减1并返回0;否则,当前进程或线程将被阻塞,直到有其他进程或线程释放了资源。
up(): 释放信号量,并将其计数器加1。如果有任何进程或线程在等待信号量,则唤醒其中一个进程或线程。
在Linux内核中,信号量机制是用于实现各种同步原语的基础。例如,读写锁、自旋锁等都是基于信号量机制实现的。另外,Linux内核还提供了一些高级的同步原语,例如spinlock和mutex等,它们通常也使用了信号量机制作为底层实现。

3、Linux内核中添加一个杂项设备驱动

有关如何在Linux内核中添加驱动可以参考这篇:

Linux下把驱动编译进内核及图形化配置的方式进行选择_suifen_的博客-CSDN博客

3.1在kernel/drivers/lte新建这些文件

3.2修改kernel/drivers/makefile

3.3添加kernel/drivers/lte/Kconfig

menuconfig LTE_DRIVERSbool "lte drivers"default y

3.4添加kernel/drivers/lte/makefile

obj-y				+= lte_misc/

3.5添加kernel/drivers/lte/lte_misc/lte_misc.c

#include <linux/kernel.h>
#include <linux/fcntl.h>
#ifndef __LITEOS__
#include <linux/version.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/poll.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#else
#include "asm-generic/ioctl.h"
#include <i2c.h>
#endif
#include<linux/seq_file.h>
#include<linux/lte.h>/*===========================================================================* Global varible
*===========================================================================*/
#define PROC_LTE "lte"#include "settings.c"#define IOC_SET_KEY_NUMS		_IOW('S', 0x01, char)
#define IOC_GET_KEY_NUMS		_IOR('S', 0x02, char)
#define IOC_GET_KEY_VAL  		_IOR('S', 0x03, LTEENTRY)
#define IOC_GET_KEY_VAL_EX  	_IOR('S', 0x04, LTEENTRY_EX)
#define IOC_SET_KEY_VAL			_IOW('S', 0x05, LTEENTRY)
#define IOC_GET_POS_VAL			_IOR('S', 0x06, LTEENTRY)
#define IOC_DEL_KEY				_IOW('S', 0x07, LTEENTRY)
#define IOC_DEL_KEY_BYPOS		_IOW('S', 0x08, char)
#define IOC_GET_CHANGED_FLAG	_IOR('S', 0x09, char)
#define IOC_CLR_CHANGED_FLAG	_IOR('S', 0x0A, char)#define IOC_REQ_PWROFFSRC		_IOW('S', 0x011, LTE_POWEROFF_RES)
#define IOC_REL_PWROFFSRC		_IOW('S', 0x012, LTE_POWEROFF_RES)#define SET_KYE_BUFFER_SIZE     1024struct semaphore lte_lock;int CutoffChar(char *str, char c)
{int i = 0;int n = strlen(str);for (i=0; i<n; i++) {if (str[i] == c) {str[i] = 0;return i;}}return 0;
}
unsigned int lte_strtoint(const char *str)
{unsigned int temp=0;unsigned int fact=1;unsigned char len=strlen(str);unsigned char i;for(i=len;i>0;i--){temp+=((str[i-1]-0x30)*fact);fact*=10;}return temp;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++
static LTE_POWEROFF_RES g_ePwrOffRes=LTE_POWEROFF_RES_NULL;
LTE_POWEROFF_RES LteSetPowerOffRes(LTE_POWEROFF_RES ePwroffRes)
{down(&lte_lock);g_ePwrOffRes |= ePwroffRes;up(&lte_lock);return g_ePwrOffRes;
}
LTE_POWEROFF_RES LteClrPowerOffRes(LTE_POWEROFF_RES ePwroffRes)
{down(&lte_lock);g_ePwrOffRes &= (~ePwroffRes);up(&lte_lock);return g_ePwrOffRes;
}
LTE_POWEROFF_RES LteIsPowerOffRes(LTE_POWEROFF_RES ePwroffRes)
{return g_ePwrOffRes & ePwroffRes;
}
LTE_POWEROFF_RES LteGetPowerOffRes(void)
{return g_ePwrOffRes;
}
EXPORT_SYMBOL_GPL(LteSetPowerOffRes);
EXPORT_SYMBOL_GPL(LteClrPowerOffRes);
EXPORT_SYMBOL_GPL(LteIsPowerOffRes);
EXPORT_SYMBOL_GPL(LteGetPowerOffRes);
void RequestPwrOffSrc(LTE_POWEROFF_RES res)
{LteSetPowerOffRes(res);
}
void ReleasePwrOffSrc(LTE_POWEROFF_RES res)
{LteClrPowerOffRes(res);
}//-------------------------------------------------------
static long lte_ioctl(struct file* filp, unsigned int cmd, unsigned long args)
{int ret = 0;LTEENTRY entry;LTEENTRY_EX entryEx;char pVal[SET_KYE_BUFFER_SIZE] = {0};unsigned char nums;LTE_POWEROFF_RES res;switch (cmd){case IOC_REQ_PWROFFSRC:if(args){if (copy_from_user(&res, (void __user * )args, sizeof(res)) > 0)return -EFAULT;elseRequestPwrOffSrc(res);}elsereturn -EFAULT;break;case IOC_REL_PWROFFSRC:if(args){if (copy_from_user(&res, (void __user * )args, sizeof(res)) > 0)return -EFAULT;elseReleasePwrOffSrc(res);}elsereturn -EFAULT;break;case IOC_GET_KEY_VAL:case IOC_GET_KEY_VAL_EX:if(args){if (copy_from_user(&entryEx, (void __user * )args, sizeof(entryEx)) > 0){printk("copy key to Kernel failed!\n");return -EFAULT;}if(entryEx.len > (SET_KYE_BUFFER_SIZE))  //不超过SET_KYE_BUFFER_SIZE{printk("settings: entryEx.len must <= SET_KYE_BUFFER_SIZE\n");return -EFAULT;}down(&lte_lock);ret = GetKeyVal(entryEx.pval, pVal, entryEx.len);up(&lte_lock);if(ret){printk("settings: Get pVal failed!!!!\n");return ret;}//printk("settings: \n GetKeyVal %s=%s!!!!\n", entryEx.pval, pVal);pVal[entryEx.len-1] = 0;if (copy_to_user((void __user * )args, &pVal, entryEx.len) > 0){printk("settings: Copy pVal to user failed!!!!\n");return -EFAULT;}}elsereturn -EFAULT;break;case IOC_SET_KEY_VAL: if(args){if (copy_from_user(&entry, (void __user * )args, sizeof(entry)) > 0){	printk("Copy entry failed!!!!\n");return -EFAULT;}printk("settings: AddEntry %s=%s!\n", entry.pkey, entry.pval);down(&lte_lock);ret = AddEntry(entry.pkey, entry.pval);up(&lte_lock);if(ret){printk("settings: AddEntry failed!!!!\n");return ret;}}elsereturn -EFAULT;break;case IOC_GET_POS_VAL:if(args){if (copy_from_user(&entry, (void __user * )args, sizeof(entry)) > 0){printk("IOC_GET_POS_VAL Copy args failed!!!!\n");ret = -EFAULT;break;}down(&lte_lock);ret = GetKeyValByPos(&entry);up(&lte_lock);if(ret)return ret;if (copy_to_user((void __user * )args, &entry, sizeof(entry)) > 0){printk("IOC_GET_POS_VAL Copy entry failed!!!!\n");return -EFAULT;}}elsereturn -EFAULT;break;case IOC_SET_KEY_NUMS:if(args){if (copy_from_user(&nums, (void __user * )args, sizeof(nums)) > 0)return -EFAULT;down(&lte_lock);ret = SetEntryNums(nums);up(&lte_lock);}elsereturn -EFAULT;break;case IOC_GET_KEY_NUMS:if(args){down(&lte_lock);ret = GetEntryNums(&nums);up(&lte_lock);if(ret == 0){if (copy_to_user((void __user * )args, &nums, sizeof(nums)) > 0)return -EFAULT;}}elsereturn -EFAULT;break;case IOC_DEL_KEY:if(args){if (copy_from_user(&entry, (void __user * )args, sizeof(entry)) > 0)return -EFAULT;down(&lte_lock);ret = DelEntry(entry.pkey, entry.pval);up(&lte_lock);}else return -EFAULT;break;case IOC_DEL_KEY_BYPOS:if(args){if (copy_from_user(&nums, (void __user * )args, sizeof(nums)) > 0)return -EFAULT;down(&lte_lock);ret = DelEntryByPos(nums);up(&lte_lock);}elsereturn -EFAULT;break;case IOC_GET_CHANGED_FLAG:if(args){down(&lte_lock);nums = IsSettingsChanged();up(&lte_lock);//if(ret == 0){if (copy_to_user((void __user * )args, &nums, sizeof(nums)) > 0)return -EFAULT;}}elsereturn -EFAULT;break;case IOC_CLR_CHANGED_FLAG:down(&lte_lock);CleanSettingsChangedFlag();up(&lte_lock);break;default:break;}return ret;
}
static int lte_open(struct inode* inode, struct file* filp)
{return 0;
}
static int lte_close(struct inode* inode, struct file* filp)
{return 0;
}
static ssize_t lte_read(struct file *filp, char __user *buf,size_t count, loff_t *f_pos)
{	return count;
}
static ssize_t lte_write(struct file *filp, const char __user *buf,size_t count, loff_t *f_pos)
{int ret=0;char str[65]={0};char* pTmp=NULL;char* pVal = str;char strcmd[32]={0};char strval[32]={0};unsigned int val = 0;//            cmd     val//eg. echo "REQ_PWROFF_SRC=POWERKEY" > /dev/lte//eg. echo "TIME=#100" > /dev/lte#define MIN(a,b) ((a) < (b) ? (a) : (b))ret = copy_from_user(&str, (void __user*)buf, MIN(count, 64));str[64] = 0;CutoffChar(pVal, '\r');CutoffChar(pVal, '\n');CutoffChar(pVal, ' ');pTmp = strchr(str, '=');if(pTmp) *pTmp = 0;else {printk("lte_write: cmd str error! (%s)\r\n", str);return count;		}strcpy(strcmd, str);pTmp = pTmp+1;strcpy(strval, pTmp);if(pTmp[0] == '#'){pTmp = pTmp+1;strcpy(strval, pTmp);ret = kstrtoint(strval, 10, &val);if(val<0 || val > 0xFFFF){printk("lte_write: val error! (%d)\r\n", val);return count;		}}elseret = kstrtoint(strval, 10, &val);printk("lte_write %s=%s (%d)\r\n", strcmd, strval, val);if(strcmp(str, "REQ_PWROFF_SRC") == 0)RequestPwrOffSrc(val);else if(strcmp(str, "REL_PWROFF_SRC") == 0)ReleasePwrOffSrc(val);return count;
}
static struct file_operations lte_fops = {.owner      = THIS_MODULE,.unlocked_ioctl = lte_ioctl,.open       = lte_open,.release    = lte_close,.read		= lte_read,.write		= lte_write
};
static struct miscdevice lte_dev = {.minor       = MISC_DYNAMIC_MINOR,.name        = "lte",.fops        = &lte_fops,
};static int lte_proc_show(struct seq_file *m, void *v)
{seq_printf(m, "PwrOffSrc=0x%x\n""end", LteGetPowerOffRes());return 0;
}static int lte_proc_open(struct inode *inode, struct file *file)
{return single_open(file, lte_proc_show, NULL);
}static struct file_operations lte_proc_fops = {.owner	= THIS_MODULE,.open	= lte_proc_open,.release= single_release,.read	= seq_read,.llseek	= seq_lseek,.write	= NULL,
};static void init_proc_file(void)
{struct proc_dir_entry *proc_lte_entry;proc_lte_entry = proc_create(PROC_LTE, 0, NULL, &lte_proc_fops);if (!proc_lte_entry) {pr_err("%s: failed to create proc file %s\n", __func__, PROC_LTE);return ;}
}static int __init lte_init(void)
{int ret;sema_init(&lte_lock, 1);ret = misc_register(&lte_dev);if(ret<0){printk("lte_dev_register fail!\n");return -1;}else{init_proc_file();LteSettingsInit();printk("lte_dev_register ok!\n");}return 0;
}void __exit lte_exit(void)
{LteSettingsDeInit();printk("lte driver: exit\n");
}module_init(lte_init);
module_exit(lte_exit);
MODULE_AUTHOR("lte");
MODULE_DESCRIPTION("lte driver");
MODULE_LICENSE("GPL");

3.6添加kernel/drivers/lte/lte_misc/setting.c

#include<linux/fs.h>
#include<linux/string.h>
#include<linux/syscalls.h>#define SETTINGS_END_STR	";;END"
#define MAX_SETTINGS_ENRTY_NUMS		250#define SETTINGS_ENTRY_ARROW_SIZE		48typedef struct _lte_entryEx {int len;char pval[SETTINGS_ENTRY_ARROW_SIZE];
} LTEENTRY_EX,*PLTEENTRY_EX;typedef struct _lte_entry {char pkey[SETTINGS_ENTRY_ARROW_SIZE];char pval[SETTINGS_ENTRY_ARROW_SIZE];
} LTEENTRY,*PLTEENTRY;unsigned char g_EntryNums = 0;
LTEENTRY* g_Entrys[MAX_SETTINGS_ENRTY_NUMS] = {0};
unsigned char g_SettingsChangedFlag = 0;int IsSameString(char* src, char* dst)
{if((strncasecmp(src, dst, strlen(dst)) == 0) && (strlen(src)==strlen(dst)))return 1;return 0;
}int DelEntry(char* pKey, char* pVal)
{	int i = 0;if(!pKey)return -1;if(g_EntryNums == 0)return -2;for(i=0; i<g_EntryNums; i++){if(g_Entrys[i] == NULL)continue;if(IsSameString(g_Entrys[i]->pkey, pKey)){memset(g_Entrys[i]->pkey, 0, (SETTINGS_ENTRY_ARROW_SIZE));memset(g_Entrys[i]->pval, 0, (SETTINGS_ENTRY_ARROW_SIZE));g_SettingsChangedFlag = 1;return 0;}}return -2;
}
int DelEntryByPos(unsigned char pos)
{	if(g_EntryNums == 0)return -2;if(pos >= g_EntryNums)return -2;if(g_Entrys[pos] == NULL)return -3;memset(g_Entrys[pos]->pkey, 0, (SETTINGS_ENTRY_ARROW_SIZE));memset(g_Entrys[pos]->pval, 0, (SETTINGS_ENTRY_ARROW_SIZE));g_SettingsChangedFlag = 1;return 0;
}int AddEntry(char* pKey, char* pVal)
{	int i = 0;int iFirstEmptyPos = MAX_SETTINGS_ENRTY_NUMS;int iSeted = 0;if(!pKey || !pVal){printk("settings: ERR AddEntry  !pKey || !pVal !!!!!!\n");return -1;}if(g_EntryNums == 0){printk("settings: ERR AddEntry  g_EntryNums == 0 !!!!!!\n");return -2;}if(pKey[0]==';'||pVal[0]==';'){printk("settings: AddEntry ERR  add key end !!!!!!\n");return 0;}for(i=0; i<g_EntryNums; i++){if(g_Entrys[i] == NULL){continue;}if(g_Entrys[i]->pkey[0] == 0 && iFirstEmptyPos == MAX_SETTINGS_ENRTY_NUMS){iFirstEmptyPos = i;//break;}if(IsSameString(g_Entrys[i]->pkey, pKey)){iSeted = 1;if(!IsSameString(g_Entrys[i]->pval, pVal)){strncpy(g_Entrys[i]->pval, pVal, SETTINGS_ENTRY_ARROW_SIZE-1);g_Entrys[i]->pval[SETTINGS_ENTRY_ARROW_SIZE-1] = '\0';printk("settings: AddEntry replace [%d]:%s=%s [%s]\n", i, g_Entrys[i]->pkey, g_Entrys[i]->pval, pVal);g_SettingsChangedFlag = 1;}break;}}if(!iSeted){if(iFirstEmptyPos < MAX_SETTINGS_ENRTY_NUMS){strncpy(g_Entrys[iFirstEmptyPos]->pkey, pKey, SETTINGS_ENTRY_ARROW_SIZE-1);strncpy(g_Entrys[iFirstEmptyPos]->pval, pVal, SETTINGS_ENTRY_ARROW_SIZE-1);g_Entrys[iFirstEmptyPos]->pkey[SETTINGS_ENTRY_ARROW_SIZE-1]='\0';g_Entrys[iFirstEmptyPos]->pval[SETTINGS_ENTRY_ARROW_SIZE-1]='\0';iSeted = 1;g_SettingsChangedFlag = 1;printk("settings: AddEntry add [%d]:%s=%s\n", iFirstEmptyPos, g_Entrys[iFirstEmptyPos]->pkey, g_Entrys[iFirstEmptyPos]->pval);}}if(!iSeted) {printk("settings: ERR AddEntry  pKey %s, iFirstEmptyPos %d, i = %d\n",pKey,iFirstEmptyPos,i);return -2;}return 0;
}
int GetKeyVal(char* pKey, char* pVal, int len)
{	int i = 0;int bMult = 0;char tmp[156];if(!pKey || !pVal){	printk("settings: ERR GetKeyVal pKey or pVal invalid  !!\n");return -1;}if(strchr(pKey, '*'))bMult = 1;if(g_EntryNums == 0){	printk("settings: ERR GetKeyVal   g_EntryNums == 0!!\n");return -2;}memset(pVal, 0, len);for(i=0; i<g_EntryNums; i++){if(g_Entrys[i] == NULL)continue;if(bMult){if(strncasecmp(g_Entrys[i]->pkey, pKey, strlen(pKey)-1) == 0){sprintf(tmp, "%s=%s\n", g_Entrys[i]->pkey, g_Entrys[i]->pval);if(strlen(pVal)+strlen(tmp) < len){strcat(pVal, tmp);continue;}elsereturn -3;}if(g_Entrys[i]->pkey[0]==0)return 0;}else{if(IsSameString(g_Entrys[i]->pkey, pKey)){strncpy(pVal, g_Entrys[i]->pval, len);return 0;}}}printk("settings: GetKeyVal : %s=%s\n",pKey, pVal);return -4;
}int GetKeyValByPos(LTEENTRY* pEntry)
{	int pos = 0;if(!pEntry)return -1;if(g_EntryNums == 0)return -2;pos = pEntry->pkey[0];if(pos >= g_EntryNums)return -2;if(g_Entrys[pos] == NULL)return -3;if(g_Entrys[pos]->pkey[0] == 0)return -4;memset(pEntry, 0, sizeof(LTEENTRY));strncpy(pEntry->pkey, g_Entrys[pos]->pkey, SETTINGS_ENTRY_ARROW_SIZE-1);strncpy(pEntry->pval, g_Entrys[pos]->pval, SETTINGS_ENTRY_ARROW_SIZE-1);pEntry->pkey[SETTINGS_ENTRY_ARROW_SIZE-1] = '0';	pEntry->pval[SETTINGS_ENTRY_ARROW_SIZE-1] = '0';printk("settings: GetKeyValByPos[%d]:%s=%s\n", pos, pEntry->pkey, pEntry->pval);return 0;
}int SetEntryNums(unsigned char nums)
{int i = 0;if(nums > MAX_SETTINGS_ENRTY_NUMS)return -1;if(nums == 0)return -2;g_EntryNums = nums;for(i=0; i<g_EntryNums; i++){if(g_Entrys[i])continue;g_Entrys[i] = (LTEENTRY*)vmalloc(sizeof(LTEENTRY));if(g_Entrys[i] == NULL)return -2;elseg_Entrys[i]->pkey[0] = 0;}return 0;
}int GetEntryNums(unsigned char* pnums)
{if(g_EntryNums > MAX_SETTINGS_ENRTY_NUMS)return -1;if(!pnums)return -2;*pnums = g_EntryNums;return 0;
}void LteSettingsInit(void)
{int i = 0;for(i=0; i<MAX_SETTINGS_ENRTY_NUMS; i++){g_Entrys[i] = NULL;}
}void LteSettingsDeInit(void)
{int i = 0;for(i=0; i<MAX_SETTINGS_ENRTY_NUMS; i++){if(g_Entrys[i]){vfree(g_Entrys[i]);g_Entrys[i] = NULL;}}
}unsigned char IsSettingsChanged(void)
{return g_SettingsChangedFlag;
}void CleanSettingsChangedFlag(void)
{g_SettingsChangedFlag = 0;
}

3.7添加kernel/drivers/lte/lte_misc/makefile

obj-m += lte_misc.o

4、在应用层中添加数据加载至驱动以及从驱动中读取数据的接口 

4.1应用层添加Setting.cpp

#include "Hal.h"#ifdef SET_NO_MTD  		//set工具 暂时不支持备份到MTD
#if BACKUP_SETTNIGS_TOSD
#define SETTINGS_ABCKUP_EN  1   //没有MTD但是备份到SD卡
#else
#define SETTINGS_ABCKUP_EN  0	//没有MTD而且备份到MTD
#endif
#else
#define SETTINGS_ABCKUP_EN  1
#endif#define SETTINGS_END_STR			";;END"
#define MAX_SETTINGS_ENRTY_NUMS		250			//最多250个设置项#define IOC_SET_KEY_NUMS		_IOW('S', 0x01, char)
#define IOC_GET_KEY_NUMS		_IOR('S', 0x02, char)
#define IOC_GET_KEY_VAL  		_IOR('S', 0x03, ENTRY)
#define IOC_GET_KEY_VAL_EX  	_IOR('S', 0x04, ENTRY_EX)
#define IOC_SET_KEY_VAL			_IOW('S', 0x05, ENTRY)
#define IOC_GET_POS_VAL			_IOR('S', 0x06, ENTRY)
#define IOC_DEL_KEY				_IOW('S', 0x07, ENTRY)
#define IOC_DEL_KEY_BYPOS		_IOW('S', 0x08, char)
#define IOC_GET_CHANGED_FLAG	_IOR('S', 0x09, char)
#define IOC_CLR_CHANGED_FLAG	_IOR('S', 0x0A, char)#define IOC_REQ_PWROFFSRC		_IOW('S', 0x011, POWEROFF_RES)
#define IOC_REL_PWROFFSRC		_IOW('S', 0x012, POWEROFF_RES)#define IOC_MMC1_RESCAN			_IOW('S', 0x080, char)static unsigned char s_nums = 0;
static int s_SettingsDriverFd = -1;
static NVHDR s_NvHdr = {0};static pthread_mutex_t s_SettingsMutex=PTHREAD_MUTEX_INITIALIZER;#if HIS_WEB
static ENTRY s_DefEnters[] = {{COMMON_KEY_SETTINGS_VERSION, 			COMMON_VAL_SETTINGS_VERSION}, //设置版本号{COMMON_KEY_MOVIE_SIZE, 				RES_STR_2K},{COMMON_KEY_VIDEO_CLIP_TIME, 			STR_LEV_TIME_1MIN},{COMMON_KEY_RECD_SOUND, 				STR_LEV_SETTINGS_ON},{COMMON_KEY_TIMELAPSE, 					STR_LEV_SETTINGS_OFF},{COMMON_KEY_PARK_TIMELAPSE,				STR_LEV_SETTINGS_OFF},{COMMON_KEY_WDR_EN, 					STR_LEV_SETTINGS_ON},{COMMON_KEY_PARK_TYPE, 					STR_LEV_SETTINGS_OFF},{COMMON_KEY_BOOTSOUND,					STR_LEV_SETTINGS_ON},{COMMON_KEY_BEEP,						STR_LEV_SETTINGS_ON},{COMMON_KEY_DATETIME_FMT, 				STR_LEV_DATETIME_YMD},{COMMON_KEY_STICKER_EN,					STR_LEV_TIME_STAMP_DL},{COMMON_KEY_LANGUAGE,					STR_ID_LANGUAGE_ENGLISH}, {COMMON_KEY_FLICKER,					STR_LEV_FLICKER_60HZ},{COMMON_KEY_LCD_POWERS,					STR_LEV_TIME_OFF},{COMMON_KEY_GSENSOR_SENS,				STR_LEV_SETTINGS_MID},{COMMON_KEY_GSENSOR_PWR_ON_SENS,         STR_LEV_SETTINGS_OFF},{COMMON_KEY_SPEED_UNIT, 				STR_LEV_SPEEDUNIT_KMH},{COMMON_KEY_ENCODE_H265, 				STR_LEV_SETTINGS_H265},    //ON:H265{COMMON_KEY_USER_GUIDE_MODE, 			STR_LEV_SETTINGS_ON},{COMMON_KEY_VOICE_CONTROL,				STR_LEV_SETTINGS_ON},{COMMON_KEY_SPK_VOLUME_LEVEL,			DEF_SPK_VOLUME},{COMMON_KEY_POWER_OFF_TIME,				STR_LEV_TIME_OFF},{COMMON_KEY_FIRST_ENTER_BROWSER, 		STR_LEV_SETTINGS_ON},{COMMON_KEY_ENTER_PARKING_TIME, 		"0"},{COMMON_KEY_EXIST_NEW_PARKING_VIDEO,	STR_LEV_SETTINGS_OFF},{COMMON_KEY_REAR_CAM_CONNECT_STATUS, 	STR_LEV_SETTINGS_OFF},{COMMON_KEY_FACTORY_MODE,				STR_LEV_SETTINGS_OFF},{COMMON_KEY_MOVIE_QUALITY,				STR_LEV_SETTINGS_HIGH},{COMMON_KEY_SYNC_TIME,				    STR_LEV_SETTINGS_ON},{COMMON_KEY_SPEED_CAM_ALERT,			STR_LEV_SETTINGS_ON},{COMMON_KEY_LDWS_EN, 					STR_LEV_SETTINGS_OFF},{COMMON_KEY_FCWS_EN,					STR_LEV_SETTINGS_OFF},{COMMON_KEY_SAG_EN,						STR_LEV_SETTINGS_ON},{COMMON_KEY_EV,							STR_LEV_EVVALUE_00},{COMMON_KEY_ISO,						STR_LEV_ISO_AUTO},{COMMON_KEY_SPEED_LIMIT,				STR_LEV_SETTINGS_OFF},{COMMON_KEY_STICKER_GPS,				STR_LEV_SETTINGS_ON},{COMMON_KEY_STICKER_SPEED,				STR_LEV_SETTINGS_ON},{COMMON_KEY_MOTION_SENS,				STR_LEV_SETTINGS_HIGH},{COMMON_KEY_TIME_ZONE,				    DEF_TIMEZONE}, //STR_LEV_TIMEZONE_GMT_P_8{COMMON_KEY_WIFI_EN,					STR_LEV_SETTINGS_OFF},{COMMON_KEY_WIFI_POWER_ON,				STR_LEV_SETTINGS_ON},{COMMON_KEY_WIFI_SECURITY,				STR_LEV_SETTINGS_ON},{COMMON_KEY_WIFI_BAND,					STR_LEV_WIFI_BAND_2P4G},{COMMON_KEY_ADAS_MAINACTIVITYMARK,		STR_LEV_SETTINGS_OFF},{COMMON_KEY_ADAS_ONOFF,					STR_LEV_SETTINGS_OFF},{COMMON_KEY_EDOG_EN,					STR_LEV_SETTINGS_OFF},{COMMON_KEY_FACTORY_AGING_TEST_TIME, 		"0"},#if LCD_NESS{COMMON_KEY_WIFI_PASSWD,				WIFI_DEF_PASSWD},#endif{"end", "end"}
};
#else
static ENTRY s_DefEnters[] = {{COMMON_KEY_REARMIRROR,                 STR_LEV_SETTINGS_OFF},{COMMON_KEY_MOTIONDETECTION,            STR_LEV_SETTINGS_OFF},{COMMON_KEY_MOVIE_SIZE, 				"2560*1440@30fps"},{COMMON_KEY_VIDEO_CLIP_TIME, 			STR_LEV_TIME_1MIN},{COMMON_KEY_RECD_SOUND, 				STR_LEV_SETTINGS_ON},{COMMON_KEY_TIMELAPSE, 					STR_LEV_SETTINGS_OFF},//STR_LEV_SETTINGS_ON{COMMON_KEY_PARK_TIMELAPSE,				STR_LEV_SETTINGS_OFF},{COMMON_KEY_WDR_EN, 					STR_LEV_SETTINGS_ON},{COMMON_KEY_PARK_TYPE, 					STR_LEV_SETTINGS_OFF},{COMMON_KEY_BOOTSOUND,					STR_LEV_SETTINGS_ON},{COMMON_KEY_BEEP,						STR_LEV_SETTINGS_ON},{COMMON_KEY_DATETIME_FMT, 				STR_LEV_DATETIME_DMY},{COMMON_KEY_STICKER_EN,					STR_LEV_SETTINGS_ON},{COMMON_KEY_LANGUAGE,					STR_ID_LANGUAGE_ENGLISH},  //m move to func{COMMON_KEY_FLICKER,					STR_LEV_FLICKER_60HZ},{COMMON_KEY_LCD_POWERS,					STR_LEV_TIME_OFF},{COMMON_KEY_GSENSOR_SENS,				STR_LEV_SETTINGS_MID},{COMMON_KEY_GSENSOR_PWR_ON_SENS,		STR_LEV_SETTINGS_OFF},//{COMMON_KEY_SPEED_UNIT,					STR_LEV_SPEEDUNIT_KMH},{COMMON_KEY_SPEED_UNIT, 				STR_LEV_SPEEDUNIT_KMH},{COMMON_KEY_ENCODE_H265, 				STR_LEV_SETTINGS_H265},    //ON:H265{COMMON_KEY_USER_GUIDE_MODE, 			STR_LEV_SETTINGS_OFF},{COMMON_KEY_VOICE_CONTROL,				STR_LEV_SETTINGS_OFF},{COMMON_KEY_SPK_VOLUME_LEVEL,			DEF_SPK_VOLUME},{COMMON_KEY_POWER_OFF_TIME,				STR_LEV_TIME_OFF},{COMMON_KEY_FIRST_ENTER_BROWSER, 		STR_LEV_SETTINGS_ON},{COMMON_KEY_ENTER_PARKING_TIME, 		"0"},{COMMON_KEY_EXIST_NEW_PARKING_VIDEO,	STR_LEV_SETTINGS_OFF},{COMMON_KEY_REAR_CAM_CONNECT_STATUS, 	STR_LEV_SETTINGS_OFF},{COMMON_KEY_FACTORY_MODE,				STR_LEV_SETTINGS_OFF},{COMMON_KEY_MOVIE_QUALITY,				STR_LEV_SETTINGS_HIGH},{COMMON_KEY_SYNC_TIME,				    STR_LEV_SETTINGS_ON},{COMMON_KEY_SPEED_CAM_ALERT,			STR_LEV_SETTINGS_ON},{COMMON_KEY_LDWS_EN, 					STR_LEV_SETTINGS_OFF}, //ADAS车道偏离{COMMON_KEY_FCWS_EN,					STR_LEV_SETTINGS_OFF}, //ADAS前车碰撞{COMMON_KEY_SAG_EN,						STR_LEV_SETTINGS_OFF}, //ADAS停车起步{COMMON_KEY_EV,							STR_LEV_EVVALUE_00},{COMMON_KEY_ISO,						STR_LEV_ISO_AUTO},{COMMON_KEY_SPEED_LIMIT,				STR_LEV_SETTINGS_OFF},{COMMON_KEY_STICKER_GPS,				STR_LEV_SETTINGS_ON},{COMMON_KEY_STICKER_SPEED,				STR_LEV_SETTINGS_ON},{COMMON_KEY_MOTION_SENS,				STR_LEV_SETTINGS_HIGH},{COMMON_KEY_TIME_ZONE,				    DEF_TIMEZONE}, //STR_LEV_TIMEZONE_GMT_P_8{COMMON_KEY_WIFI_EN,					STR_LEV_SETTINGS_OFF},{COMMON_KEY_WIFI_POWER_ON,				STR_LEV_SETTINGS_ON},{COMMON_KEY_WIFI_SECURITY,				STR_LEV_SETTINGS_ON},{COMMON_KEY_WIFI_BAND,					STR_LEV_WIFI_BAND_2P4G},{COMMON_KEY_ADAS_MAINACTIVITYMARK,		STR_LEV_SETTINGS_OFF},{COMMON_KEY_ADAS_ONOFF,					STR_LEV_SETTINGS_OFF},{COMMON_KEY_EDOG_EN,					STR_LEV_SETTINGS_OFF},{COMMON_KEY_FACTORY_AGING_TEST_TIME, 		"0"},#if LCD_NESS{COMMON_KEY_WIFI_PASSWD,				WIFI_DEF_PASSWD},#endif{"end", "end"}
};
#endif	//---------------------------------------------------------------
int _Settings_ClrChangedFlag();
int _Settings_IsChanged();
int SettingsLoadToDriver(char* pPath);int _Settings_Lev_Str2Int(char* str)
{if(strcasecmp(str, STR_LEV_SETTINGS_OFF) == 0)return 0;else if(strcasecmp(str, STR_LEV_SETTINGS_ON) == 0)return 1;else if(strcasecmp(str, STR_LEV_SETTINGS_LOW) == 0)return 2;else if(strcasecmp(str, STR_LEV_SETTINGS_MID) == 0)return 3;else if(strcasecmp(str, STR_LEV_SETTINGS_HIGH) == 0)return 4;elsereturn 0;
}
char* _Settings_Lev_Int2Str(int lev)
{switch(lev){case 0:return STR_LEV_SETTINGS_OFF;case 1:return STR_LEV_SETTINGS_ON;case 2:return STR_LEV_SETTINGS_LOW;case 3:return STR_LEV_SETTINGS_MID;case 4:return STR_LEV_SETTINGS_HIGH;}return STR_LEV_SETTINGS_OFF;
}int _Settings_Time_Str2Int(char* str)
{if(strcasecmp(str, STR_LEV_TIME_OFF) == 0)return 0;else if(strcasecmp(str, STR_LEV_TIME_30S) == 0)return 30;else if(strcasecmp(str, STR_LEV_TIME_1MIN) == 0)return 60;else if(strcasecmp(str, STR_LEV_TIME_2MIN) == 0)return 120;else if(strcasecmp(str, STR_LEV_TIME_3MIN) == 0)return 180;else if(strcasecmp(str, STR_LEV_TIME_5MIN) == 0)return 300;else if(strcasecmp(str, STR_LEV_TIME_10MIN) == 0)return 600;else if(strcasecmp(str, STR_LEV_TIME_20MIN) == 0)return 1200;else if(strcasecmp(str, STR_LEV_TIME_30MIN) == 0)return 1800;elsereturn 0;
}
char* _Settings_Time_Int2Str(int time)
{switch(time){case 0:return STR_LEV_TIME_OFF;case 30:return STR_LEV_TIME_30S;case 60:return STR_LEV_TIME_1MIN;case 120:return STR_LEV_TIME_2MIN;case 180:return STR_LEV_TIME_3MIN;case 300:return STR_LEV_TIME_5MIN;case 600:return STR_LEV_TIME_10MIN;case 1200:return STR_LEV_TIME_20MIN;case 1800:return STR_LEV_TIME_30MIN;}return STR_LEV_TIME_OFF;
}int _ReqPwrOffSrcToDriver(POWEROFF_RES res)
{int s32Ret = 0;if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return -2;}s32Ret = ioctl(s_SettingsDriverFd, IOC_REQ_PWROFFSRC, &res);if (s32Ret != 0) {LOGE("get failed\n");return s32Ret;}return 0;
}
int _RelPwrOffSrcToDriver(POWEROFF_RES res)
{int s32Ret = 0;if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return -2;}s32Ret = ioctl(s_SettingsDriverFd, IOC_REL_PWROFFSRC, &res);if (s32Ret != 0) {LOGE("get failed\n");return s32Ret;}return 0;
}//判断两个字符串是否相同,相同返回0
int _Settings_CompStr(char* str1, char* str2)
{if(!str1 || !str2) return -1;if(strcasecmp(str1, str2) == 0)return 0;return 1;
}//eg. _Settings_GetKeys("Camera.Menu.*", str, len);
int _Settings_GetKeys(const char* key, char* strVal, int strValSize)
{int s32Ret;ENTRY_EX* pEntryEx = (ENTRY_EX*)strVal;if(!strVal || !key) return -1;if (s_SettingsDriverFd == -1) {LOGE("%s, please initialized first\n", key);return -2;}if(strValSize <= (strlen(key)+sizeof(pEntryEx->len))){LOGE("param error\n");return -3;}pEntryEx->len = strValSize;strcpy(pEntryEx->pval, key);  //strValSize > strlen(key);s32Ret = ioctl(s_SettingsDriverFd, IOC_GET_KEY_VAL_EX, pEntryEx);if (s32Ret != 0) {LOGE("del key[%s,%s] failed ret=%d\n",pEntryEx->pval, key, s32Ret);return s32Ret;}return 0;
}int _Settings_GetKeyStrVal(const char* key, char* strVal, int strValSize)
{int s32Ret;ENTRY_EX* pEntryEx = (ENTRY_EX*)strVal;if(!strVal || !key) return -1;if (s_SettingsDriverFd == -1) {LOGE("%s, please initialized first\n", key);return -2;}if(strValSize <= (strlen(key)+sizeof(pEntryEx->len))){LOGE("param error:%s [%d<=%d]\n", key, strValSize, (strlen(key)+sizeof(pEntryEx->len)));return -3;}pEntryEx->len = strValSize;strcpy(pEntryEx->pval, key);  //strValSize > strlen(key);s32Ret = ioctl(s_SettingsDriverFd, IOC_GET_KEY_VAL, pEntryEx);if (s32Ret != 0) {LOGE("get key[%s,%s] failed ret=%d\n",pEntryEx->pval, key, s32Ret);memset(strVal, 0, strValSize);return s32Ret;}return 0;
}int _Settings_GetKeyIntVal(const char* key,           int* pInt)
{char strVal[66] = {0};if(!pInt || !key) return -1;if(_Settings_GetKeyStrVal(key, strVal, sizeof(strVal)))return -2;	*pInt = atoi(strVal);return 0;
}//相同返回0, 其他返回值为不相同
int _Settings_GetAndCompStr(const char* key, const char* str)
{char strVal[66] = {0};if(!str || !key) return -1;if(_Settings_GetKeyStrVal(key, strVal, sizeof(strVal)))return -2;return _Settings_CompStr(strVal, (char*)str);
}int _Settings_GetPosVal(unsigned char pos, ENTRY* pentry)
{int s32Ret;if(!pentry) return -1;if (s_SettingsDriverFd == -1) {LOGE("%d, please initialized first\n", pos);return -2;}pentry->pkey[0] = pos;s32Ret = ioctl(s_SettingsDriverFd, IOC_GET_POS_VAL, pentry);if (s32Ret != 0) {LOGE("get pos[%d]: ret=%d  failed, maybe null\n", pos,s32Ret);return s32Ret;}return 0;
}int _Settings_Set(const char* key, const char* str)
{int s32Ret;ENTRY entry = {0};if(!str || !key){LOGE("_Settings_Set  key or str is NULL fail \n");return -1;}if (s_SettingsDriverFd == -1) {LOGE("%s, please initialized first\n", key);return -2;}memset(&entry, 0, sizeof(entry));strncpy(entry.pkey, key, SETTINGS_ENTRY_ARROW_SIZE-1);strncpy(entry.pval, str, SETTINGS_ENTRY_ARROW_SIZE-1);entry.pkey[SETTINGS_ENTRY_ARROW_SIZE-1] = 0;entry.pval[SETTINGS_ENTRY_ARROW_SIZE-1] = 0;s32Ret = ioctl(s_SettingsDriverFd, IOC_SET_KEY_VAL, &entry);if (s32Ret != 0) {LOGE("set %s=%s failed\n", key, str);return s32Ret;}return 0;
}
int _Settings_SetInt(const char* key, int val)
{char buf[32] = {0};sprintf(buf, "%d", val);return _Settings_Set(key, buf);
}int _Settings_ShowAll(char* key, char* strOut, int outsize)
{int i = 0;int s32Ret = 0;int s32WriteBytes = 0;unsigned char tmp[156];ENTRY entry;int iGetSize = 0;if(!s_nums){if(_Settings_GetKeyNums(&s_nums))return -1;if(s_nums > MAX_SETTINGS_ENRTY_NUMS){LOGE("nums mast <= %d\n", MAX_SETTINGS_ENRTY_NUMS);return -1;}if(!s_nums) {LOGE("not set nums:%d\n", s_nums);return -1;}}if(strOut) strOut[0] = 0;for(i=0; i<s_nums; i++){memset(tmp, 0, sizeof(tmp));memset(&entry, 0, sizeof(entry));if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return -2;}entry.pkey[0] = i;s32Ret = ioctl(s_SettingsDriverFd, IOC_GET_POS_VAL, &entry);if (s32Ret != 0) {break;}sprintf(tmp, "%s=%s\n", entry.pkey, entry.pval);if(strncasecmp(key, entry.pkey, strlen(key)) == 0){if(strOut){if(outsize>(iGetSize+strlen(tmp))){strcat(strOut, tmp);iGetSize += strlen(tmp);}else {LOGE("outsize too small\n");break;}}elseprintf("%s", tmp);break;}if(strchr(key, '*')){if(key[0] == '*'){if(strOut){if(outsize>(iGetSize+strlen(tmp))){strcat(strOut, tmp);iGetSize += strlen(tmp);}else {LOGE("outsize too small\n");break;}}elseprintf("%s", tmp);}			else{if(strncasecmp(key, entry.pkey, strlen(key)-1) == 0){if(strOut){if(outsize>(iGetSize+strlen(tmp))){strcat(strOut, tmp);iGetSize += strlen(tmp);}else {LOGE("outsize too small\n");break;}}elseprintf("%s", tmp);}				}}}return 0;
}int _Settings_DelAll(void)
{int i = 0;int s32Ret = 0;int s32WriteBytes = 0;unsigned char tmp[156];ENTRY entry;if(!s_nums){if(_Settings_GetKeyNums(&s_nums))return -1;if(s_nums > MAX_SETTINGS_ENRTY_NUMS){LOGE("nums mast <= %d\n", MAX_SETTINGS_ENRTY_NUMS);return -1;}if(!s_nums) {LOGE("not set nums:%d\n", s_nums);return -1;}}for(i=0; i<s_nums; i++){_Settings_DelKey_ByPos(i);}return 0;
}int _Settings_ResetToDefault()
{int i = 0;int fd = -1;int s32WriteBytes = 0;unsigned char tmp[156];//检查重复for(i=0; i<sizeof(s_DefEnters)/sizeof(ENTRY); i++){for(int j=i+1; j<sizeof(s_DefEnters)/sizeof(ENTRY); j++){if(strcmp(s_DefEnters[i].pkey,s_DefEnters[j].pkey)==0){LOGE("Get repeat key: %s @ %d and %d\n", s_DefEnters[i].pkey, i, j);//return -1;}}}//设置默认语言for(i=0; i<sizeof(s_DefEnters)/sizeof(ENTRY); i++){if(strcmp(s_DefEnters[i].pkey,COMMON_KEY_LANGUAGE)==0) {if(strcmp(DEF_LANGUAGE, "CH") == 0) {strcpy(s_DefEnters[i].pval, STR_ID_LANGUAGE_SCHINESE);} else if(strcmp(DEF_LANGUAGE, "EN") == 0) {strcpy(s_DefEnters[i].pval, STR_ID_LANGUAGE_ENGLISH);}else if(strcmp(DEF_LANGUAGE, "JP") == 0) {strcpy(s_DefEnters[i].pval, STR_ID_LANGUAGE_JAPANESE);}}}fd = open(SETTINGS_PATH,O_RDWR|O_CREAT|O_TRUNC);if(fd == -1){LOGE("open %s failed\n", SETTINGS_PATH);return -1;}if (lseek(fd, sizeof(s_NvHdr), SEEK_SET) == (off_t)-1) {LOGE("lseek \"%d\" fail. error(%s)\n", fd, strerror(errno));close(fd);return errno;}s_NvHdr.magicnumS = NVRAM_MAGIC_S;s_NvHdr.crcnum = 0xFF;s_NvHdr.len = 0;s_NvHdr.magicnumE = NVRAM_MAGIC_E;s_NvHdr.newLine = '\n';i = 0;while(strcmp(s_DefEnters[i].pkey,"end")!=0){memset(tmp, 0, sizeof(tmp));sprintf(tmp, "%s=%s\n", s_DefEnters[i].pkey, s_DefEnters[i].pval);s32WriteBytes = write(fd, (unsigned char*)tmp, strlen(tmp));if (s32WriteBytes != (ssize_t)strlen(tmp)) {LOGE("write \"%d\" fail. error(%s) (%dbytes)\n", fd, strerror(errno), s32WriteBytes);close(fd);return -2;}LOGD("%s", tmp);s_NvHdr.crcnum = _Comm_CheckCrc8(tmp, strlen(tmp), s_NvHdr.crcnum);s_NvHdr.len += strlen(tmp);i++;}s32WriteBytes = write(fd, (unsigned char*)SETTINGS_END_STR, strlen(SETTINGS_END_STR));if (s32WriteBytes != (ssize_t)strlen(SETTINGS_END_STR)) {LOGE("write \"%d\" fail. error(%s) (%dbytes)\n", fd, strerror(errno), s32WriteBytes);close(fd);return -3;}LOGD("%s\n", SETTINGS_END_STR);s_NvHdr.crcnum = _Comm_CheckCrc8((unsigned char*)SETTINGS_END_STR, strlen(SETTINGS_END_STR), s_NvHdr.crcnum);s_NvHdr.len += strlen(SETTINGS_END_STR);LOGI("crc=%x, len=%d\n", s_NvHdr.crcnum, s_NvHdr.len);if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {LOGE("lseek \"%d\" fail. error(%s)\n", fd, strerror(errno));close(fd);return errno;}s32WriteBytes = write(fd, (unsigned char*)&s_NvHdr, sizeof(s_NvHdr));if (s32WriteBytes != (ssize_t)sizeof(s_NvHdr)) {LOGE("write \"%d\" fail. error(%s) (%dbytes)\n", fd, strerror(errno), s32WriteBytes);close(fd);return -4;}fsync(fd);close(fd);//LOGI("filesize=%d\n", _Comm_GetFileSize(SETTINGS_PATH));//system("cat /config/settings.txt");_Settings_DelAll();return SettingsLoadToDriver(SETTINGS_PATH);
}int _Settings_SetKeyNums(unsigned char nums)
{int s32Ret;if(nums == 0)return -1;if(nums > MAX_SETTINGS_ENRTY_NUMS){LOGE("nums mast <= %d\n", MAX_SETTINGS_ENRTY_NUMS);return -1;}if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return -2;}s32Ret = ioctl(s_SettingsDriverFd, IOC_SET_KEY_NUMS, &nums);if (s32Ret != 0) {LOGE("failed\n");return s32Ret;}s_nums = nums;return 0;
}int _Settings_GetKeyNums(unsigned char* nums)
{int s32Ret;if(!nums)return -1;if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return -2;}s32Ret = ioctl(s_SettingsDriverFd, IOC_GET_KEY_NUMS, nums);if (s32Ret != 0) {LOGE("failed\n");return s32Ret;}return 0;
}int _Settings_DelKey(const char* key)
{int s32Ret;ENTRY entry = {0};if(!key) return -1;if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return -2;}strncpy(entry.pkey, key, SETTINGS_ENTRY_ARROW_SIZE-1);entry.pkey[SETTINGS_ENTRY_ARROW_SIZE-1] =  0;s32Ret = ioctl(s_SettingsDriverFd, IOC_DEL_KEY, &entry);if (s32Ret != 0) {LOGE("del key[%s,%s] failed ret=%d\n",entry.pkey, key, s32Ret);return s32Ret;}return 0;
}
int _Settings_DelKey_ByPos(unsigned char pos)
{int s32Ret;if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return -2;}s32Ret = ioctl(s_SettingsDriverFd, IOC_DEL_KEY_BYPOS, &pos);if (s32Ret != 0) {LOGE("failed pos=%d\n", pos);return s32Ret;}return 0;
}static int AddEntryByLine(char* pLine)
{char* pKey = NULL;char* pVal = NULL;char* pTmp = NULL;//1 skip ' 'while(*pLine == ' ') {pLine++;if(*pLine == 0)return -1;}//2 去掉注释pTmp = strchr(pLine, ';');if(pTmp) *pTmp = 0;//3. get keyif(*pLine == ';')return 1;if(*pLine == '#')return 1;pKey = pLine;pTmp = strchr(pLine, '=');if(!pTmp) {LOGW("invalid str:%s\n", pLine);return 1;}if(*pTmp){*pTmp = 0;pVal = pTmp+1;}//4 skip ' 'pTmp = pVal;while(*pTmp == ' ') {pTmp++;if(*pTmp == 0)break;}//LOGI("add:%s=%s\n", pKey, pVal);return _Settings_Set(pKey, pVal);
}static char* GetNextLine(char* pData)
{char* pLineEnd = NULL;char* pLineS = pData;if(!pData)return NULL;if(pData[0] == 0 || pData[0] == ';')return pData;pLineEnd = strchr(pData, '\n');if(pLineEnd){*pLineEnd = 0;pData = pLineEnd+1;return pLineS;}return NULL;
}
static int ParserSettings(char* pData, int iLen)
{unsigned char crc;char* pstr = NULL;char* pLine = NULL;int len = 0;int iLenSettings = iLen-sizeof(NVHDR);memcpy(&s_NvHdr, pData, sizeof(NVHDR));len += sizeof(NVHDR);if((s_NvHdr.magicnumS != (int)NVRAM_MAGIC_S) || (s_NvHdr.magicnumE != (int)NVRAM_MAGIC_E)){LOGE("ParserSettings: magicnum error!\n");return -1;}pstr = pData+sizeof(NVHDR);crc = _Comm_CheckCrc8((unsigned char*)pstr, iLenSettings, 0xFF);if(crc != s_NvHdr.crcnum){LOGE("ParserSettings: crc error[%x != %x] len[%d,%d]!\n", crc, s_NvHdr.crcnum, s_NvHdr.len, iLen-sizeof(NVHDR));return -2;}//LOGE("start parse, exception todo...\n");//_Comm_WriteFile("/mnt/mmc/settings_dbg.txt", pData, iLen);  //for debugwhile(1){if(pstr[0]==';')break;pLine = GetNextLine(pstr);if(pLine == NULL)break;pstr+=strlen(pLine)+1;if(pLine){len += strlen(pLine)+1;AddEntryByLine(pLine);if(len >= iLenSettings || pstr[0]==';')break;}elsebreak;}LOGD("end parse\n");return 0;
}int SettingsLoadToDriver(char* pPath)
{char* pData = NULL;int len = 0;int ret = 0;int bChanged = _Settings_IsChanged();  //load之前先保存changed flagdo {if(!pPath){ret = -1;break;}len = _Comm_GetFileSize(pPath);if(!len){ret = -2;break;}pData = (char*)malloc(len+1);memset(pData, 0, len+1);if(_Comm_ReadFile(pPath, pData, len)){ ret = -3;break;}pData[len] = 0;ret = ParserSettings(pData, len);}while(0);if(pData)free(pData);if(!bChanged)  //如果之前没有change, 清除change flag_Settings_ClrChangedFlag();if(ret)LOGE("ret = %d\n", ret);return ret;
}//当前设置备份到FLASH, 也可以备份到SD卡
int _Settings_Recovery(char* strBackUpPath)
{int ret = 0;#if SETTINGS_ABCKUP_ENunsigned char* pData = NULL;int len = 0;int bChanged = _Settings_IsChanged();  //load之前先保存changed flagNVHDR lNvHdr={0};#if BACKUP_SETTNIGS_TOSDstrBackUpPath = SETTINGS_BACKUP_SD_PATH;#endif//LOGI("Enter\n");do {if(!strBackUpPath){ret = -1;break;}#if BACKUP_SETTNIGS_TOSDif(_Comm_ReadFile(strBackUpPath, &lNvHdr, sizeof(NVHDR)))#elselen = _MtdMgr_Read(strBackUpPath, 0, (unsigned char*)&lNvHdr, sizeof(NVHDR));#endifif(len!=sizeof(NVHDR)){ret = -2;break;}if((lNvHdr.magicnumS != (int)NVRAM_MAGIC_S) || (lNvHdr.magicnumE != (int)NVRAM_MAGIC_E) || (lNvHdr.len > (10<<10))){ret = -21;break;}len = sizeof(NVHDR)+lNvHdr.len;pData = (char*)malloc(len+1);memset(pData, 0, len+1);#if BACKUP_SETTNIGS_TOSDif(_Comm_ReadFile(strBackUpPath, (char*)pData, len))#elseif(_MtdMgr_Read(strBackUpPath, 0, pData, len)!=len)#endif	{ ret = -3;break;}pData[len] = 0;ret = ParserSettings(pData, len);}while(0);if(pData)free(pData);if(!bChanged)  //如果之前没有change, 清除change flag_Settings_ClrChangedFlag();if(ret)LOGE("ret = %d\n", ret);elseLOGI("succees\n");
#endif//LOGI("Exit\n");return ret;
}int _Settings_BackUp(char* strBackUpPath, char* pPath)
{int ret = 0;#if SETTINGS_ABCKUP_ENunsigned char* pData = NULL;int len = 0;#if BACKUP_SETTNIGS_TOSDstrBackUpPath = SETTINGS_BACKUP_SD_PATH;#endifLOGI("Enter\n");do {if(!pPath){ret = -1;break;}len = _Comm_GetFileSize(pPath);if(!len){ret = -2;break;}pData = (char*)malloc(len+1);if(!pData) {ret = -21;break;}memset(pData, 0, len+1);if(_Comm_ReadFile(pPath, pData, len)){ ret = -3;break;}pData[len] = 0;//_Comm_DumpHexEx("settings backup", pData, 64);#if BACKUP_SETTNIGS_TOSDif(_Comm_WriteFile(strBackUpPath, pData, len))#elseif(_MtdMgr_Write(strBackUpPath, 0, pData, len, 1) != len)#endif	{ret = -4;break;}#if BACKUP_SETTNIGS_TOSD_Comm_SetFileHide(strBackUpPath, 1);#endif}while(0);if(pData)free(pData);if(ret)LOGE("ret = %d\n", ret);elseLOGI("succees\n");
#endifLOGI("Exit\n");return ret;
}int _Settings_ClrChangedFlag()
{int s32Ret;if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return 0;}s32Ret = ioctl(s_SettingsDriverFd, IOC_CLR_CHANGED_FLAG, NULL);if (s32Ret != 0) {LOGE("failed\n");return -1;}return 0;
}int _Settings_IsChanged()
{int s32Ret;char changed = 0;if (s_SettingsDriverFd == -1) {LOGE("please initialized first\n");return 0;}s32Ret = ioctl(s_SettingsDriverFd, IOC_GET_CHANGED_FLAG, &changed);if (s32Ret != 0) {LOGE("failed\n");return 1;}return (int)changed;
}int _Settings_Save(char* pPath, int bBackUp)
{int i = 0;int fd = -1;int s32WriteBytes = 0;unsigned char tmp[156];ENTRY entry;if(pPath == NULL)pPath = SETTINGS_PATH;if (s_SettingsDriverFd == -1) {return -1;}if(!s_nums){if(_Settings_GetKeyNums(&s_nums))return -1;if(s_nums > MAX_SETTINGS_ENRTY_NUMS){LOGE("nums mast <= %d\n", MAX_SETTINGS_ENRTY_NUMS);return -1;}if(!s_nums) {LOGE("not set nums:%d\n", s_nums);return -1;}}if(!_Settings_IsChanged()){LOGI("Settings no change, no need to save!\n");return 1;}fd = open(pPath,O_RDWR | O_TRUNC);if(fd == -1){LOGE("open %s failed\n", pPath);return -1;}if (lseek(fd, sizeof(s_NvHdr), SEEK_SET) == (off_t)-1) {LOGE("lseek \"%d\" fail. error(%s)\n", fd, strerror(errno));close(fd);return -1;}s_NvHdr.magicnumS = NVRAM_MAGIC_S;s_NvHdr.crcnum = 0xFF;s_NvHdr.len = 0;s_NvHdr.magicnumE = NVRAM_MAGIC_E;s_NvHdr.newLine = '\n';for(i=0; i<s_nums; i++){memset(tmp, 0, sizeof(tmp));memset(&entry, 0, sizeof(entry));if(_Settings_GetPosVal(i, &entry)){LOGV("get entry[%d] error\n", i);break;}sprintf(tmp, "%s=%s\n", entry.pkey, entry.pval);s32WriteBytes = write(fd, (unsigned char*)tmp, strlen(tmp));if (s32WriteBytes != (ssize_t)strlen(tmp)) {LOGE("write \"%d\" fail. error(%s) (%dbytes)\n", fd, strerror(errno), s32WriteBytes);close(fd);return -2;}LOGV("%s", tmp);s_NvHdr.crcnum = _Comm_CheckCrc8(tmp, strlen(tmp), s_NvHdr.crcnum);s_NvHdr.len += strlen(tmp);}s32WriteBytes = write(fd, (unsigned char*)SETTINGS_END_STR, strlen(SETTINGS_END_STR));if (s32WriteBytes != (ssize_t)strlen(SETTINGS_END_STR)) {LOGE("write \"%d\" fail. error(%s) (%dbytes)\n", fd, strerror(errno), s32WriteBytes);close(fd);return -3;}LOGV("%s\n", SETTINGS_END_STR);s_NvHdr.crcnum = _Comm_CheckCrc8((unsigned char*)SETTINGS_END_STR, strlen(SETTINGS_END_STR), s_NvHdr.crcnum);s_NvHdr.len += strlen(SETTINGS_END_STR);LOGI("crc=%x, len=%d\n", s_NvHdr.crcnum, s_NvHdr.len);if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {LOGE("lseek \"%d\" fail. error(%s)\n", fd, strerror(errno));close(fd);return -4;}s32WriteBytes = write(fd, (unsigned char*)&s_NvHdr, sizeof(s_NvHdr));if (s32WriteBytes != (ssize_t)sizeof(s_NvHdr)) {LOGE("write \"%d\" fail. error(%s) (%dbytes)\n", fd, strerror(errno), s32WriteBytes);close(fd);return -5;}fsync(fd);close(fd);if(bBackUp){//save to raw part for backup_Settings_BackUp(MTD_PART_SETTINGS_NAME, SETTINGS_PATH);}return 0;
}int _Settings_Start(int bLoad)
{int ret = 0;if (s_SettingsDriverFd != -1) {LOGI("already init\r\n");return 1;}if (access(SETTINGS_DEV_NODE, F_OK) != 0) {LOGE("%s not exist\n", SETTINGS_DEV_NODE);//return -1;}s_SettingsDriverFd = open(SETTINGS_DEV_NODE, O_RDWR);if (s_SettingsDriverFd < 0) {LOGE("open [%s] failed\n", SETTINGS_DEV_NODE);return -2;}int fd = open(SETTINGS_PATH,O_RDWR|O_CREAT);if(fd == -1)LOGE("open creat [%s] failed\n", SETTINGS_PATH);elseclose(fd);if(bLoad){_Settings_SetKeyNums(100);if(SettingsLoadToDriver(SETTINGS_PATH)){if(_Settings_Recovery(MTD_PART_SETTINGS_NAME)) //load from raw part to driver{ret = _Settings_ResetToDefault();}else  //raw settings ok, recovery{//_Settings_Save(SETTINGS_PATH);}}}return ret;
}
int _Settings_Stop(int bSave)
{int ret = 0;//LOGI("Enter !!!!!!!!!!!!\n");pthread_mutex_lock(&s_SettingsMutex);do {if (s_SettingsDriverFd == -1) {ret = 0;break;}if(bSave)ret = _Settings_Save(SETTINGS_PATH, 1);ret = close(s_SettingsDriverFd);if (0 > ret) {LOGE("settings fd[%d] close,fail,errno(%d)\n", s_SettingsDriverFd, errno);ret = -1;break;}s_SettingsDriverFd = -1;}while(0);pthread_mutex_unlock(&s_SettingsMutex);return ret;
}

4.2应用层添加Setting.h

#ifndef _SETTINGS_MANAGER_H_
#define _SETTINGS_MANAGER_H_#ifdef __cplusplus
extern "C" {
#endif#include "PowerManager.h"
#define SD_OUT_POWER_OFF 	0#define STR_VERSION		VERSION
#define PRODUCT_STR_SKU   	SKU
#define DEVICE_NAME		   	PROJNAME
#define DEVICE_MFRS		   	VENDOR/* 将设置写入驱动中,支持多个应用共享 */
#define SETTINGS_DEV_NODE	"/dev/lte"#define SETTINGS_PATH	"/config/settings.txt"#define DEF_DATA_TIME	"2021-10-01 08:00:00"#define BACKUP_SETTNIGS_TOSD	0	//1:SD, 0:FLASH
#define SETTINGS_BACKUP_SD_PATH		"/mnt/mmc/settings.bin"#define VIDEO_RES_4K_W		3840
#define VIDEO_RES_4K_H		2160
#define VIDEO_RES_2K_W		RES_2K_W
#define VIDEO_RES_2K_H		RES_2K_H
#define VIDEO_RES_DEF_W		RES_DEF_W
#define VIDEO_RES_DEF_H		RES_DEF_H
#if HIS_WEB
#define STR_LEV_VIDEO_RES_720P 		"1280x720"
#define STR_LEV_VIDEO_RES_1080P 	"1920x1080"
#define STR_LEV_VIDEO_RES_4K		"3840x2160"
#else
#define STR_LEV_VIDEO_RES_720P 		"1280x720P30"
#define STR_LEV_VIDEO_RES_1080P 	"1920x1080P30"
#define STR_LEV_VIDEO_RES_4K		"3840x2160P30"
#endif
#define STR_LEV_VIDEO_RES_2K		RES_STR_2K //STR_RES_2K_W "x" STR_RES_2K_H "P30" //2560x1440P30"
#define STR_LEV_VIDEO_RES_DEF		RES_STR_DEF#define STR_LEV_SETTINGS_OFF 		"OFF"
#if HIS_WEB
#define STR_LEV_SETTINGS_LOW		"LOW"
#define STR_LEV_SETTINGS_MID		"MIDDLE"
#define STR_LEV_SETTINGS_HIGH		"HIGH"
#else
#define STR_LEV_SETTINGS_LOW		"LEVEL4"
#define STR_LEV_SETTINGS_MID		"LEVEL2"
#define STR_LEV_SETTINGS_HIGH		"LEVEL0"
#define STR_LEV_MD_LOW		        "LOW"
#define STR_LEV_MD_MID		        "MID"
#define STR_LEV_MD_HIGH		        "HIGHT"#endif
#define STR_LEV_SETTINGS_ON			"ON"
#define STR_LEV_SETTINGS_OK			"OK"
#define STR_LEV_SETTINGS_FAIL		"FAIL"
#define STR_LEV_SETTINGS_H265		"H265"
#define STR_LEV_SETTINGS_H264		"H264"#define STR_ID_LANGUAGE_ENGLISH	"en_US"#define STR_ID_LANGUAGE_RUSSIAN	"ru_RU"#define STR_ID_LANGUAGE_JAPANESE	"ja_JP"#define STR_ID_LANGUAGE_FRENCH      "fr_FR"#define STR_ID_LANGUAGE_UKRANINIAN  "uk_UA"#define STR_ID_LANGUAGE_SLOVAK		"sk_SK"
#define STR_ID_LANGUAGE_ROMANIAN 	"ro_RO"
#define STR_ID_LANGUAGE_LATVIAN 	"lv_LV"
#define STR_ID_LANGUAGE_ITALIAN 	"it_IT"
#define STR_ID_LANGUAGE_GERMAN		"de_DE"#define STR_ID_LANGUAGE_KOREAN		"ko_KR"#define STR_ID_LANGUAGE_SPANISH	"es_ES"#define STR_ID_LANGUAGE_PORTUGUESE	"pt_PT"#define STR_ID_LANGUAGE_SCHINESE	"zh_CN"#define STR_ID_LANGUAGE_TCHINESE	"zh_TW"#define STR_ID_LANGUAGE_POLISH		"pl_PL"#define STR_ID_LANGUAGE_THAI		"th_rTH"#define STR_ID_LANGUAGE_AUTO		"AUTO"#define STR_LEV_TIME_OFF 			"OFF"
#define STR_LEV_TIME_10S 			"30S"
#define STR_LEV_TIME_30S 			"30S"
#define STR_LEV_TIME_1MIN			"1MIN"
#define STR_LEV_TIME_2MIN			"2MIN"
#define STR_LEV_TIME_3MIN			"3MIN"
#define STR_LEV_TIME_5MIN			"5MIN"
#define STR_LEV_TIME_10MIN			"10MIN"
#define STR_LEV_TIME_20MIN			"20MIN"
#define STR_LEV_TIME_30MIN			"30MIN"#define STR_LEV_FLICKER_50HZ		"50Hz-PAL"
#define STR_LEV_FLICKER_60HZ 		"60Hz-NTSC"
#define STR_LEV_FLICKER_55HZ		"55Hz"#if HIS_WEB
#define STR_LEV_DATETIME_YMD		"YYYY-MM-DD"
#define STR_LEV_DATETIME_MDY 		"MM-DD-YYYY"
#define STR_LEV_DATETIME_DMY		"DD-MM-YYYY"
#else
#define STR_LEV_DATETIME_YMD		"YMD"
#define STR_LEV_DATETIME_MDY 		"MDY"
#define STR_LEV_DATETIME_DMY		"DMY"
#endif#define STR_LEV_TIME_STAMP_DL 		"DATE+LOGO"
#define STR_LEV_TIME_STAMP_D		"DATE"
#define STR_LEV_TIME_STAMP_L		"LOGO"#define STR_LEV_SPEEDUNIT_KMH 		"km/h"
#define STR_LEV_SPEEDUNIT_MPH		"mph"#define STR_LEV_WIFI_BAND_2P4G 		"2.4G"
#define STR_LEV_WIFI_BAND_5G		"5G"#define STR_LEV_EVVALUE_N20			"EVN200"
#define STR_LEV_EVVALUE_N17			"EVN167"
#define STR_LEV_EVVALUE_N15			"EVN155"
#define STR_LEV_EVVALUE_N13			"EVN133"
#define STR_LEV_EVVALUE_N10			"EVN100"
#define STR_LEV_EVVALUE_N07			"EVN67"
#define STR_LEV_EVVALUE_N05			"EVN55"
#define STR_LEV_EVVALUE_N03			"EVN33"
#define STR_LEV_EVVALUE_00			"EV0"
#define STR_LEV_EVVALUE_P03			"EVP33"
#define STR_LEV_EVVALUE_P05			"EVP55"
#define STR_LEV_EVVALUE_P07			"EVP67"
#define STR_LEV_EVVALUE_P10		    "EVP100"
#define STR_LEV_EVVALUE_P13			"EVP133"
#define STR_LEV_EVVALUE_P15			"EVP155"
#define STR_LEV_EVVALUE_P17			"EVP167"
#define STR_LEV_EVVALUE_P20			"EVP200"#define STR_LEV_ISO_AUTO			"ISO_AUTO"
#define STR_LEV_ISO_100				"ISO_100"
#define STR_LEV_ISO_200				"ISO_200"
#define STR_LEV_ISO_400				"ISO_400"
#define STR_LEV_ISO_800				"ISO_800"
#define STR_LEV_ISO_1200			"ISO_1200"
#define STR_LEV_ISO_1600			"ISO_1600"
#define STR_LEV_ISO_3200			"ISO_3200"#define STR_LEV_SPEED_LIMIT_50		"50"
#define STR_LEV_SPEED_LIMIT_60		"60"
#define STR_LEV_SPEED_LIMIT_70		"70"
#define STR_LEV_SPEED_LIMIT_80		"80"
#define STR_LEV_SPEED_LIMIT_90		"90"
#define STR_LEV_SPEED_LIMIT_100		"100"
#define STR_LEV_SPEED_LIMIT_110		"110"
#define STR_LEV_SPEED_LIMIT_120		"120"
#define STR_LEV_SPEED_LIMIT_130		"130"
#define STR_LEV_SPEED_LIMIT_140		"140"
#define STR_LEV_SPEED_LIMIT_150		"150"
#define STR_LEV_SPEED_LIMIT_160		"160"
#define STR_LEV_SPEED_LIMIT_170		"170"
#define STR_LEV_SPEED_LIMIT_180		"180"
#define STR_LEV_SPEED_LIMIT_190		"190"
#define STR_LEV_SPEED_LIMIT_200		"200"#define STR_LEV_LEVEL_0				"0"
#define STR_LEV_LEVEL_1				"10"
#define STR_LEV_LEVEL_2				"20"
#define STR_LEV_LEVEL_3				"30"
#define STR_LEV_LEVEL_4				"40"
#define STR_LEV_LEVEL_5				"50"
#define STR_LEV_LEVEL_6				"60"
#define STR_LEV_LEVEL_7				"70"
#define STR_LEV_LEVEL_8				"80"
#define STR_LEV_LEVEL_9				"90"
#define STR_LEV_LEVEL_10			"100"#define STR_LEV_TIMEZONE_GMT_M_12   "GMT-12:00"
#define STR_LEV_TIMEZONE_GMT_M_11   "GMT-11:00"
#define STR_LEV_TIMEZONE_GMT_M_10   "GMT-10:00"
#define STR_LEV_TIMEZONE_GMT_M_9    "GMT-9:00"
#define STR_LEV_TIMEZONE_GMT_M_8   	"GMT-8:00"
#define STR_LEV_TIMEZONE_GMT_M_7   	"GMT-7:00"
#define STR_LEV_TIMEZONE_GMT_M_6   	"GMT-6:00"
#define STR_LEV_TIMEZONE_GMT_M_5   	"GMT-5:00"
#define STR_LEV_TIMEZONE_GMT_M_4   	"GMT-4:00"
#define STR_LEV_TIMEZONE_GMT_M_3_30 "GMT-3:30"
#define STR_LEV_TIMEZONE_GMT_M_3   	"GMT-3:00"
#define STR_LEV_TIMEZONE_GMT_M_2   	"GMT-2:00"
#define STR_LEV_TIMEZONE_GMT_M_1   	"GMT-1:00"
#define STR_LEV_TIMEZONE_GMT   		"GMT"
#define STR_LEV_TIMEZONE_GMT1   	"GMT+00"
#define STR_LEV_TIMEZONE_GMT_P_1    "GMT+1:00"
#define STR_LEV_TIMEZONE_GMT_P_2   	"GMT+2:00"
#define STR_LEV_TIMEZONE_GMT_P_3   	"GMT+3:00"
#define STR_LEV_TIMEZONE_GMT_P_3_30 "GMT+3:30"
#define STR_LEV_TIMEZONE_GMT_P_4   	"GMT+4:00"
#define STR_LEV_TIMEZONE_GMT_P_4_30 "GMT+4:30"
#define STR_LEV_TIMEZONE_GMT_P_5   	"GMT+5:00"
#define STR_LEV_TIMEZONE_GMT_P_5_30 "GMT+5:30"
#define STR_LEV_TIMEZONE_GMT_P_5_45 "GMT+5:45"
#define STR_LEV_TIMEZONE_GMT_P_6   	"GMT+6:00"
#define STR_LEV_TIMEZONE_GMT_P_6_30 "GMT+6:30"
#define STR_LEV_TIMEZONE_GMT_P_7   	"GMT+7:00"
#define STR_LEV_TIMEZONE_GMT_P_8   	"GMT+8:00"
#define STR_LEV_TIMEZONE_GMT_P_9   	"GMT+9:00"
#define STR_LEV_TIMEZONE_GMT_P_9_30 "GMT+9:30"
#define STR_LEV_TIMEZONE_GMT_P_10   "GMT+10:00"
#define STR_LEV_TIMEZONE_GMT_P_11   "GMT+11:00"
#define STR_LEV_TIMEZONE_GMT_P_12   "GMT+12:00"
#define STR_LEV_TIMEZONE_GMT_P_13   "GMT+13:00"
#define STR_LEV_TIMEZONE_GMT_P_14   "GMT+14:00"#define DEF_SPK_VOLUME		STR_LEV_SETTINGS_MID//---------------------------------------
#if HIS_WEB
#define COMMON_KEY_USER_GUIDE_MODE			"UserGuide"
#define COMMON_KEY_RECD_SOUND               "AudioRec"
#define COMMON_KEY_VOICE_CONTROL			"Speech"
#define COMMON_KEY_SPK_VOLUME_LEVEL			"SpkVol"
#define COMMON_KEY_VIDEO_CLIP_TIME          "VideoClipTime"
#define COMMON_KEY_DATETIME_FMT             "TimeFormat"	//YMD MDY DMY
#define COMMON_KEY_BOOTSOUND				"BootSound"			//开机音
#define COMMON_KEY_MOVIE_QUALITY			"ImageQuality"	//目前用作rtsp图像质量设置,高为720p,其他为408p
#define COMMON_KEY_MOVIE_SIZE				"Resolution"
#define COMMON_KEY_GSENSOR_SENS             "EmergencyLev"
#define COMMON_KEY_GSENSOR_PWR_ON_SENS      "ParkingLev"
#define COMMON_KEY_ADAS_ONOFF				"ADAS"
#define COMMON_KEY_TIMELAPSE                "DrivingTimeLapse"
#define COMMON_KEY_PARK_TIMELAPSE           "ParkingTimeLapse"
#define COMMON_KEY_POWER_OFF_TIME			"AutoPoweroff"
#define COMMON_KEY_WDR_EN                   "WDR"
#define COMMON_KEY_HDR_EN                   "HDR"
#define COMMON_KEY_STICKER_EN				"TimeStamp"		//all stamp, 水印开关
#define COMMON_KEY_LANGUAGE                 "Language"
#define COMMON_KEY_WIFI_POWER_ON			"PowerOnWifi"
#define COMMON_KEY_STICKER_GPS				"GpsStamp"			//gps
#define COMMON_KEY_SPEED_UNIT 				"SpeedUnit"			//速度单位
#define COMMON_KEY_BEEP                     "Beep"
#define COMMON_KEY_FLICKER                  "Flicker"
#define COMMON_KEY_LCD_POWERS               "LCDPowerSave"			//屏保时间
#define COMMON_KEY_TIME_ZONE                "TimeZone"
#define COMMON_KEY_ENCODE_H265  			"EnCodingType"
#define COMMON_KEY_EXIST_NEW_PARKING_VIDEO  "NewParkingVideo"#define COMMON_KEY_MIC_SENSITIVITY			"Menu.MicSensitivity"
#define COMMON_KEY_VMD_REC_TIME             "Menu.MotionVideoTime"
#define COMMON_KEY_NIGHT_MODE_EN 			"Menu.NightMode"
#define COMMON_KEY_PARK_TYPE                "Menu.ParkType"
#define COMMON_KEY_ADAS_MAINACTIVITYMARK	"Menu.AdasMark"  //实景标注(车道线,前车框)
#define COMMON_KEY_LDWS_EN                  "Menu.LDWS"
#define COMMON_KEY_FCWS_EN                  "Menu.FCWS"
#define COMMON_KEY_SAG_EN                   "Menu.SAG"
#define COMMON_KEY_GPSSYNCTIME              "Menu.SyncTime"
#define COMMON_KEY_STICKER_LOGO_TXT         "Menu.TimeStampLogoTXT"  //logo
#define COMMON_KEY_STICKER_SPEED			"Menu.SpeedStamp"		//speed, 包括gps
#define COMMON_KEY_DISTANCE_UINT            "Menu.DistanceUnit"
#define COMMON_KEY_WIFI_EN                  "Menu.WiFi"
#define COMMON_KEY_SPEED_CAM_ALERT  		"Menu.SpeedCamAlert"
#define COMMON_KEY_SYNC_TIME				"Menu.SyncTime"
#define COMMON_KEY_EV						"Menu.EV"
#define COMMON_KEY_ISO						"Menu.ISO"
#define COMMON_KEY_SPEED_LIMIT 				"SpeedLimit"
#define COMMON_KEY_MOTION_SENS              "Menu.MotionSensitivity"
#define COMMON_KEY_EDOG_EN              	"Menu.EDOG"
#define COMMON_KEY_NULL              		"Set.NULL"
#define COMMON_KEY_TODO              		"Set.TODO"
#define COMMON_VAL_SETTINGS_VERSION    		"Ver.HIS.01"
#else
#define COMMON_KEY_REARMIRROR               "Camera.Menu.RearMirror"
#define COMMON_KEY_MOTIONDETECTION          "Camera.Menu.MTD"
#define COMMON_KEY_MOVIE_SIZE				"Camera.Menu.Videores"
#define COMMON_KEY_MOVIE_QUALITY			"Camera.Menu.VideoQuality"
#define COMMON_KEY_MIC_SENSITIVITY			"Camera.Menu.MicSensitivity"
#define COMMON_KEY_VIDEO_CLIP_TIME          "Camera.Menu.LoopingVideo"
#define COMMON_KEY_RECD_SOUND               "Camera.Menu.GetMic"
#define COMMON_KEY_VMD_REC_TIME             "Camera.Menu.MotionVideoTime"
#define COMMON_KEY_TIMELAPSE                "Camera.Menu.Timelapse"
#define COMMON_KEY_PARK_TIMELAPSE           "Camera.Menu.ParkTimelapse"//"not_use"
#define COMMON_KEY_HDR_EN                   "Camera.Menu.HDR"
#define COMMON_KEY_WDR_EN                   "Camera.Menu.WDR"
#define COMMON_KEY_NIGHT_MODE_EN 			"Camera.Menu.NightMode"
#define COMMON_KEY_PARK_TYPE                "Camera.Menu.ParkType"
#define COMMON_KEY_ADAS_MAINACTIVITYMARK	"Camera.Menu.AdasMark"  //实景标注(车道线,前车框)
#define COMMON_KEY_ADAS_ONOFF				"Camera.Menu.ADAS"
#define COMMON_KEY_LDWS_EN                  "Camera.Menu.LDWS"
#define COMMON_KEY_FCWS_EN                  "Camera.Menu.FCWS"
#define COMMON_KEY_SAG_EN                   "Camera.Menu.SAG"
#define COMMON_KEY_BEEP                     "Camera.Menu.Beep"
#define COMMON_KEY_GPSSYNCTIME              "Camera.Menu.SyncTime"
#define COMMON_KEY_DATETIME_FMT          	"Camera.Menu.TimeFormat"
#define COMMON_KEY_STICKER_LOGO_TXT         "Camera.Menu.TimeStampLogoTXT"  //logo
#define COMMON_KEY_STICKER_GPS				"Camera.Menu.GpsStamp"			//gps
#define COMMON_KEY_STICKER_SPEED			"Camera.Menu.SpeedStamp"		//speed, 包括gps
#define COMMON_KEY_STICKER_EN          		"Camera.Menu.TimeStamp"
#define COMMON_KEY_LANGUAGE                 "Camera.Menu.Language"
#define COMMON_KEY_FLICKER                  "Camera.Menu.Flicker"
#define COMMON_KEY_LCD_POWERS               "Camera.Menu.LCDPower"			//屏保时间
#define COMMON_KEY_GSENSOR_SENS             "Camera.Menu.GSensor"
#define COMMON_KEY_GSENSOR_PWR_ON_SENS      "Camera.Menu.GSensorPowerOnSens"
#define COMMON_KEY_TIME_ZONE                "Camera.Menu.TimeZone"
#define COMMON_KEY_SPEED_UNIT 				"Camera.Menu.SpeedUnit"			//速度单位
#define COMMON_KEY_DISTANCE_UINT            "Camera.Menu.DistanceUnit"
#define COMMON_KEY_ENCODE_H265  			"Camera.Menu.EnCodingH265"
#define COMMON_KEY_USER_GUIDE_MODE			"Camera.Menu.UserGuide"
#define COMMON_KEY_WIFI_POWER_ON			"Camera.Menu.PwrOnWifi"
#define COMMON_KEY_WIFI_EN                  "Camera.Menu.WiFi"
#define COMMON_KEY_SPEED_CAM_ALERT  		"Camera.Menu.SpeedCamAlert"
#define COMMON_KEY_BOOTSOUND				"Camera.Menu.BootSound"			//开机音
#define COMMON_KEY_VOICE_CONTROL			"Camera.Menu.GetSpeechSens"
#define COMMON_KEY_SPK_VOLUME_LEVEL			"Camera.Menu.GetVol"
#define COMMON_KEY_SYNC_TIME				"Camera.Menu.SyncTime"
#define COMMON_KEY_POWER_OFF_TIME			"Camera.Menu.PowerOffDelay"
#define COMMON_KEY_EV						"Camera.Menu.EV"
#define COMMON_KEY_ISO						"Camera.Menu.ISO"
#define COMMON_KEY_SPEED_LIMIT 				"SpeedLimit"
#define COMMON_KEY_MOTION_SENS          		"Camera.Menu.MTD1"
#define COMMON_KEY_EDOG_EN              	"Camera.Menu.EDOG"
#define COMMON_KEY_NULL              		"Camera.Menu.NULL"
#define COMMON_KEY_TODO              		"Camera.Menu.TODO"
#define COMMON_KEY_EXIST_NEW_PARKING_VIDEO  "System.ExistNewParkingVideo"
#define COMMON_VAL_SETTINGS_VERSION    		"Ver.MSTAR.01"
#endif
#define COMMON_KEY_SYS_INFO_PROJECT  		"sys.info.proj"
#define COMMON_KEY_SYS_INFO_CUSTOMER  		"sys.info.cust"
#define COMMON_KEY_SYS_INFO_VERSION  		"sys.info.ver"
#define COMMON_KEY_SYS_INFO_BUILT_DATE 		"sys.info.date"   //编译时间
#define COMMON_KEY_SETTINGS_VERSION         "Systme.Set.Ver"  //系统设置版本 = COMMON_VAL_SETTINGS_VERSION
#define COMMON_KEY_WIFI_BAND                "Camera.WiFi.Band"			//ON:5G, OFF:2.4G
#define COMMON_KEY_WIFI_SSID             	"Camera.WiFi.SSID"
#define COMMON_KEY_WIFI_PASSWD              "Camera.WiFi.PassWD"
#define COMMON_KEY_WIFI_SECURITY            "Camera.WiFi.Security"
#define COMMON_KEY_APP_TOKEN            	"Camera.APP.Token"
#define COMMON_KEY_APP_DID            		"Camera.APP.DID"
#define COMMON_KEY_APP_TOKEN2            	"Camera.WiFi.Token2"		//支持绑定2个手机
#define COMMON_KEY_APP_DID2            		"Camera.APP.DID2"			//支持绑定2个手机
#define COMMON_KEY_FIRST_ENTER_BROWSER		"System.FirstEnterBrowser"
#define COMMON_KEY_ENTER_PARKING_TIME		"System.EnterParkingTime"
#define COMMON_KEY_REAR_CAM_CONNECT_STATUS  "System.RearCamConnStatus"
#define COMMON_KEY_FACTORY_MODE				"System.FactoryMode"			//UI检测到此key为ON时,需要与正常模式区分显示,让工厂能够一眼看出还处于工厂模式, 产测模式的时候指示灯也应该RGB循环闪烁
#define COMMON_KEY_FACTORY_AGING_TEST_TIME	"System.FactoryAgingTestTime"typedef enum _LANGUAGE_ID_E
{ID_LANGUAGE_ENGLISH = 0,ID_LANGUAGE_RUSSIAN,ID_LANGUAGE_JAPANESE,ID_LANGUAGE_KOREAN,ID_LANGUAGE_SPANISH,ID_LANGUAGE_PORTUGUESE,ID_LANGUAGE_SCHINESE,ID_LANGUAGE_TCHINESE,ID_LANGUAGE_POLISH,ID_LANGUAGE_THAI,ID_LANGUAGE_GERMAN,ID_LANGUAGE_AUTO,
}LANGUAGE_ID_E;typedef enum{TIME_FORMAT_Y_M_D = 0,TIME_FORMAT_M_D_Y,TIME_FORMAT_D_M_Y,
}TIME_DAET_FORMAT_E;  //sync to mstar define
typedef enum{SPEED_UNIT_KMH = 0,  //km/hSPEED_UNIT_MPH,SPEED_UNIT_MAX
}SPEED_UNIT_E;#define SETTINGS_ENTRY_ARROW_SIZE		48  //sync kernel uboot
typedef struct _entry {  //修改此结构同时需要修改驱动中的结构char pkey[SETTINGS_ENTRY_ARROW_SIZE];char pval[SETTINGS_ENTRY_ARROW_SIZE];
} ENTRY,*PENTRY;
typedef struct _entryEx {  //修改此结构同时需要修改驱动中的结构int len;char pval[SETTINGS_ENTRY_ARROW_SIZE];
} ENTRY_EX,*PENTRY_EX;
#define NVRAM_MAGIC_S       (('A')|('P'<<8)|('K'<<16)|('S'<<24))
#define NVRAM_MAGIC_E       (('S')|('K'<<8)|('P'<<16)|('A'<<24))
#pragma pack(1) 
typedef struct _nvconfhdr {  //修改此结构同时需要修改驱动中的结构int magicnumS;int crcnum;int len;int magicnumE;char newLine; //always \n
} NVHDR, *PNVHDR;
#pragma pack() //设置驱动存储设置结构体的个数,一般cardv中设置
int Settings_SetKeyNums(unsigned char nums);
int Settings_GetKeyNums(unsigned char* nums);//cardv: bLoad=1, other bLoad=0
int Settings_Start(int bLoad);//cardv: bSave=1, other bSave=0
int Settings_Stop(int bSave);int Settings_ResetToDefault();
int Settings_ShowAll(char* key, char* strOut, int outsize);int Settings_Set(const char* key, const char* str);
int Settings_SetInt(const char* key, int val);
int Settings_CompStr(char* str1, char* str2);//strVal 至少64字节
int Settings_GetAndCompStr(const char* key, const char* str);
int Settings_GetKeyStrValEx(const char* key, char* strVal, int len);
int Settings_GetKeyStrVal(const char* key, char* strVal, int len);
int Settings_GetKeyIntVal(const char* key,           int* pInt);
int Settings_GetPosVal(unsigned char pos, ENTRY* pentry);
int Settings_GetKeys(const char* key, char* strVal, int strValSize); //可以用*通配符 eg. Settings_GetKeys("Camera.Menu.*", str, len);int Settings_DelKey(const char* key);
int Settings_DelKey_ByPos(unsigned char poss);//一般情况下由cardv在Settings_Stop时保存
int Settings_Save(char* pPath, int bBackUp);//只申请真正关机的关机源
int ReqPwrOffSrcToDriver(POWEROFF_RES res);
int RelPwrOffSrcToDriver(POWEROFF_RES res);int Settings_Lev_Str2Int(char* str);
char* Settings_Lev_Int2Str(int lev);
int Settings_Time_Str2Int(char* str);
char* Settings_Time_Int2Str(int time);int Settings_BackUp(char* strBackUpPath, char* pPath);
int Settings_Recovery(char* strBackUpPath);#ifdef __cplusplus
}
#endif#endif //_SETTINGS_MANAGER_H_

5、使用方法说明

5.1在cardv进程如何使用

初始化的时候调用:Settings_Start

退出的时候调用:Settings_Stop

保存的时候调用:Settings_Save

设置一个设置项:Settings_Set

5.2在UI进程如何使用

设置一个设置项:Settings_Set

这篇关于Linux进程间通信-杂项设备驱动buf共享的方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/689841

相关文章

AJAX请求上传下载进度监控实现方式

《AJAX请求上传下载进度监控实现方式》在日常Web开发中,AJAX(AsynchronousJavaScriptandXML)被广泛用于异步请求数据,而无需刷新整个页面,:本文主要介绍AJAX请... 目录1. 前言2. 基于XMLHttpRequest的进度监控2.1 基础版文件上传监控2.2 增强版多

Docker镜像修改hosts及dockerfile修改hosts文件的实现方式

《Docker镜像修改hosts及dockerfile修改hosts文件的实现方式》:本文主要介绍Docker镜像修改hosts及dockerfile修改hosts文件的实现方式,具有很好的参考价... 目录docker镜像修改hosts及dockerfile修改hosts文件准备 dockerfile 文

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

Win11安装PostgreSQL数据库的两种方式详细步骤

《Win11安装PostgreSQL数据库的两种方式详细步骤》PostgreSQL是备受业界青睐的关系型数据库,尤其是在地理空间和移动领域,:本文主要介绍Win11安装PostgreSQL数据库的... 目录一、exe文件安装 (推荐)下载安装包1. 选择操作系统2. 跳转到EDB(PostgreSQL 的

Linux换行符的使用方法详解

《Linux换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa