国民技术N32G430开发笔记(12)- IAP升级 Settings区域数据初始化

文章介绍了如何在不修改boot和App程序的基础上,通过预先初始化Settings区域数据来区分两个不同的软件版本。具体步骤包括创建setting.bin文件,设置编译选项,编写Makefile以生成可执行文件,并使用pyocd工具将生成的bin文件烧录到指定地址。同时,文章还展示了读取和设置单片机中version和board_name的代码示例。
摘要由CSDN通过智能技术生成

IAP升级 Settings区域数据初始化

1、假如,有两个产品,A产品跟B产品,硬件都一样,要求一个软件里的board_name为N32G430C8L7_STB_A,另一个软件里的board_name为N32G430C8L7_STB_B。
那我们如何在不改boot程序跟App程序的基础上,快速的使两个软件看上去不同呢?
这里我们将setting区域的数据提前初始化,通过c语言的文件流的操作方法,创建一个setting.bin文件,然后将setting区域存储的结构体初始化后写入setting.bin文件,然后通过pyocd烧录到0x08004000地址即可。

2、根目录创建Settings目录,并创建setting_init.c Makefile文件

在这里插入图片描述

3、Makefile文件,编译setting_init.c的脚本文件,主要作用是用gcc编译出setting可执行文件,然后执行生成setting.bin
Makefile

CC = gcc
SRC = $(wildcard *.c)
OBJ = $(addprefix $(BUILD_DIR)/,$(notdir $(SRC:.c=.o)))
#OBJ = $(patsubst %.c, %.o, $(SRC))

TRAGET = settings
BUILD_DIR = build

ifeq ($(PRODUCT_A), y)
APPLICATION_FLAGS += \
	-DUSER_PRODUCT_A
endif

ifeq ($(PRODUCT_B), y)
APPLICATION_FLAGS += \
	-DUSER_PRODUCT_B
endif

C_INCLUDES +=  \
	-I../Common/Flash \
	-I../Common/Settings \
	-I../Common

C_FLAG += -Wall -MD -MP -MF"$(@:%.o=%.d)"

C_FLAG += -DUSER_SETTING_IN_HOST
C_FLAG += $(APPLICATION_FLAGS)
 
all: $(BUILD_DIR) $(BUILD_DIR)/$(TRAGET)

$(BUILD_DIR)/$(TRAGET):$(OBJ) Makefile | $(BUILD_DIR) 
	$(CC)  $< -o $@

$(OBJ): $(SRC)  Makefile | $(BUILD_DIR) 
	$(CC) -c $(C_FLAG) $(C_INCLUDES) $< -o $@

$(BUILD_DIR):
	@-mkdir $@

clean:
	@rm -rf $(TRAGET)
	@rm -rf $(OBJ)
	@rm -rf $(BUILD_DIR)

