Android系统10 RK3399 init进程启动(十) parameter.txt 文件详解

本文详细解读了RK3399的parameter.txt参数文件,涉及固件版本、机器型号、分区信息和启动参数,对Android10.0 ROM系统开发者极具指导价值。

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

 配套系列教学视频链接:

      安卓系列教程之ROM系统开发-百问100ask

说明

系统:Android10.0

设备: FireFly RK3399 (ROC-RK3399-PC-PLUS)

前言

         在uboot启动,以及生成的所有镜像文件中, 有一个parameter.txt文件, 这个文件通过名字就知道, 参数文件, 肯定是和定制化和启动有关, 学习他很有必有, 本章重点介绍parameter.txt里的内容。


一,简介

ls rockdev/Image-rk3399_roc_pc_plus/

        paramete.txt 是瑞星微安卓系统平台对系统参数进行配置的文件,比如定义串口号,固件版本,机器型号,传递给内核参数存放位置,cmdline, 以及系统分区信息。

        parameter.txt对应的内容:

FIRMWARE_VER:10.0
MACHINE_MODEL:RK3399
MACHINE_ID:007
MANUFACTURER: RK3399
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 3399
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE: console=ttyFIQ0 androidboot.baseband=N/A androidboot.selinux=permissive androidboot.hardware=rk30board androidboot.console=ttyFIQ0 init=/init mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(trust),0x00002000@0x00006000(misc),0x00002000@0x00008000(dtbo),0x00000800@0x0000a000(vbmeta),0x00020000@0x0000a800(boot),0x00030000@0x0002a800(recovery),0x00038000@0x0005a800(backup),0x00002000@0x00092800(security),0x000c0000@0x00094800(cache),0x00008000@0x00154800(metadata),0x00000400@0x0015c800(frp),0x00714000@0x0015cc00(super),0x00100000@0x00870c00(oem),-@0x00970c00(userdata:grow)

 二, parameter.txt分析

FIRMWARE_VER:10.0

    Android固件版本,打包update.img 用到。升级工具据此识别固件版本。

MACHINE_MODEL: RK3399

    机型。

MACHINE_ID: 007

    产品 ID, 可以用于识别机器机型。

MANUFACTURER: RK3399

    厂商信息。

MAGIC: 0x5041524B

    魔幻数, 无法修改

ATAG: 0x00200800

    U-boot传递内核的参数存放内存位置,uboot对应一个atag结构体数组。

MACHINE: 3399

    内核识别用,不能修改

CHECK_MASK: 0x80

    内核识别用,无法修改。

PWR_HLD: 0,0,A,0,1

控制 GPIO0A0 输出高电平

CMDLINE

androidboot.baseband=N/A

通信基带的型号, 如APQ(是AP only的芯片,无modem,用于wifi only的平板), MSM(Mobile Station Modem)

androidboot.selinux=permissive(宽容) /enforcing(严格)/disable(关闭)

    Selinux权限模式, init进程会根据这个来决定设置selinux权限模式

androidboot.hardware=rk30board

    硬件平台

androidboot.console=ttyFIQ0

    串口定义

init=/init

祖先可执行程序路径

MTD分区信息:

mtdparts 的格式如下:

     mtdparts=<mtddef>[;<mtddef]     

     mtdparts 可以由一个或多个 mtddef 组成。每个mtddef定义如下:

     <mtddef> := <mtd-id>:<partdef>[,<partdef>]

     mtddef 可以由mtd-id 和一个或多个partdef组成,每个partdef定义如下:

     <partdef> := <size>[@offset][<name>][ro]

     <mtd-id> := unique id used in mapping driver/device

     <size> := standard linux memsize OR "-" to denote all remaining space

     <name> := (NAME)

因此在使用的时候,需要按照下面的格式来设置:

     mtdparts=mtd-id:<size1>@<offset1>(<name1>),<size2>@<offset2>(<name2>)

Rk3399中的分区表信息:

