S32K144启动流程分析

汽车ECU开发 2022-10-31 08:47

1. S32K144为NXP公司采用ARM内核(cortex-M4)IP和ARMv7-M架构集成的SOC。


2. 内存映射图

2.1 S32K144芯片内存映射图(memory map)

2.2 Cortex-M4内存映射图


Code,SRAM,RAM区域都能保存程序。ARM系统推荐使用Code段来保存执行程序。


3. 编程模型

3.1) Cortex-M4两种工作模式:

线程模式(Thread Model),应用程序正常执行的时候所在的模式,处理器每次reset重启后进入这个模式;异常处理模式(Handler Model),CPU异常处理的时候进入这个模式,当CPU执行完异常处理程序后会退回到Thread Model。


3.2) Cortex-M4两种特权级:

非特权级状态(Unprivileged),软件限制使用MSR和MRS指令,不能使用CPS指令。不能访问系统定时器,NVIC嵌套向量中断控制器和系统控制块。特权级状态(Privileged),能访问所有资源,使用所有指令。


3.3) Thread模式下,CONTROL寄存器控制软件执行在privileged或者unprivileged状态。unpriveleged 软件执行时可以通过 SVC 指令进行supervisor call进入privilieged software。


3.4) 处理器使用降栈。Thread mode下,CONTROL寄存器控制处理器使用main stack还是进程栈process stack。在Handler模式下,处理器只使用main stack。


3.5) 核寄存器(Core registers)


R0-R12为通用寄存器


特殊寄存器:

R13是堆栈寄存器(stack Pointer),在Thread mode下,COTROL寄存器的bit[1]控制stack pointer作为Main Stack Pointer(MSP 这个是reset 值)还是Process Stack Pointer(PSP)


note:reset后,处理器装载0x00000000地址处的四字节值到MSP寄存器。也就是说系统启动的时候,0地址处存放的是MSP寄存器的值。


R14是连接寄存器(Link Register),他存储子程序、函数调用、异常处理程序时的返回信息。reset重启时,处理器设置LR寄存器的默认值为0xFFFFFFFF。


R15是程序计数器(Program Counter PC)。存储当前程序地址。reset重启的时候,处理器装载0x00000004地址处的值到PC指针。


程序状态寄存器(Program Status Register),包括应用程序状态寄存器(Application Program Status Register APSR)、中断程序状态寄存器(IPSR)、异常程序状态寄存器(EPSR)。


4. startup_S32K144.S源代码分析:

4.1 上电启动

根据上面的分析,reset后处理器从0x00000000地址处取四字节值到MSP寄存器,也就是取 __StackTop标号的值到MSP寄存器。然后处理器装载0x00000004地址处的值(Reset_Handler标号代表的值)到PC指针,也就是程序跳转到Reset_Handler标号处开始运行。

__isr_vector:    .long   __StackTop                                      /* Top of Stack */    .long   Reset_Handler                                   /* Reset Handler */

 

4.2 关闭CPU全局中断

 通过汇编指令“cpsid i”,关闭 CPU 全局中断的目的是避免启动过程中中断的影响;因为此时中断向量表还未建立好,无法响应外设中断 

Reset_Handler:    cpsid   i               /* Mask interrupts */



4.3 清零R1-R12通用寄存器

每次复位后, CPU 内核寄存器的值是随机不确定的,所以需要将其清零。


note 1: 为什么清零r1-r7寄存器用ldr伪指令,而清除r8-r12寄存器是要用mov指令 ?

r1-r7是low registers,r8-r12是hight registers,参考ARMv7-M Architecture手册:

大多数16位指令指令只能访问R0-R7这8个通用寄存器(low registers);只有小部分的指令能访问R8-R15寄存器(high registers)


note2: LDR R,label 和 LDR R,=label的区别

LDR 是ARM中的指令,也是伪指令。当用 LDR r, =imd ;r 为寄存器, imd为立即数LDR 是一条伪指令。编译器会根据 立即数的大小,决定用 ldr 指令或者是mov或mvn指令。当imd能用mov或者mvn操作时,就将它翻译成一条mov或mvn指令。当imd大于mov或mvn能够操作的数时,编译器会将imd存在一个内存单元中,然后再用一条ldr指令加载这个内存单元的的值到寄存器中。


