地瓜RDK S100平台Ofilm ISX031相机内参读取方案

  1. 内参表格示例

2. isx031驱动

cpp 复制代码
diff --git a/drivers/sensor/isx031std/inc/isx031std_setting.h b/drivers/sensor/isx031std/inc/isx031std_setting.h
index cc65f41..4452264 100644
--- a/drivers/sensor/isx031std/inc/isx031std_setting.h
+++ b/drivers/sensor/isx031std/inc/isx031std_setting.h
@@ -17,6 +17,7 @@ uint8_t ext_trig_mfp
 #define FLASH_ADDR     2   // 0x00000
 #define FLASH_ADDR1 1   // 0xC0000
 #define FLASH_ADDR3 3   // 0xC8000
+#define FLASH_ADDR4 4   // 0x80000
 
 enum MODE_TYPE {
        HIKVISION_M24F217D4P0A2_S2R0T8E5,
@@ -32,7 +33,7 @@ enum MODE_TYPE {
        LC032_M24F100D4P1A1_S0R0T8E3,     // 10
        SHINE_M25F200D4P1A1_S2R0T8E5,     // 11
        BLDCAS_M25F198D4P1A1_S2R0T8E5,    // 12
-       OFILM_M24F200D4P1A1_S2R7T8E3,    // 13
+       OFILM_M24F200D4P0A4_S2R7T8E3,    // 13
        MODE_TYPE_MAX,
        MODE_TYPE_NUM,
 };
diff --git a/drivers/sensor/isx031std/isx031std_utility.c b/drivers/sensor/isx031std/isx031std_utility.c
index 4903fd0..9461b13 100755
--- a/drivers/sensor/isx031std/isx031std_utility.c
+++ b/drivers/sensor/isx031std/isx031std_utility.c
@@ -28,10 +28,10 @@
 #define I2C_SMBUS_BLOCK_MAX 32
 #endif
 
-#define EFL_X_ADDR_031     (0x00)
-#define EFL_Y_ADDR_031     (0x04)
-#define COD_X_ADDR_031     (0x08)
-#define COD_Y_ADDR_031     (0x12)
+#define EFL_X_ADDR_031     (0x07)
+#define EFL_Y_ADDR_031     (0x0B)
+#define COD_X_ADDR_031     (0x6F)
+#define COD_Y_ADDR_031     (0x73)
 #define K1_ADDR_031        (0x1C)
 #define K2_ADDR_031        (0x20)
 #define P1_ADDR_031        (0xD0)
@@ -40,6 +40,32 @@
 #define K4_ADDR_031        (0x30)
 #define K5_ADDR_031        (0xF0)
 #define K6_ADDR_031        (0xF8)
+// Ultron_W project
+#define C1_ADDR_031        (0x13)
+#define C2_ADDR_031        (0x17)
+#define C3_ADDR_031        (0x1B)
+#define C4_ADDR_031        (0x1F)
+#define C5_ADDR_031        (0x23)
+#define A1_ADDR_031        (0x2B)
+#define A2_ADDR_031        (0x2F)
+#define A3_ADDR_031        (0x33)
+#define A4_ADDR_031        (0x37)
+#define A5_ADDR_031        (0x3B)
+#define A6_ADDR_031        (0x3F)
+#define A7_ADDR_031        (0x43)
+#define A8_ADDR_031        (0x47)
+#define A9_ADDR_031        (0x4B)
+#define A10_ADDR_031       (0x4F)
+#define A11_ADDR_031       (0x53)
+#define A12_ADDR_031       (0x57)
+#define A13_ADDR_031       (0x5B)
+
+#define AFFINE_C_ADDR_031  (0x5F)
+#define AFFINE_D_ADDR_031  (0x63)
+#define AFFINE_E_ADDR_031  (0x67)
+
+#define SERIAL_NUM_ADDR_031 (0x49)
+
 
 #define INTRIN_DATA_SIZE    58
 #define STR_LEN                128
@@ -159,7 +185,7 @@ static emode_data_t emode_data[MODE_TYPE_MAX] = {
                .serial_rclk_out = 0,
                .rclk_mfp = 0,
        },
-       [OFILM_M24F200D4P1A1_S2R7T8E3] = {
+       [OFILM_M24F200D4P0A4_S2R7T8E3] = {
                .serial_addr = 0x40,
                .sensor_addr = 0x1a,
                .serial_rclk_out = 1,
@@ -181,7 +207,7 @@ static const sensor_emode_type_t sensor_emode[MODE_TYPE_NUM] = {
        SENSOR_EMADD(LC032_M24F100D4P1A1_S0R0T8E3, "0.0.1", "NULL", "NULL", &emode_data[LC032_M24F100D4P1A1_S0R0T8E3]),
        SENSOR_EMADD(SHINE_M25F200D4P1A1_S2R0T8E5, "0.0.1","NULL", "NULL", &emode_data[SHINE_M25F200D4P1A1_S2R0T8E5]),
        SENSOR_EMADD(BLDCAS_M25F198D4P1A1_S2R0T8E5, "0.0.1","NULL", "NULL", &emode_data[BLDCAS_M25F198D4P1A1_S2R0T8E5]),
-       SENSOR_EMADD(OFILM_M24F200D4P1A1_S2R7T8E3, "0.0.1","NULL", "NULL", &emode_data[OFILM_M24F200D4P1A1_S2R7T8E3]),
+       SENSOR_EMADD(OFILM_M24F200D4P0A4_S2R7T8E3, "0.0.1","NULL", "NULL", &emode_data[OFILM_M24F200D4P0A4_S2R7T8E3]),
 
        SENSOR_EMEND(),
 };
@@ -1150,7 +1176,109 @@ static int flash_read(sensor_info_t *sensor_info, uint8_t addr,
        // Address settings of the Serial NOR Flash Device
        buf[0] = 0x00;
        buf[1] = 0x08;
-       buf[2] = 0x00;
+       buf[2] = 0x10;
+       buf[3] = 0x00;
+       // Execution of a subcommand
+       buf[4] = 0x5a;
+       buf_size = 5;
+
+       // Serial NOR Flash read request (Host -> Sensor)
+       ret = flash_i2c_write_retry(sensor_info->bus_num, sensor_info->sensor_addr,
+               reg_addr, reg_size, buf, buf_size);
+       if (ret < 0) {
+               vin_err("%s : Serial NOR FLash Read request failed\n",
+                       sensor_info->sensor_name);
+       }
+       (void)usleep(10 * 1000);
+
+       // Buffer read request (Host -> Sensor)
+       while (bytes > 0) {
+               memset(buf, 0, I2C_SMBUS_BLOCK_MAX);
+               reg_size = 2;
+               memset(reg_addr, 0, reg_size);
+               reg_addr[0] = 0x00;
+               reg_addr[1] = addr + offset;
+
+               if (bytes > I2C_SMBUS_BLOCK_MAX - reg_size) {
+                       buf_size = I2C_SMBUS_BLOCK_MAX - reg_size;
+                       ret = flash_i2c_read_retry(sensor_info->bus_num, sensor_info->sensor_addr,
+                               reg_addr, reg_size, buf, buf_size);
+                       if (ret < 0) {
+                               vin_err("%s : read reg_addr 0x%x for %d bytes failed\n",
+                                       sensor_info->sensor_name, reg_addr[1], buf_size);
+                       }
+               } else {
+                       buf_size = bytes;
+                       ret = flash_i2c_read_retry(sensor_info->bus_num, sensor_info->sensor_addr,
+                               reg_addr, reg_size, buf, buf_size);
+                       if (ret < 0) {
+                               vin_err("%s : read reg_addr 0x%x for %d bytes failed\n",
+                                       sensor_info->sensor_name, reg_addr[1], buf_size);
+                       }
+               }
+               memcpy(data + offset, buf, buf_size);
+               bytes -= buf_size;
+               offset += buf_size;
+       }
+       (void)usleep(10 * 1000);
+
+       // Serial NOR Flash access lock request (Host -> Sensor)
+       ret = hb_vin_i2c_write_reg16_data8(sensor_info->bus_num,
+               sensor_info->sensor_addr, 0xFFFF, 0xF5);
+       if (ret < 0) {
+               vin_err("%s : Serial NOR FLash Access lock request failed\n",
+                       sensor_info->sensor_name);
+       }
+       (void)usleep(2 * 1000);
+
+       return ret;
+}
+
+
+static int flash_read_2(sensor_info_t *sensor_info, uint8_t addr,
+       uint8_t* data, uint32_t bytes)
+{
+       int ret = 0;
+       uint8_t reg_addr[4] = {0};
+       uint8_t reg_size = 0;
+       uint8_t buf[I2C_SMBUS_BLOCK_MAX] = {0};
+       uint8_t buf_size = 0;
+       uint8_t offset = 0;
+
+       ret = flash_size_set(sensor_info);
+       if (ret < 0) {
+               vin_err("%s : Serial NOR FLash size set failed\n",
+                       sensor_info->sensor_name);
+       }
+
+       // Serial NOR Flash access unlock request (Host -> Sensor)
+       ret = hb_vin_i2c_write_reg16_data8(sensor_info->bus_num,
+               sensor_info->sensor_addr, 0xFFFF, 0xF4);
+       if (ret < 0) {
+               vin_err("%s : Serial NOR FLash Access unlock request failed\n",
+                       sensor_info->sensor_name);
+       }
+       (void)usleep(2 * 1000);
+
+       // Serial NOR Flash all read request (Host -> Sensor)
+       ret = hb_vin_i2c_write_reg16_data8(sensor_info->bus_num,
+               sensor_info->sensor_addr, 0xFFFF, 0xF7);
+       if (ret < 0) {
+               vin_err("%s : Serial NOR FLash Access request failed\n",
+                       sensor_info->sensor_name);
+       }
+       (void)usleep(2 * 1000);
+
+       // Serial NOR Flash Read Subcommand
+       reg_addr[0] = 0x80;
+       reg_addr[1] = 0x00;
+       reg_addr[2] = 0x01;
+       reg_size = 3;
+
+       // Address settings of the Serial NOR Flash Device
+       buf[0] = 0x00;
+       buf[1] = 0x08;
+       buf[2] = 0x20;
        buf[3] = 0x00;
        // Execution of a subcommand
        buf[4] = 0x5a;
@@ -1603,6 +1731,219 @@ ret_clear:
        return ret;
 }
 
+typedef enum {
+    WRITE_MODE_WRITE,
+    WRITE_MODE_APPEND,
+    WRITE_MODE_BINARY
+} WriteMode;
+
+static int write_to_file(const char *filepath, const char *content, WriteMode mode) {
+    if (filepath == NULL) {
+        vin_err("file path is null\n");
+        return -1;
+    }
+
+    if (content == NULL) {
+        vin_err("content is null\n");
+        return -2;
+    }
+
+    const char *open_mode;
+    switch (mode) {
+        case WRITE_MODE_WRITE:
+            open_mode = "w";
+            break;
+        case WRITE_MODE_APPEND:
+            open_mode = "a";
+            break;
+        case WRITE_MODE_BINARY:
+            open_mode = "wb";
+            break;
+        default:
+            open_mode = "w";
+    }
+
+    FILE *file = fopen(filepath, open_mode);
+    if (file == NULL) {
+        vin_err("Open file failed");
+        return -3;
+    }
+
+    int result = fprintf(file, "%s", content);
+
+    if (fclose(file) != 0) {
+        vin_err("Close file failed");
+        return -6;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief 将 BCD 码数组转换为十进制字符串
+ * @param bcd_buf   输入的 BCD 码数组
+ * @param len       数组长度
+ * @param out_str   输出字符串缓冲区
+ * @param out_size  输出缓冲区大小
+ * @param is_packed 是否为紧凑 BCD (true: 1字节存2数字, false: 1字节存1数字)
+ * @return int      成功返回输出的字符串长度,失败返回 -1
+ */
+int bcd_to_str(const uint8_t *bcd_buf, int len, char *out_str, int out_size, bool is_packed) {
+    if (!bcd_buf || !out_str || len <= 0 || out_size <= 0) {
+        return -1;
+    }
+
+    int str_idx = 0;
+
+    for (int i = 0; i < len; i++) {
+        uint8_t byte = bcd_buf[i];
+
+        if (is_packed) {
+            // --- 紧凑模式 (Packed BCD) ---
+            // 处理高4位 (十位)
+            uint8_t high = (byte >> 4) & 0x0F;
+            if (high <= 9) {
+                if (str_idx + 1 >= out_size) return -1; // 缓冲区溢出检查
+                out_str[str_idx++] = high + '0';
+            }
+
+            // 处理低4位 (个位)
+            uint8_t low = byte & 0x0F;
+            if (low <= 9) {
+                if (str_idx + 1 >= out_size) return -1;
+                out_str[str_idx++] = low + '0';
+            }
+        } else {
+            // --- 非紧凑模式 (Unpacked BCD) ---
+            // 直接使用 bcd_to_dec_single 转换整个字节
+            // 注意:非紧凑模式下,通常高4位为0或无效,只看低4位
+            // 但为了兼容你提供的函数,这里直接调用它
+            uint8_t val = bcd_to_dec_single(byte);
+
+            // 如果 val 是两位数 (例如 0x12 -> 12),需要拆分字符
+            if (val >= 10) {
+                if (str_idx + 2 >= out_size) return -1;
+                out_str[str_idx++] = (val / 10) + '0';
+                out_str[str_idx++] = (val % 10) + '0';
+            } else {
+                if (str_idx + 1 >= out_size) return -1;
+                out_str[str_idx++] = val + '0';
+            }
+        }
+    }
+
+    // 字符串结束符
+    if (str_idx >= out_size) return -1;
+    out_str[str_idx] = '\0';
+
+    return str_idx;
+}
+
+int32_t sensor_intrinsic_params_from_flash_addr4(sensor_info_t *si,
+                       sensor_intrinsic_parameter_t *sip)
+{
+       int ret = RET_OK;
+       uint8_t intrin_raw_data[308] = {0};
+       uint8_t intrin_raw_data_2[123] = {0};
+       char filepath[256] = {0};
+       char buffer[1024];
+       int result = 0;
+
+
+       ret = flash_read(si, 0x0, intrin_raw_data,
+               sizeof(intrin_raw_data));
+       if (ret < 0) {
+               vin_err("%s : flash_read failed\n", si->sensor_name);
+       }
+
+       sip->focal_u = float_trans_from_char(intrin_raw_data, EFL_X_ADDR_031);
+       sip->focal_v = float_trans_from_char(intrin_raw_data, EFL_Y_ADDR_031);
+       sip->center_u = float_trans_from_char(intrin_raw_data, COD_X_ADDR_031);
+       sip->center_v = float_trans_from_char(intrin_raw_data, COD_Y_ADDR_031);
+       sip->k1_2 = float_trans_from_char(intrin_raw_data, C1_ADDR_031);
+       sip->k2_2 = float_trans_from_char(intrin_raw_data, C2_ADDR_031);
+       sip->k3_2 = float_trans_from_char(intrin_raw_data, C3_ADDR_031);
+       sip->k4_2 = float_trans_from_char(intrin_raw_data, C4_ADDR_031);
+       sip->k14 = float_trans_from_char(intrin_raw_data, C5_ADDR_031);
+       sip->k1 = float_trans_from_char(intrin_raw_data, A1_ADDR_031);
+       sip->k2 = float_trans_from_char(intrin_raw_data, A2_ADDR_031);
+       sip->k3 = float_trans_from_char(intrin_raw_data, A3_ADDR_031);
+       sip->k4 = float_trans_from_char(intrin_raw_data, A4_ADDR_031);
+       sip->k5 = float_trans_from_char(intrin_raw_data, A5_ADDR_031);
+       sip->k6 = float_trans_from_char(intrin_raw_data, A6_ADDR_031);
+       sip->k7 = float_trans_from_char(intrin_raw_data, A7_ADDR_031);
+       sip->k8 = float_trans_from_char(intrin_raw_data, A8_ADDR_031);
+       sip->k9 = float_trans_from_char(intrin_raw_data, A9_ADDR_031);
+       sip->k10 = float_trans_from_char(intrin_raw_data, A10_ADDR_031);
+       sip->k11 = float_trans_from_char(intrin_raw_data, A11_ADDR_031);
+       sip->k12 = float_trans_from_char(intrin_raw_data, A12_ADDR_031);
+       sip->k13 = float_trans_from_char(intrin_raw_data, A13_ADDR_031);
+       sip->pp_x = float_trans_from_char(intrin_raw_data, AFFINE_C_ADDR_031);
+       sip->pp_y = float_trans_from_char(intrin_raw_data, AFFINE_D_ADDR_031);
+       sip->cam_skew = float_trans_from_char(intrin_raw_data, AFFINE_E_ADDR_031);
+
+       ret = flash_read_2(si, 0x0, intrin_raw_data_2,
+               sizeof(intrin_raw_data_2));
+       if (ret < 0) {
+               vin_err("%s : flash_read_2 failed\n", si->sensor_name);
+       }
+
+       bcd_to_str(intrin_raw_data_2 + SERIAL_NUM_ADDR_031, 8, sip->serial_num, 18, true);
+
+       // filepath = "/tmp/isx031_intrinsic_params.txt";
+       snprintf(filepath, sizeof(filepath), "/tmp/bus%d_cam%d_intrinsic_params.txt", si->deserial_index, si->deserial_port);
+       snprintf(buffer, sizeof(buffer), "SN:\n");
+       result = write_to_file(filepath, buffer, WRITE_MODE_WRITE);
+       if (result != 0) {
+               vin_err("SN title write failed\n");
+       }
+       // example SN: 2026030700009223
+       snprintf(buffer, sizeof(buffer), "%s\n", sip->serial_num);
+       result = write_to_file(filepath, buffer, WRITE_MODE_APPEND);
+       if (result != 0) {
+               vin_err("SN write failed\n");
+       }
+       snprintf(buffer, sizeof(buffer), "Intrinsic Params:\n");
+       result = write_to_file(filepath, buffer, WRITE_MODE_APPEND);
+       if (result != 0) {
+               vin_err("Intrinsic title write failed\n");
+       }
+       snprintf(buffer, sizeof(buffer), "focal_u: %f, focal_v: %f, center_u: %f, center_v: %f, c1: %f, c2: %f, c3: %f, c4: %f, c5: %f, a1: %f, a2: %f, a3: %f, a4: %f, a5: %f, a6: %f, a7: %f, a8: %f, a9: %f, a10: %f, a11: %f, a12: %f, a13: %f, affine_c: %f, affine_d: %f, affine_e: %f\n",
+               sip->focal_u, sip->focal_v, sip->center_u, sip->center_v,
+               sip->k1_2, sip->k2_2, sip->k3_2, sip->k4_2, sip->k14,
+               sip->k1, sip->k2, sip->k3, sip->k4, sip->k5,
+               sip->k6, sip->k7, sip->k8, sip->k9, sip->k10,
+               sip->k11, sip->k12, sip->k13, sip->pp_x, sip->pp_y, sip->cam_skew);
+       result = write_to_file(filepath, buffer, WRITE_MODE_APPEND);
+       if (result != 0) {
+               vin_err("Intrinsic write failed\n");
+       }
+       vin_info("Write to file %s done\n", filepath);
+
+       vin_info("Serial Number: %s\n", sip->serial_num);
+       vin_info("focal_u:%0.12f focal_v:%0.12f center_u:%0.12f center_v:%0.12f\n",
+                       sip->focal_u, sip->focal_v, sip->center_u, sip->center_v);
+       vin_info("c1:%0.12f c2:%0.12f c3:%0.12f c4:%0.12f c5:%0.12f\n",
+                       sip->k1_2, sip->k2_2, sip->k3_2, sip->k4_2, sip->k14);
+       vin_info("a1:%0.12f a2:%0.12f a3:%0.12f a4:%0.12f a5:%0.12f\n",
+                       sip->k1, sip->k2, sip->k3, sip->k4, sip->k5);
+       vin_info("a6:%0.12f a7:%0.12f a8:%0.12f a9:%0.12f a10:%0.12f\n",
+                       sip->k6, sip->k7, sip->k8, sip->k9, sip->k10);
+       vin_info("a11:%0.12f a12:%0.12f a13:%0.12f\n",
+                       sip->k11, sip->k12, sip->k13);
+       vin_info("affine_c:%0.12f affine_d:%0.12f affine_e:%0.12f\n",
+                       sip->pp_x, sip->pp_y, sip->cam_skew);
+
+// Register Access request (Host -> Sensor)
+       ret = hb_vin_i2c_write_reg16_data8(si->bus_num,
+               si->sensor_addr, 0xFFFF, 0x00);
+       if (ret < 0) {
+               vin_err("%s : Register Access request failed\n",
+                       si->sensor_name);
+       }
+       return RET_OK;
+}
+
 static int get_intrinsic_params_from_flash(sensor_info_t *si,
                sensor_intrinsic_parameter_t *sip)
 {
@@ -1631,6 +1972,9 @@ static int get_intrinsic_params_from_flash(sensor_info_t *si,
                case FLASH_ADDR3:
                        ret = sensor_intrinsic_params_from_flash_addr3(si, sip);
                break;
+               case FLASH_ADDR4:
+                       ret = sensor_intrinsic_params_from_flash_addr4(si, sip);
+               break;
                default:
                        return -1;
                break;
@@ -1848,14 +2192,14 @@ static int32_t get_intrinsic_params(sensor_info_t *si,
                break;
        }
 
-       vin_info("img_h:%d img_w:%d type:0x%x vendor:0x%x module_serial:0x%x\n",
-                       sip->image_height, sip->image_width, sip->cam_type, sip->vendor_id, sip->module_serial);
-       vin_info("focal_u:%0.12lf focal_v:%0.12lf center_u:%0.12lf center_v:%0.12lf\n",
-                       sip->focal_u, sip->focal_v, sip->center_u, sip->center_v);
-       vin_info("fov:%0.12lf k1:%0.12lf k2:%0.12lf p1:%0.12lf p2:%0.12lf\n",
-                       sip->hfov, sip->k1, sip->k2, sip->p1, sip->p2);
-       vin_info("k3:%0.12lf k4:%0.12lf k5:%0.12lf k6:%0.12lf, crc_group1:%d\n",
-                       sip->k3, sip->k4, sip->k5, sip->k6, sip->crc_group1);
+       // vin_info("img_h:%d img_w:%d type:0x%x vendor:0x%x module_serial:0x%x\n",
+       //              sip->image_height, sip->image_width, sip->cam_type, sip->vendor_id, sip->module_serial);
+       // vin_info("focal_u:%0.12lf focal_v:%0.12lf center_u:%0.12lf center_v:%0.12lf\n",
+       //              sip->focal_u, sip->focal_v, sip->center_u, sip->center_v);
+       // vin_info("fov:%0.12lf k1:%0.12lf k2:%0.12lf p1:%0.12lf p2:%0.12lf\n",
+       //              sip->hfov, sip->k1, sip->k2, sip->p1, sip->p2);
+       // vin_info("k3:%0.12lf k4:%0.12lf k5:%0.12lf k6:%0.12lf, crc_group1:%d\n",
+       //              sip->k3, sip->k4, sip->k5, sip->k6, sip->crc_group1);
 
        return ret;
 }
  1. sample vin
cpp 复制代码
< typedef struct cam_intrinsic_parameter_s {
<         uint8_t sn[40];
<         double focal_u;
<         double focal_v;
<         double center_u;
<         double center_v;
<         double c1;
<         double c2;
<         double c3;
<         double c4;
<         double c5;
<         double a1;
<         double a2;
<         double a3;
<         double a4;
<         double a5;
<         double a6;
<         double a7;
<         double a8;
<         double a9;
<         double a10;
<         double a11;
<         double a12;
<         double a13;
<         double affine_c;
<         double affine_d;
<         double affine_e;
< } cam_intrinsic_parameter_t;
< 
62,228d31
< // 从文件读取参数并填充到data结构体(只解析需要的参数)
< int read_cam_intrinsic_data(cam_intrinsic_parameter_t *data, const char *filename) {
<     if (filename == NULL) {
<         printf("get calibration file name is NULL\n");
<         return -1;
<     }
< 
<     // 打开文件
<     FILE* file = fopen(filename, "r");
<     if (!file) {
<         printf("Failed to open calibration file: %s", filename);
<         return -1;
<     }
< 
<     // 初始化数据
<     memset(data, 0, sizeof(cam_intrinsic_parameter_t));
< 
<     char line[256];
<     char param_line[1024];
<     bool found_sn = false;
<     bool found_params = false;
< 
<     // 根据相机类型确定要查找的标签
<     const char* target_label = "Intrinsic Params:";
< 
<     // 读取文件内容,只解析需要的部分
<     while (fgets(line, sizeof(line), file)) {
<         // 移除行尾的换行符
<         size_t len = strlen(line);
<         if (len > 0 && line[len - 1] == '\n') {
<             line[len - 1] = '\0';
<         }
< 
<         // 跳过空行
<         if (line[0] == '\0') {
<             continue;
<         }
< 
<         // 解析SN(只需要一次)
<         if (!found_sn && strncmp(line, "SN:", 3) == 0) {
<             char* sn_start = line + 3;
<             // 跳过空格
<             while (*sn_start == ' ') sn_start++;
< 
<             // 情况1: SN在同一行,如"SN: P008GYX5825E2B001"
<             if (*sn_start != '\0') {
<                 strncpy(&data->sn, sn_start, sizeof(data->sn) - 1);
<                 data->sn[sizeof(data->sn) - 1] = '\0';
<                 found_sn = true;
<             } else {// 情况2: SN在单独一行,如文件中的格式
<                 // 读取下一行作为SN
<                 if (fgets(line, sizeof(line), file)) {
<                     // 移除行尾的换行符和前导空格
<                     len = strlen(line);
<                     if (len > 0 && line[len - 1] == '\n') {
<                         line[len - 1] = '\0';
<                         len--;
<                     }
< 
<                     // 跳过前导空格
<                     int i = 0;
<                     while (i < len && line[i] == ' ') i++;
< 
<                     if (i < len) {  // 确保不是空行
<                         strncpy(&data->sn, line + i, sizeof(data->sn) - 1);
<                         data->sn[sizeof(data->sn) - 1] = '\0';
<                         found_sn = true;
<                     }
<                 }
<             }
< 
<             // 如果已经找到参数,可以提前退出
<             if (found_params) {
<                 break;
<             }
<             continue;
<         }
< 
<         // 查找目标参数标签
<         if (!found_params && strstr(line, target_label) != NULL) {
<             // 读取下一行参数(使用大缓冲区,因为该行很长)
<             if (fgets(param_line, sizeof(param_line), file)) {
<                 // 移除换行符
<                 len = strlen(param_line);
<                 if (len > 0 && param_line[len - 1] == '\n') param_line[len - 1] = '\0';
< 
<                 // 解析参数行
<                                 double focal_u;
<                                 double focal_v;
<                                 double center_u;
<                                 double center_v;
<                                 double c1;
<                                 double c2;
<                                 double c3;
<                                 double c4;
<                                 double c5;
<                                 double a1;
<                                 double a2;
<                                 double a3;
<                                 double a4;
<                                 double a5;
<                                 double a6;
<                                 double a7;
<                                 double a8;
<                                 double a9;
<                                 double a10;
<                                 double a11;
<                                 double a12;
<                                 double a13;
<                                 double affine_c;
<                                 double affine_d;
<                                 double affine_e;
< 
<                 int parsed = sscanf(param_line, 
<                     "focal_u: %lf, focal_v: %lf, center_u: %lf, center_v: %lf, c1: %lf, c2: %lf, c3: %lf, c4: %lf, c5: %lf, a1: %lf, a2: %lf, a3: %lf, a4: %lf, a5: %lf, a6: %lf, a7: %lf, a8: %lf, a9: %lf, a10: %lf, a11: %lf, a12: %lf, a13: %lf, affine_c: %lf, affine_d: %lf, affine_e: %lf",
<                     &focal_u, &focal_v, &center_u, &center_v, &c1, &c2, &c3, &c4, &c5, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11, &a12, &a13, &affine_c, &affine_d, &affine_e);
< 
<                 // if (parsed == 25) {
<                                 if (parsed == 25) {
<                     // 赋值给data结构体
<                     data->focal_u = focal_u;
<                                         data->focal_v = focal_v;
<                                         data->center_u = center_u;
<                                         data->center_v = center_v;
<                                         data->c1 = c1;
<                                         data->c2 = c2;
<                                         data->c3 = c3;
<                                         data->c4 = c4;
<                                         data->c5 = c5;
<                                         data->a1 = a1;
<                                         data->a2 = a2;
<                                         data->a3 = a3;
<                                         data->a4 = a4;
<                                         data->a5 = a5;
<                                         data->a6 = a6;
<                                         data->a7 = a7;
<                                         data->a8 = a8;
<                                         data->a9 = a9;
<                                         data->a10 = a10;
<                                         data->a11 = a11;
<                                         data->a12 = a12;
<                                         data->a13 = a13;
<                                         data->affine_c = affine_c;
<                                         data->affine_d = affine_d;
<                                         data->affine_e = affine_e;
<                                         found_params = true;
< 
<                     // 如果已经找到SN,可以提前退出
<                     if (found_sn) {
<                         break;
<                     }
<                 } else {
<                     printf("Failed to parse params, parsed %d parameters\n", parsed);
<                 }
<             }
<                         continue;
<         }
< 
<         // 如果已经找到SN和参数,提前退出循环
<         if (found_sn && found_params) {
<             break;
<         }
<     }
< 
<     fclose(file);
<     return 0;
< }
333,357d135
<         // 读取内参
<         cam_intrinsic_parameter_t intrinsic_params = {0};
<         char filepath[256] = {0};
<         snprintf(filepath, sizeof(filepath), "/tmp/bus%d_cam%d_intrinsic_params.txt", pipe_contex.csi_config.mipi_rx, (int)link_port);
<         printf("Reading intrinsic parameters from file: %s\n", filepath);
< 
<         ret = read_cam_intrinsic_data(&intrinsic_params, filepath);
<         if (ret != 0) {
<                 printf("Failed to read intrinsic parameters from file. ret = %d\n", ret);
<         } else {
<                 printf("Intrinsic parameters read successfully:\n");
<                 printf("SN: %s\n", intrinsic_params.sn);
<                 printf("focal_u: %0.24f, focal_v: %0.24f, center_u: %0.24f, center_v: %0.24f\n",
<                         intrinsic_params.focal_u, intrinsic_params.focal_v,
<                         intrinsic_params.center_u, intrinsic_params.center_v);
<                 printf("c1: %0.24f, c2: %0.24f, c3: %0.24f, c4: %0.24f, c5: %0.24f\n",
<                         intrinsic_params.c1, intrinsic_params.c2, intrinsic_params.c3,
<                         intrinsic_params.c4, intrinsic_params.c5);
<                 printf("a1: %0.24f, a2: %0.24f, a3: %0.24f, a4: %0.24f, a5: %0.24f, a6: %0.24f, a7: %0.24f, a8: %0.24f, a9: %0.24f, a10: %0.24f, a11: %0.24f, a12: %0.24f, a13: %0.24f\n",
<                         intrinsic_params.a1, intrinsic_params.a2, intrinsic_params.a3, intrinsic_params.a4, intrinsic_params.a5,
<                         intrinsic_params.a6, intrinsic_params.a7, intrinsic_params.a8, intrinsic_params.a9, intrinsic_params.a10, intrinsic_params.a11, intrinsic_params.a12, intrinsic_params.a13);
<                 printf("affine_c: %0.24f, affine_d: %0.24f, affine_e: %0.24f\n",
<                         intrinsic_params.affine_c, intrinsic_params.affine_d, intrinsic_params.affine_e);
<         }
< 
537c315
<                 printf("hbn_vnode_getframe %d CIM failed(%d)\n", (int)ochn_id, ret);
---
>                 printf("hbn_vnode_getframe %d CIM failed(%d)\n", ochn_id, ret);
544c322
<                          (int)vin_node_handle, (int)ochn_id,
---
>                          (int)vin_node_handle, ochn_id,
575c353
<                                 printf("Dump successful: %s (size: %ld)\n", dst_file, (long)sizeof(dst_file));
---
>                                 printf("Dump successful: %s (size: %ld)\n", dst_file, sizeof(dst_file));
590c368
<         char option;
---
>         char option = 'a';
602c380
<                                 break;
---
>                                 return;
相关推荐
不悔哥1 天前
开源 Zephyr:现代嵌入式 RTOS 长什么样
单片机·开源·嵌入式
the sun341 天前
CMSIS标准与各种库的发展历史+哈弗架构+CPU统一编址
stm32·架构·嵌入式
慧都小项3 天前
从 Figma 到 Qt:Qtitan 能减少哪些界面还原工作?
前端·qt·嵌入式·figma·图形界面·工业界面·qtitan
程序员打怪兽3 天前
完整的开发板使用流程
嵌入式
youcans_4 天前
【嵌入式软件AI编程】01. 基于 STM32/Claude Code的AI编程
stm32·mcu·嵌入式·ai编程·claude code
小智学长 | 嵌入式4 天前
实测GPT-6 Astra绘制硬件原理图和PCB效果分享
嵌入式·嵌入式开发·ai工具·单片机开发
一路往蓝-Anbo4 天前
第七篇:以太网设计 —— 从 RMII 时序到变压器隔离的深度拆解
stm32·单片机·嵌入式硬件·嵌入式·stm32硬件设计
玄奕子5 天前
三相逆变器系列(一):看懂三相全桥拓扑
嵌入式·dsp开发·电力电子·ti c2000·三相全桥逆变
the sun345 天前
嵌入式易错点:ARM指令架构、IP核、MCU厂商关系+BOOTLoader刷机原理
stm32·嵌入式