mtdparts=rk29xxnand:0x00002000@0x00002000(uboot),0x00002000@0x00004000(trust),0x00002000@0x00006000(misc),0x00002000@0x00008000(dtbo),0x00000800@0x0000a000(vbmeta),0x00020000@0x0000a800(boot),0x00030000@0x0002a800(recovery),0x00038000@0x0005a800(backup),0x00002000@0x00092800(security),0x000c0000@0x00094800(cache),0x00008000@0x00154800(metadata),0x00000400@0x0015c800(frp),0x00714000@0x0015cc00(super),0x00100000@0x00870c00(oem),-@0x00970c00(userdata:grow)

RK30xx,RK29xx,RK292x 都是用 rk29xxnand 做标识

@符号前是分区的大小, @符号后是分区的起始地址

括号中是分区的名字

单位都是 sector(512Bytes)

比如 uboot 起始地址为 0x2000 sectors (4MB)的位置,大小为 0x2000 sectors(4M)

另外 flash 最大的 block 是 4M(0x2000 sectors),所以每个分区需要 4MB 对齐,即每个分区必须为 4MB 的整数倍。

三,查看TF卡分区

通过windows下SD卡烧录工具烧录统一镜像(sd卡启动), 将TF插入到linux pc系统中就会发发现:

15个分区, 其实就对应于parameter.txt中mtdparts的描述。查看sd卡的容量信息: 
cat /proc/partitions (里面的单位是k)

fdisk也是可以查看分区信息: 
#/mnt/extend_disk/android_src/RK/rk3399_Android10.0$ sudo fdisk -l /dev/sdb
Disk /dev/sdb: 29.7 GiB, 31914983424 bytes, 62333952 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 23000000-0000-4C4A-8000-699000005ABB

设备         Start   末尾   扇区  Size 类型
/dev/sdb1     8192    16383     8192    4M 未知
/dev/sdb2    16384    24575     8192    4M 未知
/dev/sdb3    24576    32767     8192    4M 未知
/dev/sdb4    32768    40959     8192    4M 未知
/dev/sdb5    40960    43007     2048    1M 未知
/dev/sdb6    43008   174079   131072   64M 未知
/dev/sdb7   174080   370687   196608   96M 未知
/dev/sdb8   370688   600063   229376  112M 未知
/dev/sdb9   600064   608255     8192    4M 未知
/dev/sdb10  608256  1394687   786432  384M 未知
/dev/sdb11 1394688  1427455    32768   16M 未知
/dev/sdb12 1427456  1428479     1024  512K 未知
/dev/sdb13 1428480  8850431  7421952  3.6G 未知
/dev/sdb14 8850432  9899007  1048576  512M 未知
/dev/sdb15 9899008 62333887 52434880   25G 未知

查看某个特定分区的信息
cat /sys/block/sdb/sdb6/uevent
MAJOR=8
MINOR=22
DEVNAME=sdb6
DEVTYPE=partition
PARTN=6
PARTNAME=boot

 总结

通过理解parameter.txt, 是可以了解到系统的整个分区布局, 以及启动参数, 对理解烧录和启动都有很大帮助。