LDR r, label 和 LDR r, =label的区别:
LDR r, =label 会把label表示的值加载到寄存器中,而LDR r, label会把label当做地址,把label指向的地址中的值加载到寄存器中。譬如 label的值是 0x8000, LDR r, =label会将 0x8000加载到寄存器中,而LDR r, label则会将内存0x8000处的值加载到寄存器中。

    /* Init the rest of the registers */    ldr     r1,=0    ldr     r2,=0    ldr     r3,=0    ldr     r4,=0    ldr     r5,=0    ldr     r6,=0    ldr     r7,=0    mov     r8,r7    mov     r9,r7    mov     r10,r7    mov     r11,r7    mov     r12,r7

4.4 初始化堆栈

ARM Cortex M 系列 CPU 内核有 MSP PSP 两个 32-bit 的堆栈,由于中断和异常处理时使用 MSP 所以必须在发生中断/异常之前将其初始化,其初始化值来自默认向量表的 0 地址偏移,即 0x0000 地址存放的 4 个字节。

note: __StackTop是S32K144_64_flash.ld链接器脚本中定义标号,也就是0x20007000地址处,在SRAM中

    /* Initialize the stack pointer */    ldr     r0,=__StackTop    mov     r13,r0

 

/* S32K144_64_flash.ld */
/* Specify the memory areas */MEMORY{ /* Flash */ m_interrupts (RX) : ORIGIN = 0x00005000, LENGTH = 0x00000400 m_flash_config (RX) : ORIGIN = 0x00005400, LENGTH = 0x00000010 m_text (RX) : ORIGIN = 0x00005410, LENGTH = 0x0007FBF0
/* SRAM_L */ m_data (RW) : ORIGIN = 0x1FFF8000, LENGTH = 0x00008000
/* SRAM_U */ m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00007000}
//...
/* Initializes stack on the end of block */ __StackTop = ORIGIN(m_data_2) + LENGTH(m_data_2); __StackLimit = __StackTop - STACK_SIZE; PROVIDE(__stack = __StackTop);


4.5 系统初始化

在完成了以上堆栈初始化之后, CPU 就可以运行 C 代码了,所以此时通过调用定义在工程 SDK->platform->device->S32K144->startup 目录下的 system_S32K144.c 中的系统初始化函数--SystemInit():根据工程配置完成:1)CPU 内核 FPU 配置和使能(如果创建应用工程时选择浮点数运算使用硬件 FPU)

2)关闭看门狗(默认配置)

3)使能 CPU 内核指令缓冲(I-Cache)等 MCU 硬件平台配置。


#ifndef __NO_SYSTEM_INIT    /* Call the system init routine */    ldr     r0,=SystemInit    blx     r0#endif

我们么有选择使用FPU和CPU内核指令缓冲,所以主要介绍关闭看门狗操作:


4.5.1 配置CNT(Watchdog Counter Register)寄存器

往看门狗模块的CNT(Watchdog Counter Register)寄存器写入0xD928C520(FEATURE_WDOG_UNLOCK_VALUE)。为什么要写入这个值?

查看S32芯片手册:

Unlock sequence of writing 0xC520 and then 0xD928 for allowing updates to write-once configuration bits .

意思就是看门狗的默认配置是lock的,如果要改变看门狗的配置首先需要解锁:往CNT寄存器中写入

0xD928C520,然后再通过CS(Watchdog Control and Status Register)来配置看门狗模块。


4.5.2 配置CS(Watchdog Control and Status Register)

主要配置CS寄存器的四个功能


4.5.3 配置看门狗TOVAL寄存器

TOVAL是一个16位的超时寄存器(65535),也就是说是timeout65535个时钟周期,到点没有喂狗则产生看门狗复位。


  