-include $(wildcard $(BUILD_DIR)/*.d)

# *** EOF ***

4、setting_init.c文件

之前讲过system_info的结构体,这里只写了四个变量,当然你也可以添加更多。在setting_init.c文件里,初始化了version跟board_name 变量。

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "settings.h"
#include "flash.h"

MI_S32 get_current_times(MI_CHAR *c_time)
{
    time_t timep;
    struct tm *p;
    time(&timep);
    p = gmtime(&timep);

    sprintf(c_time,"%04d%02d%02d %02d%02d%02d",p->tm_year + 1900,p->tm_mon + 1,p->tm_mday,
                                            p->tm_hour + 8,p->tm_min,p->tm_sec);

    return 0;
}

MI_S32 main(int argc,char *argv[])
{
    system_info s_info;
    FILE *file;
    size_t w_size;

#ifdef USER_PRODUCT_A
    MI_CHAR *board_name = "N32G430C8L7_STB_A";
#endif

#ifdef USER_PRODUCT_B
    MI_CHAR *board_name = "N32G430C8L7_STB_B";
#endif

    memset(&s_info,0,sizeof(s_info));
    get_current_times(s_info.version);
    memcpy(s_info.board_name,board_name,strlen(board_name));

    printf(FONT_COLOR_BLUE"get current time %s\n"COLOR_NONE,s_info.version);
    printf(FONT_COLOR_BLUE"get board name %s\n"COLOR_NONE,s_info.board_name);

    file = fopen("./build/Settings.bin","wb");

    if (file == NULL)
    {
        printf(FONT_COLOR_YELLOW" open settings.bin error\n"COLOR_NONE);
        return -1;
    }
    w_size = fwrite((MI_U8 *)&s_info,1,sizeof(s_info),file);
    if (w_size == sizeof(system_info))
    {
        printf(FONT_COLOR_YELLOW" creat settings.bin Success!\n"COLOR_NONE);
    }
    fclose(file);
    return 0;
}

5、顶层的makefile修改

Top = ${shell pwd}
App = ${Top}/Application
BootLoader = ${Top}/Bootloader
Settings = ${Top}/Settings
#Bin = ${Top}/Bin

# A B版本的编译选项,在setting_init.c中使用
# 编译B版本setting.bin时,使用
# PRODUCT_A = n
# PRODUCT_B = y
export PRODUCT_A = y
export PRODUCT_B = n

all:  gd32 setting

# 编译setting_init.c 并执行编译出来的settings
setting:
	make -C ${Settings}
	cd ${Settings} && ./build/settings

gd32:
	make -C ${App}
	make -C ${BootLoader}

# cp ${BootLoader}/build/BootLoader.bin ${Top}/BinFiles/
# cp ${App}/build/Application.bin ${Top}/BinFiles/
	
# amp:
# 	cd ${Amp} && ./ampcreater
# 	cd ${AllBin} && ./allinone

clean:
	rm -rf ${App}/build/*
	rm -rf ${BootLoader}/build/*
	make clean -C ${Settings}
# rm -rf ${BinCreater}/*

gdboot:
	${info "start flash boot "}
	pyocd flash --erase auto --target N32G430C8L7 --base-address 0x8000000 --pack=./Nations.N32G430_DFP.1.0.0.pack ./Bootloader/build/Bootloader.bin

gdapp:
	${info "start flash Application "}
	pyocd flash --erase auto --target N32G430C8L7 --base-address 0x8006000 --pack=./Nations.N32G430_DFP.1.0.0.pack ./Application/build/Application.bin 

# 烧录settings.bin到flash的命令
gdsetting:
	${info "start flash settings "}
	pyocd flash --erase auto --target N32G430C8L7 --base-address 0x8004000 --pack=./Nations.N32G430_DFP.1.0.0.pack ./Settings/build/Settings.bin 

6、根目录执行make后,
A、
在这里插入图片描述
B、

在这里插入图片描述

执行make gdsetting 烧录两个setting.bin后分别验证,
结果如下:
B 、在这里插入图片描述
A、
在这里插入图片描述

注意,编译尽量先make clean;make

7、单片机读取version board_name的代码:

#include <string.h>
#include "settings.h"
#include "flash.h"

MI_BOOL system_info_get_version(MI_CHAR *version)
{
    system_info info;

    memset(&info,0,sizeof(info));
    n32_flash_read(SETTINGS_START_ADDRESS,(uint8_t *)&info,sizeof(info));
    memcpy(version,info.version,sizeof(info.version));

    return MI_TRUE;
}

MI_BOOL system_info_get_broad_name(MI_CHAR *name)
{
    system_info info;

    memset(&info,0,sizeof(info));
    n32_flash_read(SETTINGS_START_ADDRESS,(uint8_t *)&info,sizeof(info));
    memcpy(name,info.board_name,sizeof(info.board_name));

    return MI_TRUE;
}

MI_BOOL system_info_get_update_flag(MI_U8 *flag)
{
    system_info info;

    memset(&info,0,sizeof(info));
    n32_flash_read(SETTINGS_START_ADDRESS,(uint8_t *)&info,sizeof(info));
    *flag = info.update_flag;

    return MI_TRUE;
}

/**
 * 设置升级标志位的函数
*/
MI_BOOL system_info_set_update_flag(MI_U8 flag)
{
    system_info info;

    memset(&info,0,sizeof(info));
    n32_flash_read(SETTINGS_START_ADDRESS,(uint8_t *)&info,sizeof(info));
    info.update_flag = flag;

    //先清除system info 区域
    n32_flash_erase(SETTINGS_START_ADDRESS,SETTINGS_END_ADDRESS);
    n32_flash_write(SETTINGS_START_ADDRESS,(uint8_t *)&info,sizeof(info));

    return MI_TRUE;
}

main.c

#include <string.h>
#include "main.h"
#include "bsp_led.h"
#include "bsp_delay.h"
#include "usart.h"
#include "timer.h"
#include "pwm.h"
#include "key_input.h"
#include "flash.h"
#include "settings.h"
/**
 *\*\name   main.
 *\*\fun    main function.
 *\*\param  none.
 *\*\return none.
**/
int main(void)
{
	led_init();

	usart1_init();

	usart2_init();

	timer6_init();

	tim2_pwm_init();

	key_input_init();
	/* Delay 1s */
	SysTick_Delay_Ms(1000);

	MI_CHAR name[24] = {0};
	MI_CHAR version[48] = {0};

	system_info_get_broad_name(name);
	system_info_get_version(version);

	printf(FONT_COLOR_BLUE"from settings area read name  == %s\r\n"COLOR_NONE,name);
	printf(FONT_COLOR_BLUE"from settings area read version  == %s\r\n"COLOR_NONE,version);

	while(1)
	{
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值