/************************************************************************** ** ** FILE Name : Flash_append ** ** Description : ** ** Date : 2025年3月2日 ** ** Author : XxX ** ** Note : **************************************************************************/ #include "Flash_append.h" /******************************************************************************** * @Function 擦除所有 flash 页 ,读取 flash 初始化 * @param * @return * @note * @Author ********************************************************************************/ void Flash_erase_all_page(void) { for(int i=0; i<32;i++) flash_erase_page(0,i); } void Read_init(void) { Parameter_read(); draw_read(); Read_servo_pid(); Camera_read(); } /********************************************************************** * @Function GPS数据的保存和读取 , Item科目选择 * @param * @return * @note * @Author **********************************************************************/ uint32 GPS_start_xy_buff[2 * 3]; //存储 三组数据 起点UTM值 缓冲区 uint32 Mark_Number_buff[1 * 3]; //存储 三组数据 采点个数 缓冲区 uint32 point_mark_buff_x[50 * 3]; //存储 三组数据 坐标点 缓冲区 uint32 point_mark_buff_y[50 * 3]; //存储 三组数据 坐标点 缓冲区 uint32 point_mark_state_buff[50 * 3]; //存储 三组数据 点位状态 缓冲区 void GPS_save(void) { GPS_start_xy_buff[0 + 2 * Item_mode] = (uint32)(int32)(GPS_start_y*1000); GPS_start_xy_buff[1 + 2 * Item_mode] = (uint32)(int32)(GPS_start_x*1000); mark_point_count = sets; Mark_Number_buff[1 * Item_mode] = mark_point_count; for ( int i = 0; i < 50; i++) { point_mark_buff_x[i + 50 * Item_mode] = (uint32)(int32)(point_mark[i].x*1000); //将采集到的GPS数据放大1000000倍(成为整型)放入buff缓存区 point_mark_buff_y[i + 50 * Item_mode] = (uint32)(int32)(point_mark[i].y*1000); //将采集到的GPS数据放大1000000倍(成为整型)放入buff缓存区 point_mark_state_buff[i + 50 * Item_mode] = (uint32)(int32)point_mark_state[i]; //存储点的状态 } if(flash_check(0,Start_Point)||flash_check(0,Mark_Number)||flash_check(0,GPS_Y_SEC)||flash_check(0,GPS_X_SEC)||flash_check(0,GPS_State)) { flash_erase_page(0,Start_Point); flash_erase_page(0,Mark_Number); flash_erase_page(0,GPS_X_SEC); flash_erase_page(0,GPS_Y_SEC); flash_erase_page(0,GPS_State); } flash_write_page(0, Start_Point, GPS_start_xy_buff, 2 * 3); system_delay_ms(5); flash_write_page(0, Mark_Number, Mark_Number_buff, 1 * 3); system_delay_ms(5); flash_write_page(0, GPS_X_SEC, point_mark_buff_x, 50 * 3); system_delay_ms(5); flash_write_page(0, GPS_Y_SEC, point_mark_buff_y, 50 * 3); system_delay_ms(5); flash_write_page(0, GPS_State, point_mark_state_buff, 50 * 3); system_delay_ms(5); LCD_ShowString(0,64 , " OK", RGB565_RED, RGB565_BLACK, IPS200_8X16_FONT, 1, IPS200_DEFAULT_CHAR_GAP); } void GPS_read(void) { flash_read_page(0, Start_Point, GPS_start_xy_buff, 2 * 3);//读取起点 system_delay_ms(5); flash_read_page(0, Mark_Number, Mark_Number_buff, 1 * 3);//读取踩点个数 system_delay_ms(5); flash_read_page(0, GPS_X_SEC, point_mark_buff_x, 50 * 3);//读取经度 system_delay_ms(5); flash_read_page(0, GPS_Y_SEC, point_mark_buff_y, 50 * 3);//读取纬度 system_delay_ms(5); flash_read_page(0, GPS_State, point_mark_state_buff, 50 * 3);//读取点位状态 system_delay_ms(5); GPS_start_y=(double)(int32)GPS_start_xy_buff[0 + 2 * Item_mode]/1000.0;//起点 GPS_start_x=(double)(int32)GPS_start_xy_buff[1 + 2 * Item_mode]/1000.0; mark_point_count = Mark_Number_buff[1 * Item_mode]; for(int i = 0; i < 50; i++) { point_mark[i].y = ((double)(int32)point_mark_buff_y[i + 50 * Item_mode])/1000.0;//gps点位 point_mark[i].x = ((double)(int32)point_mark_buff_x[i + 50 * Item_mode])/1000.0; point_mark_state[i] = (point_state_enum)point_mark_state_buff[i + 50 * Item_mode]; //存储点的状态 } } /******************************************************************************** * @Function 预设速度存储读取 * @param * @return * @note * @Author ********************************************************************************/ uint32 Preset_Speed_buff[9 * 3]; //各种情况的目标速度,存入flash void speed_save(void) { if(flash_check(0,Preset_Speed)) { flash_erase_page(0,Preset_Speed); } system_delay_ms(5); Preset_Speed_buff[0 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[0]*100); Preset_Speed_buff[1 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[1]*100); Preset_Speed_buff[2 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[2]*100); Preset_Speed_buff[3 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[3]*100); Preset_Speed_buff[4 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[4]*100); Preset_Speed_buff[5 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[5]*100); Preset_Speed_buff[6 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[6]*100); Preset_Speed_buff[7 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[7]*100); Preset_Speed_buff[8 + 9 * Item_mode] = (uint32)(int32)(speed.obstacle_speed[8]*100); flash_write_page(0 , Preset_Speed , Preset_Speed_buff , 9 * 3); } void speed_read(void) { flash_read_page(0 , Preset_Speed , Preset_Speed_buff , 9 * 3); system_delay_ms(5); speed.obstacle_speed[0] = ((float)(int32)Preset_Speed_buff[0 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[1] = ((float)(int32)Preset_Speed_buff[1 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[2] = ((float)(int32)Preset_Speed_buff[2 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[3] = ((float)(int32)Preset_Speed_buff[3 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[4] = ((float)(int32)Preset_Speed_buff[4 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[5] = ((float)(int32)Preset_Speed_buff[5 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[6] = ((float)(int32)Preset_Speed_buff[6 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[7] = ((float)(int32)Preset_Speed_buff[7 + 9 * Item_mode] )/100.0f; speed.obstacle_speed[8] = ((float)(int32)Preset_Speed_buff[8 + 9 * Item_mode] )/100.0f; } /******************************************************************************** * @Function 控制参数的保存和读取 * @param * @return * @note * @Author ********************************************************************************/ uint32 Controller_buff[9 * 3]; void control_save(void) { if(flash_check(0,Control_Parameter)) { flash_erase_page(0,Control_Parameter); } system_delay_ms(5); Controller_buff[0 + 9 * Item_mode] = (uint32)(int32)( control.stanley_k[0] * 100 ); Controller_buff[1 + 9 * Item_mode] = (uint32)(int32)( control.stanley_k[1] * 100 ); Controller_buff[2 + 9 * Item_mode] = (uint32)(int32)( control.stanley_ki * 100); Controller_buff[3 + 9 * Item_mode] = (uint32)(int32)( control.stanley_i_outmax * 100); Controller_buff[4 + 9 * Item_mode] = (uint32)(int32)( control.curvature_border * 100); Controller_buff[5 + 9 * Item_mode] = (uint32)(int32)( control.curvature_k * 100); Controller_buff[6 + 9 * Item_mode] = (uint32)(int32)( control.stanley_L * 100); Controller_buff[7 + 9 * Item_mode] = (uint32)(int32)( control.stanley_L_kv * 100); Controller_buff[8 + 9 * Item_mode] = (uint32)(int32)( control.stanley_L_kc * 100); flash_write_page(0 , Control_Parameter , Controller_buff , 9 * 3); } void control_read(void) { flash_read_page( 0 , Control_Parameter , Controller_buff , 9 * 3); system_delay_ms(5); control.stanley_k[0] = ((float)(int32)Controller_buff[0 + 9 * Item_mode]) / 100.0f; control.stanley_k[1] = ((float)(int32)Controller_buff[1 + 9 * Item_mode]) / 100.0f; control.stanley_ki = ((float)(int32)Controller_buff[2 + 9 * Item_mode]) / 100.0f; control.stanley_i_outmax = ((float)(int32)Controller_buff[3 + 9 * Item_mode]) / 100.0f; control.curvature_border = ((float)(int32)Controller_buff[4 + 9 * Item_mode]) / 100.0f; control.curvature_k = ((float)(int32)Controller_buff[5 + 9 * Item_mode]) / 100.0f; control.stanley_L = ((float)(int32)Controller_buff[6 + 9 * Item_mode]) / 100.0f; control.stanley_L_kv = ((float)(int32)Controller_buff[7 + 9 * Item_mode]) / 100.0f; control.stanley_L_kc = ((float)(int32)Controller_buff[8 + 9 * Item_mode]) / 100.0f; } /******************************************************************************** * @Function 特殊标志位保存和读取 * @param * @return * @note * @Author ********************************************************************************/ void Parameter_save(void) { if(flash_check(0,MEM_SEC_SET)) { flash_erase_page(0,MEM_SEC_SET); } system_delay_ms(5); flash_write_page(0,MEM_SEC_SET,Set_parameter,9); LCD_ShowString(0,64 , " OK", RGB565_yinguanglv, RGB565_BLACK, IPS200_8X16_FONT, 1, IPS200_DEFAULT_CHAR_GAP); } void Parameter_read(void) { flash_read_page(0,MEM_SEC_SET,Set_parameter,9); gps_angle_trust = ((float)Set_parameter[7])/100.0f; gps_dis_trust = ((float)Set_parameter[8])/100.0f; } /******************************************************************************** * @Function 路径规划保存与读取 * @param * @return * @note * @Author ********************************************************************************/ uint32 R_buff[3]; void draw_save(void) { if(flash_check(0,MEM_draw_R)) { flash_erase_page(0,MEM_draw_R); } system_delay_ms(5); R_buff[0] = (uint32)(int32)(draw_R*100); R_buff[1] = (uint32)(int32)(draw_rk1*100); R_buff[2] = (uint32)(int32)(draw_rk2*100); flash_write_page(0 , MEM_draw_R , R_buff, 3); LCD_ShowString(150, 128, "save", RGB565_yinguanglv, RGB565_BLACK, IPS200_8X16_FONT, 1,IPS200_DEFAULT_CHAR_GAP); } void draw_read(void) { flash_read_page(0 , MEM_draw_R , R_buff, 3); draw_R = ((float)(int32)R_buff[0])/100.f; draw_rk1 = ((float)(int32)R_buff[1])/100.f; draw_rk2 = ((float)(int32)R_buff[2])/100.f; } /******************************************************************************** * @Function 模糊的PID * @param * @return * @note * @Author ********************************************************************************/ void fuzzy_pid_save(void) { if(flash_check(0,MEM_SEC_FUZZY_PID)) { flash_erase_page(0,MEM_SEC_FUZZY_PID); } system_delay_ms(5); fuzzy_parameter[0]=(uint32)(int32)(e_max_Turning[0]*100); fuzzy_parameter[1]=(uint32)(int32)(e_min_Turning[0]*100); fuzzy_parameter[2]=(uint32)(int32)(kp_max_Turning[0]*100); fuzzy_parameter[3]=(uint32)(int32)(kp_min_Turning[0]*100); fuzzy_parameter[4]=(uint32)(int32)(ki_max_Turning[0]*100); fuzzy_parameter[5]=(uint32)(int32)(ki_min_Turning[0]*100); fuzzy_parameter[6]=(uint32)(int32)(kd_max_Turning[0]*100); fuzzy_parameter[7]=(uint32)(int32)(kd_min_Turning[0]*100); system_delay_ms(5); fuzzy_parameter[0+8]=(uint32)(int32)(e_max_Turning[1]*100); fuzzy_parameter[1+8]=(uint32)(int32)(e_min_Turning[1]*100); fuzzy_parameter[2+8]=(uint32)(int32)(kp_max_Turning[1]*100); fuzzy_parameter[3+8]=(uint32)(int32)(kp_min_Turning[1]*100); fuzzy_parameter[4+8]=(uint32)(int32)(ki_max_Turning[1]*100); fuzzy_parameter[5+8]=(uint32)(int32)(ki_min_Turning[1]*100); fuzzy_parameter[6+8]=(uint32)(int32)(kd_max_Turning[1]*100); fuzzy_parameter[7+8]=(uint32)(int32)(kd_min_Turning[1]*100); system_delay_ms(5); flash_write_page(0, MEM_SEC_FUZZY_PID, fuzzy_parameter, 16); system_delay_ms(5); LCD_ShowString(0, 280, "save_finish", RGB565_RED, RGB565_BLACK, IPS200_8X16_FONT, 1,IPS200_DEFAULT_CHAR_GAP); } /******************************************************************************** * @Function 角度环的三套PID速度环的三套PID * @param * @return * @note * @Author ********************************************************************************/ uint32 Direct_Motor[3] = {0}; // s三套内环GPS转向环PI,Kp1、Ki1;Kp2、Ki2(被放大100倍) void Save_motor_pid(void) { Direct_Motor[0]=(uint32)(int32)(PID_Motor.kp*100); Direct_Motor[1]=(uint32)(int32)(PID_Motor.ki*100); Direct_Motor[2]=(uint32)(int32)(PID_Motor.kd*100); if(flash_check(0,MEM_SEC_MOTOR)) { flash_erase_page(0,MEM_SEC_MOTOR); } flash_write_page(0, MEM_SEC_MOTOR, Direct_Motor, 3); } /******************************************************************************** * @Function 角度环的三套PID * @param * @return * @note * @Author ********************************************************************************/ uint32 Direct_Servo[6] = {0}; // s三套外环GPS转向环PI,Kp1、Ki1;Kp2、Ki2(被放大100倍) void Save_servo_pid(void) { Direct_Servo[0]=(uint32)(int32)(PID_Servo.kp[0]*100); Direct_Servo[1]=(uint32)(int32)(PID_Servo.ki[0]*100); Direct_Servo[2]=(uint32)(int32)(PID_Servo.kd[0]*100); Direct_Servo[3]=(uint32)(int32)(PID_Servo.kp[1]*100); Direct_Servo[4]=(uint32)(int32)(PID_Servo.ki[1]*100); Direct_Servo[5]=(uint32)(int32)(PID_Servo.kd[1]*100); if(flash_check(0,MEM_SEC_SERVO)) { flash_erase_page(0,MEM_SEC_SERVO); } flash_write_page(0, MEM_SEC_SERVO, Direct_Servo, 6); } void Read_servo_pid(void) { flash_read_page(0 , MEM_SEC_SERVO , Direct_Servo , 7); system_delay_ms(5); PID_Servo.kp[0]=(float)(int32)Direct_Servo[0]/100.0f; PID_Servo.ki[0]=(float)(int32)Direct_Servo[1]/100.0f; PID_Servo.kd[0]=(float)(int32)Direct_Servo[2]/100.0f; PID_Servo.kp[1]=(float)(int32)Direct_Servo[3]/100.0f; PID_Servo.ki[1]=(float)(int32)Direct_Servo[4]/100.0f; PID_Servo.kd[1]=(float)(int32)Direct_Servo[5]/100.0f; } /******************************************************************************** * @Function 摄像头参数的保存与读取 * @param * @return * @note * @Author ********************************************************************************/ uint32 Camera_parameter_buff[6]; void Camera_save(void) { Camera_parameter_buff[0] = (uint32)(int32)(SXT_rectangle_Servo_parameter_p * 1000); Camera_parameter_buff[1] = (uint32)(int32)(SXT_line_Servo_parameter_p * 1000); Camera_parameter_buff[2] = (uint32)(int32)(servo_SXT_trust * 1000); Camera_parameter_buff[3] = SXT_all_open_flag; Camera_parameter_buff[4] = SXT_control_flag; Camera_parameter_buff[5] = SXT_light; if(flash_check(0,Camera_Parameters)) { flash_erase_page(0,Camera_Parameters); } flash_write_page(0, Camera_Parameters, Camera_parameter_buff, 6); } void Camera_read(void) { flash_read_page(0, Camera_Parameters, Camera_parameter_buff, 6); system_delay_ms(5); SXT_rectangle_Servo_parameter_p = (float)(int32)Camera_parameter_buff[0]/1000.0f; SXT_line_Servo_parameter_p = (float)(int32)Camera_parameter_buff[1]/1000.0f; servo_SXT_trust = (float)(int32)Camera_parameter_buff[2]/1000.0f; SXT_all_open_flag = Camera_parameter_buff[3]; SXT_control_flag = Camera_parameter_buff[4]; SXT_light = Camera_parameter_buff[5]; } /******************************************************************************** * @Function 科目四参数的保存与读取 * @param * @return * @note * @Author ********************************************************************************/ uint32 Item_four_buff[10]; void Item_four_save(void){ } void Item_four_read(void){ }
最新发布
07-07
这段代码实现了一个嵌入式系统中用于 **Flash 存储与读取** 的模块,主要用于保存和读取 GPS 数据、PID 参数、摄像头参数、路径规划参数等关键配置信息。下面是对该文件的详细分析与解释。 --- ## 📌 文件结构概览 ```c #include "Flash_append.h" // 全局函数定义 void Flash_erase_all_page(void); void Read_init(void); // GPS 数据相关 uint32 GPS_start_xy_buff[2 * 3]; uint32 Mark_Number_buff[1 * 3]; ... void GPS_save(void); void GPS_read(void); // 预设速度 uint32 Preset_Speed_buff[9 * 3]; void speed_save(void); void speed_read(void); // 控制器参数 uint32 Controller_buff[9 * 3]; void control_save(void); void control_read(void); // 特殊标志位 void Parameter_save(void); void Parameter_read(void); // 路径规划 void draw_save(void); void draw_read(void); // 模糊 PID void fuzzy_pid_save(void); // 角度环 PID uint32 Direct_Motor[3]; void Save_motor_pid(void); // 转向伺服 PID uint32 Direct_Servo[6]; void Save_servo_pid(void); void Read_servo_pid(void); // 摄像头参数 uint32 Camera_parameter_buff[6]; void Camera_save(void); void Camera_read(void); // 科目四参数(暂未实现) uint32 Item_four_buff[10]; void Item_four_save(void); void Item_four_read(void); ``` --- ## 🔧 主要功能详解 ### ✅ `Flash_erase_all_page()` 遍历擦除前32个 flash 页面: ```c void Flash_erase_all_page(void) { for(int i=0; i<32;i++) flash_erase_page(0,i); } ``` - **用途:** 清空 Flash 数据区。 - **注意:** 实际使用时应谨慎调用,避免误删数据。 --- ### ✅ `Read_init()` 初始化所有 Flash 中的数据: ```c void Read_init(void) { Parameter_read(); draw_read(); Read_servo_pid(); Camera_read(); } ``` - **用途:** 系统启动时加载默认配置。 - **扩展建议:** 可加入校验机制确保数据完整性。 --- ### ✅ GPS 数据保存与读取 #### 缓冲区定义: ```c uint32 GPS_start_xy_buff[2 * 3]; uint32 point_mark_buff_x[50 * 3]; ``` #### `GPS_save()` 核心逻辑: - 将 GPS 坐标放大 1000 倍转为整型存储; - 判断目标扇区是否已写入,若存在则先擦除; - 写入 Flash; - 显示“OK”提示。 ```c flash_write_page(0, Start_Point, GPS_start_xy_buff, 2 * 3); ``` #### `GPS_read()` 核心逻辑: - 从 Flash 读取数据; - 还原浮点数坐标值。 ```c GPS_start_y = ((double)(int32)GPS_start_xy_buff[0 + 2 * Item_mode])/1000.0; ``` --- ### ✅ 预设速度保存与读取 - 使用 `Item_mode` 区分不同模式下的速度设置; - 放大 100 倍后写入 Flash; - 读取时还原为 float 类型。 --- ### ✅ 控制器参数保存与读取 - 支持 Stanley 控制器、曲率控制器等参数; - 同样采用放大 100 倍方式处理精度问题。 --- ### ✅ 特殊标志位(Set_parameter- 直接保存数组 `Set_parameter` 到 Flash; - 用于保存角度信任阈值等状态变量。 --- ### ✅ 路径规划参数(draw_R、draw_rk1、draw_rk2) - 用于画圆或曲线控制; - 同样采用放大 100 倍策略。 --- ### ✅ 模糊 PID 保存 - 存储模糊 PID 的上下限参数; - 放大 100 倍写入 Flash; - 适用于转向控制等场景。 --- ### ✅ 角度环 PID(电机与伺服) - 使用数组 `Direct_Motor` 和 `Direct_Servo` 存储 PID 参数; - 支持多组 PID 设置(如不同路况); - `Save_servo_pid()` 和 `Read_servo_pid()` 实现保存与恢复。 --- ### ✅ 摄像头参数保存与读取 - 包括伺服控制系数、信任度、开关状态等; - 扩展性强,便于后续添加更多摄像头相关配置。 --- ## ⚠️ 注意事项 | 项目 | 说明 | |------|------| | 数据类型转换 | 使用 `(uint32)(int32)` 强转防止溢出 | | 扇区管理 | `flash_write_page(page, offset, buffer, size)` 应确保不越界 | | 数据一致性 | 建议加入 CRC 或 Checksum 校验机制 | | 多模式支持 | `Item_mode` 是核心索引,需确保范围正确 | --- ## 💡 优化建议 | 改进方向 | 建议 | |----------|------| | 抽象封装 | 将 `save/read` 函数统一为模板函数 | | 数据结构 | 使用结构体代替多个独立数组 | | 错误处理 | 添加 Flash 操作失败后的重试机制 | | 日志输出 | 替换 LCD 提示为日志系统,便于调试 | | 接口统一 | 定义通用接口 `flash_save(uint8 page, void* data, uint16 size)` | --- ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旗浩QH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值