/* system_S32K144.c */
/*FUNCTION********************************************************************** * * Function Name : SystemInit * Description : This function disables the watchdog, enables FPU * and the power mode protection if the corresponding feature macro * is enabled. SystemInit is called from startup_device file. * * Implements : SystemInit_Activity *END**************************************************************************/void SystemInit(void){/**************************************************************************/ /* FPU ENABLE*//**************************************************************************/#ifdef ENABLE_FPU /* Enable CP10 and CP11 coprocessors */ S32_SCB->CPACR |= (S32_SCB_CPACR_CP10_MASK | S32_SCB_CPACR_CP11_MASK);#ifdef ERRATA_E6940 /* Disable lazy context save of floating point state by clearing LSPEN bit * Workaround for errata e6940 */ S32_SCB->FPCCR &= ~(S32_SCB_FPCCR_LSPEN_MASK);#endif#endif /* ENABLE_FPU */
/**************************************************************************/ /* WDOG DISABLE*//**************************************************************************/
#if (DISABLE_WDOG) /* Write of the WDOG unlock key to CNT register, must be done in order to allow any modifications*/ WDOG->CNT = (uint32_t ) FEATURE_WDOG_UNLOCK_VALUE; /* The dummy read is used in order to make sure that the WDOG registers will be configured only * after the write of the unlock value was completed. */ (void)WDOG->CNT;
/* Initial write of WDOG configuration register: * enables support for 32-bit refresh/unlock command write words, * clock select from LPO, update enable, watchdog disabled */ WDOG->CS = (uint32_t ) ( (1UL << WDOG_CS_CMD32EN_SHIFT) | (FEATURE_WDOG_CLK_FROM_LPO << WDOG_CS_CLK_SHIFT) | (0U << WDOG_CS_EN_SHIFT) | (1U << WDOG_CS_UPDATE_SHIFT) );
/* Configure timeout */ WDOG->TOVAL = (uint32_t )0xFFFF;#endif /* (DISABLE_WDOG) */
/**************************************************************************/ /* Power mode protection *//**************************************************************************/#ifdef SYSTEM_SMC_PMPROT_VALUE /* Power mode protection initialization */ SMC->PMPROT = SYSTEM_SMC_PMPROT_VALUE;#endif}


4.6 RAM初始化

接下来,启动文件会调用定义在 SDK->platform->devices 目录下 startup.c 中的init_data_bss()函数完成应用工程运行所需的 RAM 初始化。

    /* Init .data and .bss sections */    ldr     r0,=init_data_bss    blx     r0

 

在 startup.c 中通过申明外部变量(extern)的方式,可以引用定义在工程链接文件中的__DATA_ROM、__DATA_RAM、__DATA_END、__CODE_RAM、__CODE_ROM、__CODE_END、__BSS_START__BSS_END 符号,获得工程链接结果中.data 段(有初始化值)、 .bss 段(未初始化和初始化值为 0)的全局变量以及重定向到 RAM 中运行的.code 段代码/函数在 Flash 和RAM 中的起始地址和长度(结束地址-开始地址)。 


然后再通过数据指针的方式实现全局变量初始化值和重映射代码从 Flash 到 RAM 中的拷贝以及.bss 段的清零:具体包括:

1)初始化.data

2)初始化.code

3)初始化.bss

4)将中断向量表从 Flash 拷贝到 RAM 中并

5)初始化 CPU 系统中断向量偏移地址,使其指向 RAM 中新的中断向量表(如果编译目标为 debug,编译结果存储在 Flash 中)。 


note 1:  .code段不是代码段,.code段属于m_data域(RAM)用来存放重映射到RAM中的代码。

note 2:  .text段才是代码段,.text段属于m_text域(ROM),存放的就是代码。

note 3:  为什么要将.data .bss 中断向量表拷贝到m_data域(RAM),因为.data中保存的是初始化过后的全局变量/静态局部变量.bss段中保存的是未初始化(初始化为0)的全局变量/静态局部变量,在系统运行的时候是需要改变的,而ROM是只读的,中断向量表同理。

note 4:  代码是不需要改变的,为什么也有部分的代码需要重映射到RAM中执行?-- 因为效率,因为相对于ROM来说,RAM的数据宽度较大,速度较快。

note 5: 怎么将代码重映射到RAM中?

通过上面的分析可知,在 S32K1xx 系列 MCU 的启动过程,会自动将定义在.code 段中的代码/函数从其 Flash 储存地址拷贝到 RAM 中的运行时地址。 


只有将用户代码分配到 Flash 中的编译目标,即使用 S32K1xx_xx_flash.ld 链接文件的编译目标才存在代码重映射。若是将应用工程编译结果代码分配到 RAM 的编译目标(使用 S32K1xx_xx_ram.ld 链接文件),其编译的函数/代码本身就是储存在 RAM 中的,所以无需重映射 。


将 想 要 重 映 射 的 代 码 / 函 数 通 过 __attribute__((section(".code_ram")))指定到.code_ram 段 由于在应用工程链接文件中已经将用户段.code_ram 放置在了.code 段中,所以,我们只需要在 C 代码中,将想要重映射的代码/函数通过__attribute__ ((section(".code_ram")))指定到.code_ram 段即可。比如下面就是将 main()函数指定到.code_ram 段的具体实现:int __attribute__ ((section(".code_ram"))) main(void) 


在 S32DS IDE 应用工程中,一个函数若没有特别指定,其将分配到.text 代码段。


需要注意是关键词-- __attribute__ ((section(".code_ram"))) 添加的位置,每个需要指定的函数都要添加这个关键词,因此,可以将其定义为一个宏比如 CODE_RAM 使用:#define CODE_RAM __attribute__ ((section(".code_ram")))然后,再将 CODE_RAM 放在定义的函数名前即可。

/*startup.c*/void init_data_bss(void){    uint32_t n;    /* Declare pointers for various data sections. These pointers     * are initialized using values pulled in from the linker file */    uint8_t * data_ram;    uint8_t * code_ram;    uint8_t * bss_start;    const uint8_t * data_rom, * data_rom_end;    const uint8_t * code_rom, * code_rom_end;    const uint8_t * bss_end;
/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; extern uint32_t __VECTOR_TABLE[]; extern uint32_t __VECTOR_RAM[];
/* Get section information from linker files */#if defined(__ICCARM__) /* Data */ data_ram = __section_begin(".data"); data_rom = __section_begin(".data_init"); data_rom_end = __section_end(".data_init");
/* CODE RAM */ #pragma section = "__CODE_ROM" #pragma section = "__CODE_RAM" code_ram = __section_begin("__CODE_RAM"); code_rom = __section_begin("__CODE_ROM"); code_rom_end = __section_end("__CODE_ROM");
/* BSS */ bss_start = __section_begin(".bss"); bss_end = __section_end(".bss");#else extern uint32_t __DATA_ROM[]; extern uint32_t __DATA_RAM[]; extern uint32_t __DATA_END[];
extern uint32_t __CODE_RAM[]; extern uint32_t __CODE_ROM[]; extern uint32_t __CODE_END[];
extern uint32_t __BSS_START[]; extern uint32_t __BSS_END[];
/* Data */ data_ram = (uint8_t *)__DATA_RAM; data_rom = (uint8_t *)__DATA_ROM; data_rom_end = (uint8_t *)__DATA_END; /* CODE RAM */ code_ram = (uint8_t *)__CODE_RAM; code_rom = (uint8_t *)__CODE_ROM; code_rom_end = (uint8_t *)__CODE_END; /* BSS */ bss_start = (uint8_t *)__BSS_START; bss_end = (uint8_t *)__BSS_END;#endif
/* Check if VECTOR_TABLE copy is needed */ if (__VECTOR_RAM != __VECTOR_TABLE) { /* Copy the vector table from ROM to RAM */ for (n = 0; n < (((uint32_t)__RAM_VECTOR_TABLE_SIZE)/sizeof(uint32_t)); n++) { __VECTOR_RAM[n] = __VECTOR_TABLE[n]; } /* Point the VTOR to the position of vector table */ S32_SCB->VTOR = (uint32_t)__VECTOR_RAM; } else { /* Point the VTOR to the position of vector table */ S32_SCB->VTOR = (uint32_t)__VECTOR_TABLE; }
/* Copy initialized data from ROM to RAM */ while (data_rom_end != data_rom) { *data_ram = *data_rom; data_ram++; data_rom++; }
/* Copy functions from ROM to RAM */ while (code_rom_end != code_rom) { *code_ram = *code_rom; code_ram++; code_rom++; }
/* Clear the zero-initialized data section */ while(bss_end != bss_start) { *bss_start = 0; bss_start++; }}

      

4.7 打开CPU全局中断

在完成 RAM 初始化和中断向量表初始化后,就可以打开 CPU 全局中断,响应外设中断了;打开 ARM Cortex M 系列 CPU 内核的全局中断通过汇编语句--“cpsie i”完成。

    cpsie   i               /* Unmask interrupts */

 

4.8 跳转到应用程序 main()函数在完成以上准备工作之后,启动过程的最后一步是跳转到应用程序 main()函数.

    bl      main

 

5. 相关应用

bootloader跳转到application的时候,要设置应用中R13寄存器中的堆栈地址,然后直接跳转到app中的Reset_Handler执行:bootup_application(0x5000, 0x5004)

同时需要修改app程序中链接器脚本中的连接地址

MEMORY{  /* Flash */  m_interrupts          (RX)  : ORIGIN = 0x00005000, LENGTH = 0x00000400  m_flash_config        (RX)  : ORIGIN = 0x00005400, LENGTH = 0x00000010  m_text                (RX)  : ORIGIN = 0x00005410, LENGTH = 0x0007FBF0
/* SRAM_L */ m_data (RW) : ORIGIN = 0x1FFF8000, LENGTH = 0x00008000
/* SRAM_U */ m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00007000}

 

void bootup_application(uint32_t appEntry, uint32_t appStack){    static void (*jump_to_application)(void);    static uint32_t stack_pointer;
//shutdown_drivers();
jump_to_application = (void (*)(void))appEntry; stack_pointer = appStack; S32_SCB->VTOR = APP_IMAGE_START; //__set_MSP(stack_pointer); __asm volatile ("MSR msp, %0\n" : : "r" (stack_pointer) : "sp"); //__set_PSP(stack_pointer); __asm volatile ("MSR psp, %0\n" : : "r" (stack_pointer) : "sp"); jump_to_application();}




参考文档:

    1.1 Cortex-M4 Devices Generic User Guide

    1.2 ARM Cortex-M4 Processor Technical reference manal

    1.3 ARMv7-M Architecture 

    1.4 S32K1xx Series Reference Manual 

    1.5 汽车电子expert成长之路公众号文章


推荐阅读

国内主机整车EEA架构汇总

谈谈整车控制器对油门信号处理的理解

浅谈电机控制器及其功能

谈谈电池管理系统的功能

谈谈整车控制器的功能

谈谈整车OTA系统的理解

五千字说清汽车基础软件及国产现状

带不带功能安全(IS26262)的区别,功能安全要做啥?

谈谈simulink自动代码生成

浅谈电机控制器及其功能

谈谈Bootloader自更新

电子电气架构设计需要考虑哪些方面?

汽车E/E架构的网络安全分析

深度解读汽车域控制器

自动驾驶域控制器信息梳理

深度分析整车控制域现状与发展

分享不易,恳请点个【👍】和【在看】

汽车ECU开发 专注于汽车电子ECU软件开发,技术分享。
评论
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-12 10:13 119浏览
  • 时源芯微——RE超标整机定位与解决详细流程一、 初步测量与问题确认使用专业的电磁辐射测量设备,对整机的辐射发射进行精确测量。确认是否存在RE超标问题,并记录超标频段和幅度。二、电缆检查与处理若存在信号电缆:步骤一:拔掉所有信号电缆,仅保留电源线,再次测量整机的辐射发射。若测量合格:判定问题出在信号电缆上,可能是电缆的共模电流导致。逐一连接信号电缆,每次连接后测量,定位具体哪根电缆或接口导致超标。对问题电缆进行处理,如加共模扼流圈、滤波器,或优化电缆布局和屏蔽。重新连接所有电缆,再次测量
    时源芯微 2024-12-11 17:11 179浏览
  • 天问Block和Mixly是两个不同的编程工具,分别在单片机开发和教育编程领域有各自的应用。以下是对它们的详细比较: 基本定义 天问Block:天问Block是一个基于区块链技术的数字身份验证和数据交换平台。它的目标是为用户提供一个安全、去中心化、可信任的数字身份验证和数据交换解决方案。 Mixly:Mixly是一款由北京师范大学教育学部创客教育实验室开发的图形化编程软件,旨在为初学者提供一个易于学习和使用的Arduino编程环境。 主要功能 天问Block:支持STC全系列8位单片机,32位
    丙丁先生 2024-12-11 13:15 96浏览
  • 铁氧体芯片是一种基于铁氧体磁性材料制成的芯片,在通信、传感器、储能等领域有着广泛的应用。铁氧体磁性材料能够通过外加磁场调控其导电性质和反射性质,因此在信号处理和传感器技术方面有着独特的优势。以下是对半导体划片机在铁氧体划切领域应用的详细阐述: 一、半导体划片机的工作原理与特点半导体划片机是一种使用刀片或通过激光等方式高精度切割被加工物的装置,是半导体后道封测中晶圆切割和WLP切割环节的关键设备。它结合了水气电、空气静压高速主轴、精密机械传动、传感器及自动化控制等先进技术,具有高精度、高
    博捷芯划片机 2024-12-12 09:16 314浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-11 17:58 146浏览
  • 首先在gitee上打个广告:ad5d2f3b647444a88b6f7f9555fd681f.mp4 · 丙丁先生/香河英茂工作室中国 - Gitee.com丙丁先生 (mr-bingding) - Gitee.com2024年对我来说是充满挑战和机遇的一年。在这一年里,我不仅进行了多个开发板的测评,还尝试了多种不同的项目和技术。今天,我想分享一下这一年的故事,希望能给大家带来一些启发和乐趣。 年初的时候,我开始对各种开发板进行测评。从STM32WBA55CG到瑞萨、平头哥和平海的开发板,我都
    丙丁先生 2024-12-11 20:14 144浏览
  • RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。RK3506核心板主要分为三个型号,各型号间的区别如下图:​图 1  RK3506核心板处理器型号场景1:显示HMIRK3506核心板显示接口支持RGB、MIPI、QSPI输出,且支持2D图形加速,轻松运行QT、LVGL等GUI,最快3S内开
    万象奥科 2024-12-11 15:42 144浏览
  • 一、SAE J1939协议概述SAE J1939协议是由美国汽车工程师协会(SAE,Society of Automotive Engineers)定义的一种用于重型车辆和工业设备中的通信协议,主要应用于车辆和设备之间的实时数据交换。J1939基于CAN(Controller Area Network)总线技术,使用29bit的扩展标识符和扩展数据帧,CAN通信速率为250Kbps,用于车载电子控制单元(ECU)之间的通信和控制。小北同学在之前也对J1939协议做过扫盲科普【科普系列】SAE J
    北汇信息 2024-12-11 15:45 165浏览
  • 在智能化技术快速发展当下,图像数据的采集与处理逐渐成为自动驾驶、工业等领域的一项关键技术。高质量的图像数据采集与算法集成测试都是确保系统性能和可靠性的关键。随着技术的不断进步,对于图像数据的采集、处理和分析的需求日益增长,这不仅要求我们拥有高性能的相机硬件,还要求我们能够高效地集成和测试各种算法。我们探索了一种多源相机数据采集与算法集成测试方案,能够满足不同应用场景下对图像采集和算法测试的多样化需求,确保数据的准确性和算法的有效性。一、相机组成相机一般由镜头(Lens),图像传感器(Image
    康谋 2024-12-12 09:45 165浏览
  • 全球智能电视时代来临这年头若是消费者想随意地从各个通路中选购电视时,不难发现目前市场上的产品都已是具有智能联网功能的智能电视了,可以宣告智能电视的普及时代已到临!Google从2021年开始大力推广Google TV(即原Android TV的升级版),其他各大品牌商也都跟进推出搭载Google TV操作系统的机种,除了Google TV外,LG、Samsung、Panasonic等大厂牌也开发出自家的智能电视平台,可以看出各家业者都一致地看好这块大饼。智能电视的Wi-Fi连线怎么消失了?智能电
    百佳泰测试实验室 2024-12-12 17:33 271浏览
  • 应用环境与极具挑战性的测试需求在服务器制造领域里,系统整合测试(System Integration Test;SIT)是确保产品质量和性能的关键步骤。随着服务器系统的复杂性不断提升,包括:多种硬件组件、操作系统、虚拟化平台以及各种应用程序和服务的整合,服务器制造商面临着更有挑战性的测试需求。这些挑战主要体现在以下五个方面:1. 硬件和软件的高度整合:现代服务器通常包括多个处理器、内存模块、储存设备和网络接口。这些硬件组件必须与操作系统及应用软件无缝整合。SIT测试可以帮助制造商确保这些不同组件
    百佳泰测试实验室 2024-12-12 17:45 268浏览
  • 本文介绍瑞芯微RK3588主板/开发板Android12系统下,APK签名文件生成方法。触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,该开发板是核心板加底板设计,音视频接口、通信接口等各类接口一应俱全,可帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。工具准备下载Keytool-ImportKeyPair工具在源码:build/target/product/security/系统初始签名文件目录中,将以下三个文件拷贝出来:platform.pem;platform.
    Industio_触觉智能 2024-12-12 10:27 192浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