From af011d30260c477a72efcf9a5e3ed219c16db6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=94=AF=E6=95=99=E6=8E=88?= <2530308275@qq.com> Date: Tue, 20 Aug 2024 09:54:35 +0800 Subject: [PATCH] test --- "src/README - \345\211\257\346\234\254.md" | 811 +++++++++++++++++++++ vendor/build_sample.py | 473 ++++++++++++ 2 files changed, 1284 insertions(+) create mode 100644 "src/README - \345\211\257\346\234\254.md" create mode 100644 vendor/build_sample.py diff --git "a/src/README - \345\211\257\346\234\254.md" "b/src/README - \345\211\257\346\234\254.md" new file mode 100644 index 000000000..e827e701e --- /dev/null +++ "b/src/README - \345\211\257\346\234\254.md" @@ -0,0 +1,811 @@ +SolarA2 1.0.1.2 +# 目录整体结构 + +**表 1** 目录整体结构说明 + +|文件夹名|描述| +|--|--| +|application|应用sample目录,存放各级sample和客户主程序入口。| +|board|板级特性目录,存放板级的软件特性。| +|build|编译构建目录,存放编译相关的脚本和配置信息。| +|chip|支持芯片目录,存放当前SDK支持的芯片系列的代码。| +|drivers|驱动目录,存放当前SDK支持的IP驱动。| +|tools|工具链目录,存放当前SDK依赖的工具链。| +|generatecode|IDE自动生成代码相关目录。| +|middleware|中间件目录,存放当前SDK版本支持的中间件。| +|document|文档目录,存放用户使用指导手册。| + + +# application + +**表 2** application目录结构说明 + +|文件夹名|描述| +|--|--| +|board_sample|存放板级抽象sample代码。| +|drivers_sample|存放驱动sample代码。| +|middleware_sample|存放中间件sample代码。| +|user|main.c 存放路径。| + + + + + + + +## board\_sample + +**表 3** board\_sample目录结构说明 + +|文件夹名|描述| +|--|--| +|dimming|呼吸灯功能示例。| +|key|按键检查功能示例。| +|led|数码管功能示例。| +|pulses|gpio发送pwm波功能示例。| +|softserial|gpio实现串口通信功能示例。| + + +## drivers\_sample + + + + + + + + + + + + + + + + + + + + + + + + + +### acmp + +**表 4** acmp目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_acmp|比较器使用示例。| + + +### adc + +**表 5** adc目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_adc_associative_trigger_of_apt|APT触发ADC。| +|sample_adc_continue_trigger|ADC连续采样。| +|sample_adc_over_sample|ADC过采样。| +|sample_adc_single_trigger|ADC单次采样。| +|sample_adc_single_trigger_dma|ADC单次采样带DMA。| +|sample_adc_single_trigger_it|ADC单次采样带中断。| +|sample_adc_sync_sample|ADC同步采样。| +|sample_adc_sync_sample_dma|ADC同步采样带DMA。| +|sample_adc_sync_sample_it|ADC同步采样带中断。| + + +### apt + +**表 6** apt目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_apt_single_resistor|APT单电阻采样示例,仅在U相触发ADC采样信号。| +|sample_apt_three_resistor|APT三电阻采样示例,在U、V和W相都触发ADC采样信号。| + + +### can + +**表 7** can目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_can_send_receive|CAN发送和接收数据示例。| + + +### capm + +**表 8** capm目录结构说明 + +|文件夹名|描述| +|--|--| +|capm_hall_sample|CAPM读取霍尔传感器值示例。| + + +### cfd + +**表 9** cfd目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_cfd_check_error|cfd注入错误前后监测目标时钟异常功能。| + + +### cmm + +**表 10** cmm目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_cmm_check_error|cmm注入错误前后监测目标时钟异常功能。| + + +### crc + +**表 11** crc目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_crc_check|测试CRC不同算法和输入有效位宽,生成并校验crc值。| +|sample_crc_gen|计算并生成CRC数值。| +|sample_crc_load|通过load初始值将xmodem算法改为ccit-false算法并校验结果。| + + +### dac + +**表 12** dac目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_dac|DAC电压输出到管脚示例。| + + +### dma + +**表 13** dma目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_dma_list_transfer|DMA链式传输。| +|sample_dma_list_transfer_continue|DMA链式传输实现连续功能。| +|sample_dma_mem_to_mem|DMA内存到内存传输。| +|sample_dma_mem_to_per|DMA内存到外设传输。| +|sample_dma_per_to_mem|DMA外设到内存传输。| +|sample_dma_per_to_per|DMA外设到外设传输。| + + +### flash + +**表 14** flash目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_flash_blocking|阻塞模式操作flash。| +|sample_flash_interrupt|中断方式操作flash。| + + +### gpio + +**表 15** gpio目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_gpio_circle|GPIO环回测试电平和方向属性。| +|sample_gpio_interrupt|测试GPIO不同中断类型。| +|sample_gpio_key|GPIO用作按键功能。| +|sample_gpio_led|GPIO周期控制led亮灭功能。| + + +### gpt + +**表 16** gpt目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_gpt_simplerun|gpt产生PWM波形。| + + +### i2c + +**表 17** i2c目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_i2c_blocking_stlm75|使用阻塞的方式读写温度传感器。| +|sample_i2c_interrupt_stlm75|使用中断的方式读写温度传感器。| +|sample_i2c_dma_stlm75|使用dma方式读写温度传感器。| + + +### iocmg + +**表 18** iocmg目录结构说明 + +|文件夹名|描述| +|--|--| +|iolist_sample|iocmg初始化管脚列表的属性配置功能。| + + +### pga + +**表 19** pga目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_pga|PGA内部电阻放大示例。| +|sample_pga_extra_resistor|PGA外部电阻放大示例。| + + +### pmc + +**表 20** pmc目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_pmc_pvd|PMC掉电检测示例。| +|sample_pmc_wakeup|PMC定时器唤醒示例。| + + +### qdm + +**表 21** qdm目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_qdm_m|QDM使用M法读取电机转速的示例。| +|sample_qdm_mt|QDM使用MT法读取电机转速的示例。| + + +### spi + +**表 22** spi目录机构说明 + +|文件夹名|描述| +|--|--| +|sample_spi_blocking_kta7953|使用阻塞方式读写ADC。| +|sample_spi_dma_kta7953|使用dma方式读写ADC。| +|sample_spi_interrupt_kta7953|使用中断方式读写ADC。| +|sample_spi_microwire_master|演示如何使用microwire master。| +|sample_spi_microwire_slave|演示如何使用microwire slave。| +|sample_spi_slave|演示如何使用motorola spi slaver。| + + +### timer + +**表 23** timer目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_timer_interrupt|timer定时触发中断,执行用户串口打印。| + + +### tsensor + +**表 24** tsensor目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_tsensor|tsensor对器件结温采样。| + + +### uart + +**表 25** uart目录结构说明 + +|文件夹名|描述| +|--|--| +|sample_uart_blocking_rx|UART阻塞接收。| +|sample_uart_blocking_tx|UART阻塞发送。| +|sample_uart_dma_rx|UART带DMA接收。| +|sample_uart_dma_tx|UART带DMA发送。| +|sample_uart_interrupt_tx_after_rx|UART中断接收数据之后,再中断发送此数据。| +|sample_uart_interrupt_rx|UART中断接收。| +|sample_uart_interrupt_tx|UART中断发送。| +|sample_uart_dma_tx_dma_rx_simultaneously|UART全双工模式,DMA同时发送和接收。| +|sample_uart_dma_tx_int_rx_simultaneously|UART全双工模式,DMA发送的同时,中断接收。| +|sample_uart_int_tx_dma_rx_simultaneously|UART全双工模式,中断发送的同时,DMA接收。| +|sample_uart_int_tx_int_rx_simultaneously|UART全双工模式,中断发送的同时,中断接收。| +|sample_uart_dma_rx_cyclically_stored|UART使用DMA循环搬运数据到指定内存。| +|sample_uart_single_wire_communication|UART单线通信示例。| + + +### wdg + +**表 26** wdg目录机构说明 + +|文件夹名|描述| +|--|--| +|sample_wdg_reset|测试wdg不喂狗复位功能。| +|sample_iwdg_reset|测试iwdg不喂狗复位功能。| + + +## middleware\_sample + +**表 27** middleware\_sample目录机构说明 + +|文件夹名|描述| +|--|--| +|mcs_65ldemo|电机控制算法在AD101HDMA_VER.B板的示例。| +|mcs_65demo|电机控制算法在AD105HDMA_VER.B板的示例。| +|pmsm_sensorless_1shunt_foc|永磁同步电机单电阻采样无感FOC应用。| +|pmsm_sensorless_2shunt_foc|永磁同步电机双电阻采样无感FOC应用。| + + +## user + +客户主程序的入口文件存放在此目录下。 + +# board + +**表 28** board目录结构说明 + +|文件夹名|描述| +|--|--| +|dimming|使用GPT和TIMER实现呼吸灯功能。| +|key|按键检查功能。| +|led|数码管功能。| +|pulses|使用gpio发送pwm波功能。| +|softserial|使用gpio实现串口通信功能。| + + +# build + +**表 29** build目录 + +|文件夹名|文件名|描述| +|--|--|--| +|__pycache__|-|执行python脚本产生的缓存文件。| +|config|-|指定编译工具链和工具链对应的默认编译参数。| +|toolchain|-|编译工具链配置模板。| +|-|.gn|内容为指定BUILDCONFIG.gn路径,以及指定根构建目标BUILD.gn的路径。| +|-|BUILD.gn|由build_gn.py脚本自动生成,此文件为根构建目标文件。| +|-|build.py|完成编译命令解析、编译环境检测、执行编译等工作。| +|-|build_check.py|编译前合法性检查脚本。| +|-|build_gn.py|解析userconfig.json的编译内容,完成自动构建编译脚本的工作。| +|-|config.ini|保存编译工具链路径和gn、ninja编译命令的调用。| +|-|ide_entry.py|从SDK分离生成工程的脚本。| +|-|packet_create.py|打包生成all-in-one(loader.bin + target.bin)文件的脚本。| + + +**表 30** config目录 + +|文件夹名|文件名|描述| +|--|--|--| +|hcc|-|存放hcc编译器默认编译选项和最终编译选项。| +|hcc_fpu|-|存放hcc浮点编译器默认编译选项和最终编译选项。| +|-|BUILDCONFIG.gn|内容为指定需要使用的编译工具链。| + + +**表 31** toolchain目录 + +|文件夹名|文件名|描述| +|--|--|--| +|-|BUILD.gn|使用config.gni中的工具链配置模板配置编译工具链命令。| +|-|config.gni|内容为工具链的编译命令模板。| + + +# chip + +**表 32** chip目录结构说明 + +|文件夹名|文件夹名/文件名|描述| +|--|--|--| +|3065h/3061h|-|存放与芯片配置相关的代码文件,比如IP版本、特性宏、中断和时钟等。| +|chipinit/|存放芯片早期初始化代码,在客户程序运行前执行。| +|fotp/|存放fotp区域的读接口。| +|ip_crg/|与芯片耦合的IP时钟配置。| +|iomap/|与芯片相关的IO管脚复选功能定义。| +|baseaddr.h|芯片的寄存器地址信息。| +|chipinc.h|芯片头文集合,客户包含此头文件即可使用全部芯片信息。| +|codecopy.json|非IDE环境下分离工程信息。| +|flash.lds|芯片分区信息。| +|info.h|芯片cycle信息。| +|interrupt_ip.h|芯片中断号分配信息。| +|ioconfig.h|芯片管脚复用寄存器信息。| +|locktype.h|芯片预定义的锁信息,暂无使用。| +|startup.S|程序初始化代码。| +|sysctrl.h|系统控制寄存器信息。| +|systick.h|系统systick信息。| +|target|userconfig.json|存放默认的编译参数。| + + +# document + +**表 33** documet目录结构说明 + +|文件夹名|描述| +|--|--| +|hardware|存放硬件生态板的用户手册。| +|software|存放Solrec软件用户手册。| +|tools|存放IDE、调试器等工具用户手册。| + + +# drivers + +**表 34** drivers目录结构说明 + +|文件夹名|描述| +|--|--| +|acmp|存放比较器驱动代码。| +|adc|存放adc驱动代码。| +|apt|存放apt驱动代码。| +|base|存放基础枚举定义和通用函数接口。| +|can|存放can驱动代码。| +|capm|存放capm驱动代码。| +|cfd|存放cfd驱动代码。| +|cmm|存放cmm驱动代码。| +|crc|存放crc驱动代码。| +|crg|存放crg驱动代码。| +|dac|存放dac驱动代码。| +|debug|存放调试相关代码。| +|dma|存放dma驱动代码。| +|flash|存放flash驱动代码。| +|gpio|存放gpio驱动代码。| +|gpt|存放gpt驱动代码。| +|i2c|存放i2c驱动代码。| +|pga|存放pga驱动代码。| +|pmc|存放pmc驱动代码。| +|qdm|存放qdm驱动代码。| +|spi|存放spi驱动代码。| +|timer|存放定时器驱动代码。| +|tsensor|存放tsensor驱动代码。| +|uart|存放串口驱动代码。| +|wdg|存放看门狗驱动代码。| + + +>**说明:** +>模块目录下的v0/v1/...后缀目录代表不同的模块IP,各IP不具有升级关系。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## acmp + +**表 35** acmp目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的acmp模块头文件。| +|acmp_v0|存放与IP相关的acmp模块头文件和源码文件。| + + +## adc + +**表 36** adc目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的adc模块头文件。| +|adc_v0|存放与IP相关的adc模块头文件和源码文件。| + + +## apt + +**表 37** apt目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,apt模块头文件。| +|apt_v0|存放与IP相关的,apt模块头文件和源码文件。| + + +## base + +**表 38** base目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放base模块的头文件信息。| +|base_v0|存放base基础定义和通用功能函数以及中断接口。| + + +## can + +**表 39** can目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,can模块头文件。| +|can_v0|存放与IP相关的,can模块头文件和源码文件。| + + +## capm + +**表 40** capm目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,capm模块头文件。| +|capm_v0|存放与IP相关的,capm模块头文件和源码文件。| + + +## cfd + +**表 41** cfd目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,cfd模块头文件。| +|cfd_v0|存放与IP相关的,cfd模块头文件和源码文件。| + + +## cmm + +**表 42** cmm目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,cmm模块头文件。| +|cmm_v0|存放与IP相关的,cmm模块头文件和源码文件。| + + +## crc + +**表 43** crc目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,crc模块头文件。| +|crc_v0|存放与IP相关的,crc模块头文件和源码文件。| + + +## crg + +**表 44** crg目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的crg模块头文件。| +|crg_v0|存放与IP相关的crg模块头文件和源码文件。| + + +## dac + +**表 45** dac目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,dac模块头文件。| +|dac_v0|存放与IP相关的,dac模块头文件和源码文件。| + + +## debug + +**表 46** debug目录结构说明 + +|文件夹名|描述| +|--|--| +|inc|调试模块头文件。| +|src|调试模块源代码。| + + +## dma + +**表 47** dma目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的dma模块头文件。| +|dma_v0|存放与IP相关的串口模块头文件和源码文件。| + + +## flash + +**表 48** flash目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,flash模块头文件。| +|flash_v0|存放与IP相关的,flash模块头文件和源码文件。| + + +## gpio + +**表 49** gpio目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,gpio模块头文件。| +|gpio_v0|存放与IP相关的,gpio模块头文件和源码文件。| + + +## gpt + +**表 50** gpt目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的gpt模块头文件。| +|gpt_v0|存放与IP相关的gpt模块头文件和源码文件。| + + +## i2c + +**表 51** i2c目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的i2c模块头文件。| +|i2c_v0|存放与IP相关的i2c模块头文件和源码文件。| + + +## iocmg + +**表 52** iocmg目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,iocmg模块头文件。| +|iocmg_v0|存放与IP相关的,iocmg模块头文件和源码文件。| + + +## pga + +**表 53** pga目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,pga模块头文件。| +|pga_v0|存放与IP相关的,pga模块头文件和源码文件。| + + +## pmc + +**表 54** pmc目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,pmc模块头文件。| +|pmc_v0|存放与IP相关的,pmc模块头文件和源码文件。| + + +## qdm + +**表 55** qdm目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,qdm模块头文件。| +|qdm_v0|存放与IP相关的,qdm模块头文件和源码文件。| + + +## spi + +**表 56** spi目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的spi模块头文件。| +|spi_v0|存放与IP相关的spi模块头文件和源码文件。| + + +## timer + +**表 57** timer目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的timer模块头文件。| +|timer_v0|存放与IP相关的timer模块头文件和源码文件。| + + +## tsensor + +**表 58** tsensor目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的tsensor模块头文件。| +|tsensor_v0|存放与IP相关的tsensor模块头文件和源码文件。| + + +## uart + +**表 59** uart目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的uart模块头文件。| +|uart_v0|存放与IP相关的uart模块头文件和源码文件。| + + +## wdg + +**表 60** wdg目录结构说明 + +|文件夹名|描述| +|--|--| +|common|存放与IP无关的,看门狗模块头文件。| +|wdg_v0|存放与IP相关的,看门狗模块头文件和源码文件。| + + +# generatecode + +存放IDE根据图形化配置界面自动生成系统初始化代码的初始文件。 + +**表 61** generatecode目录结构说明 + +|文件名|描述文件| +|--|--| +|feature.h|宏定义文件,定义了参数检查、打印开关等宏。| +|main.h|main.c的头文件。| +|system_init.c|驱动初始化代码。| + + +# middleware + +**表 62** middleware目录结构说明 + +|文件夹名|描述文件| +|--|--| +|thirdparty|第三方中间件。| +|control_library|电机控制FOC算法,此算法做为电机功能验证使用,不做商用质量保证。如需商用请充分验证。| + + +# bundle.json + +**表 63** bundle.json的文件说明 + +|文件名|描述文件| +|--|--| +|bundle.json|IDE编译组件的编译命令配置文件。| + + +# 缩略语 + +|缩略语|英文|中文| +|--|--|--| +|ADC|Analog-to-digital converter|模拟数字转换器| +|APT|Advance Pluse timer|高级脉冲定时器| +|ACMP|Analog Comparator|模拟比较器| +|BGA|Ball Grid Array|球栅阵列| +|BASE|Base|基础定义| +|CRG|Clock Reset and Generator|时钟复位生成器| +|CAN|Controller Area Network|控制器局域网| +|CRC|Cyclic Redundancy Check|循环冗余校验| +|CAPM|Capture Module|捕捉器| +|CFD|Clock Failure Detector|时钟失效检测| +|CMM|Clock Monitor Module|时钟频率监测| +|CVE|Common Vulnerabilities and Exposures system|常见漏洞和暴露系统| +|DAC|Digital-to-analog converter|数字模拟转换器| +|DMA|Direct Memory Access|内存直接访问| +|GPIO|General Purpose Input/Output|通用目的输入输出接口| +|GPT|General Pluse timer|通用脉冲定时器| +|I2C master|Inter Integrated-Circuit Master|I2C主机| +|I2C Slave|Inter Integrated-Circuit Slave|I2C从机| +|PMU|Power Manager Unit|电源管理单元| +|PWM|Pulse Width Modulation|脉冲宽度调制| +|PGA|Programmable Gain Amplifier|可编程增益放大器| +|PMP|Physical Memory Protection|物理内存保护| +|QDM|Quadrature Decoder Module|正交解码器| +|ROM|Read-Only Memory|只读存储器| +|SPI|Serial Peripheral Interface|串行外设接口| +|UART|Universal Asynchronous Receiver/Transmitter|通用异步接收发送设备| +|WDG|Watch Dog timer|看门狗| \ No newline at end of file diff --git a/vendor/build_sample.py b/vendor/build_sample.py new file mode 100644 index 000000000..26f17aa6d --- /dev/null +++ b/vendor/build_sample.py @@ -0,0 +1,473 @@ +import os +import sys +import pathlib +from configparser import ConfigParser +import stat +import time +import shutil +import shlex +import subprocess +import platform +import hashlib +import json + +script_a_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../src/build')) +sys.path.append(script_a_path) + +from build_gn import read_json_file +from ide_entry import un_alltools +from build import remove_readonly + +#ws63编译配置 +BUILD_INFO_FILENAME = 'build_config.json' +# 定义要执行的脚本文件和目录 +build_directory_path = 'src' +ws63_log_image_target_directory = 'archives' +global_combined = '' + +# 获取本次git提交目录名称 +def get_changed_folders_in_vendor(): + folder_name= '' + src_folder_name= '' + print(f"start get_changed_folders_in_directory") + try: + # 执行git命令获取本次提交的变更文件列表,除去根目录src目录,其他目录提交都显示 + git_command = "git diff --name-only origin/HEAD..HEAD" + output = subprocess.check_output(git_command, shell=True, text=True) + # 将输出按行分割成文件路径列表 + changed_files = output.strip().split("\n") + # 初始化变量,用于记录是否有改变的文件类型 + has_c_or_h_files = False + # 遍历每个文件路径 + for file_path in changed_files: + if file_path.endswith(".c") or file_path.endswith(".h"): + has_c_or_h_files = True + break + changed_folders = set() + for file_path in changed_files: + # 提取文件夹名称 + if '/' in file_path: + src_folder_name = file_path.split('/')[0] + if '"src' in src_folder_name or 'src' in src_folder_name: + print(f"invalid modify, not allow modify src dir and build script") + sys.exit(0) + if has_c_or_h_files: + for file_path in changed_files: + if file_path.endswith(".c") or file_path.endswith(".h"): + folder_name = file_path.split('/')[1] + '+' + file_path.split('/')[2] + '+' + file_path.split('/')[3] + else: + '' + if folder_name: + changed_folders.add(folder_name) + print(f"[get_changed_folders_in_vendor] changed_folders: {changed_folders}") + return changed_folders + else: + print(f"not need build, only doc or readme been modified") + sys.exit(0) + except subprocess.CalledProcessError as e: + print(f"Error executing Git command: {e}") + return None + + +# 获取代码仓所有build_info.json文件内容,并拼接在一起 +def process_build_info_files(): + print(f"start process_build_info_files") + result_list = [] + # 遍历指定目录及其子目录下的所有文件和文件夹 + for root, dirs, files in os.walk("./"): + for file in files: + if file == BUILD_INFO_FILENAME: + file_path = os.path.join(root, file) + print(file_path) + # 读取JSON文件内容 + with open(file_path, 'r') as f: + try: + data = json.load(f) + for item in data: + # 提取需要的字段值 + build_target = item.get('buildTarget', '') + relative_path = item.get('relativePath', '').replace('/','-') + chip_name = item.get('chip', '') + # 组合成一个字符串并添加到结果列表 + if item.get('buildDef', ''): + build_def = item.get('buildDef', '') + combined_value = f"{file_path}+{build_target}+{relative_path}+{chip_name}+{build_def}" + else: + combined_value = f"{file_path}+{build_target}+{relative_path}+{chip_name}" + result_list.append(combined_value) + except json.JSONDecodeError: + print(f"Error decoding JSON in file: {file_path}") + sys.exit(-1) + return result_list + +# 对比git和json内容,一致则代表提交,不一样代表之前提交 +def extract_exact_match(input_list, match_list): + print(f"start extract_exact_match") + print(f"[extract_exact_match] input_list: {input_list}") + print(f"[extract_exact_match] match_list: {match_list}") + exact_matches = [] + try: + for string in input_list: + # 使用 split 方法获取第二个 + 和第三个 + 之间的内容 + parts = string.split('+') + if len(parts) >= 4: + sample_company_name = parts[0].split('/')[2] + sample_name_field = parts[2].replace('-','+') + combined_string = sample_company_name + "+" + sample_name_field + if combined_string in match_list: + exact_matches.append(string) + print(f"[extract_exact_match] exact_matches: {exact_matches}") + if not exact_matches: + print(f"build-config has not been synchronously updated") + exit(0) # 退出并返回非零状 + else: + print("exact_matche 列表不为空") + return exact_matches + except TypeError as e: + print(f"Error: {e}") + # 在捕获到异常后,可以选择退出程序 + exit(0) # 退出并返回非零状 + +# 如果代码编译cmakelist文件中通过宏控制编译哪些文件,则需要用宏重新组合编译配置信息 +def sample_meunconfig_modify(input_list): + print(f"start sample_meunconfig_modify{input_list}") + # 初始化结果列表 + result_list = [] + combined_string = "" + for string in input_list: + parts = string.split('+') + sample_file_path = parts[0] + build_target = parts[1] + sample_name = parts[2] + platform = parts[3] + if len(parts) == 5: + def_name = parts[4] + # 根据逗号分割字符串 + def_parts = def_name.split(',') + # 遍历分割后的每一个部分,添加到结果列表中,宏的个数,决定编译的次数 + if len(def_parts) == 1 and def_parts[0] == def_name: + result_list.append(sample_file_path+"+"+build_target+"+"+sample_name+"+"+platform+"+"+def_name) + else: + for idx, part in enumerate(def_parts): + if idx == 0: + combined_string = part + else: + combined_string += "+" + part # 在每个部分之前添加加号 + result_list.append(sample_file_path+"+"+build_target+"+"+sample_name+"+"+platform+"+"+combined_string) + # 如果没有逗号,则整个字符串保存到结果列表 + elif len(parts) == 4: + result_list.append(sample_file_path+"+"+build_target+"+"+sample_name+"+"+platform) + return result_list + + +def dest_path_cpoy(copy_path, dirprocesspath, dirpath, filenames): + dest_path = pathlib.Path(copy_path).joinpath(dirprocesspath) + if not dest_path.exists(): + os.makedirs(dest_path) + for file in filenames: + if 'entry.py' in file or 'trustlist.json' in file: + continue + source_file = pathlib.Path(dirpath).joinpath(file) + shutil.copy(source_file, dest_path) + +def filter_copy_adpater(copy_path, dirpath, filenames): + ''' + Function description: project creat. + ''' + ipbefore_list = [] + ipafter_list = [] + cur_sys = platform.system() + if cur_sys == 'Windows': + ipbefore_list = dirpath.split('\\') + elif cur_sys == 'Linux': + ipbefore_list = dirpath.split('/') + ipafter_list = [] + p_vindex = 0 + p_cindex = -1 + for v_index, ipdir in enumerate(ipbefore_list): + if ipdir.startswith('v') and '.' in ipdir: + continue + # Filtering files + if '_v' in ipdir: + p_vindex = v_index + if 'common_v' in ipdir: + p_cindex = v_index + ipafter_list.append(ipdir) + if ipafter_list[p_vindex - 1] + '_v' in ipafter_list[p_vindex]: + ipafter_list.pop(p_vindex) + if p_cindex >= 0: + ipafter_list[p_cindex] = 'common' + p_cindex = -1 + dirprocesspath = '/'.join(ipafter_list) + dest_path_cpoy(copy_path, dirprocesspath, dirpath, filenames) + +def traversal_path(copy_path, module_path, version): + ''' + Function description:creat and copy work + ''' + for (dirpath, _, filenames) in os.walk(module_path): + filter_copy_adpater(copy_path, dirpath, filenames) + +def copy_drive_modules(copy_abspath, product, ip_name, copyjson_content): + ''' + function description: copying drive modules + ''' + source_path = os.path.join('drivers', ip_name) + for ip_content in copyjson_content[ip_name]: + source_path = os.path.join(source_path, ip_content) + if pathlib.Path(source_path).is_dir(): + traversal_path(copy_abspath, source_path, product) + elif pathlib.Path(source_path).is_file(): + parent_path = pathlib.Path(source_path).parent_path + copy_parent_path = pathlib.Path(copy_abspath).joinpath(parent_path) + if not copy_parent_path.exists(): + os.makedirs(copy_parent_path) + shutil.copy(source_path, copy_parent_path) + source_path = '' + source_path = os.path.join('drivers', ip_name) + +def copy_code(product, copy_path): + ''' + Funcuntion + ''' + if not isinstance(copy_path, str): + raise TypeError("copy_path in para type error {}".format(type(copy_path))) + if not isinstance(product, str): + raise TypeError("product in para type error {}".format(type(product))) + # copy file path + if pathlib.Path(copy_path).exists(): + shutil.rmtree(os.path.realpath(copy_path), onerror=remove_readonly) + copy_abspath = pathlib.Path(copy_path).resolve() + copyjson_path = pathlib.Path.cwd().joinpath('chip', "{}".format(product), 'codecopy.json') + print(f"[sample_build_prepare] source_directory: {copyjson_path}") + copyjson_content = read_json_file(copyjson_path) + #Add the basic modules + for module_path in copyjson_content['modules']: + if pathlib.Path(module_path).is_dir(): + traversal_path(copy_abspath, module_path, product) + elif pathlib.Path(module_path).is_file(): + #File copy processing basic module + parent_path = pathlib.Path(module_path).parent + copy_parent_path = pathlib.Path(copy_abspath).joinpath(parent_path) + if not copy_parent_path.exists(): + os.makedirs(copy_parent_path) + shutil.copy(module_path, copy_parent_path) + if str(parent_path) == 'chip\\target' or str(parent_path) == 'chip/target': + userconfig_json_name = module_path.split('/')[-1] + os.rename(pathlib.Path(copy_parent_path).joinpath(userconfig_json_name)),pathlib.Path(copy_parent_path).joinpath('userconfig.json') + #Copying drive modules + for ip_name in copyjson_content['ip_drive_file']: + copy_drive_modules(copy_abspath, product, ip_name, copyjson_content) + +def differ_file_copy(copy_chip, copy_path, tools_path): + ''' + Function description: Projection generation for different chip + ''' + un_alltools(tools_path) + # Detach the chip package + copy_code(copy_chip, copy_path) + os.chdir(pathlib.Path(copy_path).resolve()) + target_pathconfigsource = pathlib.Path().cwd().joinpath('chip', copy_chip, 'target') + target_pathconfigdest = pathlib.Path().cwd().joinpath('chip', 'target') + # Target file replace + if pathlib.Path(target_pathconfigsource).exists(): + shutil.rmtree(target_pathconfigdest) + shutil.copytree(target_pathconfigsource, target_pathconfigdest) + # write the path of the full package tool to the config.ini file. + config_path = pathlib.Path().cwd().joinpath('build', 'config.ini') + config = ConfigParser() + config.read(config_path) + config.set('gn_args', 'tools_path', tools_path) + flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC + modes = stat.S_IWUSR | stat.S_IRUSR + flagsone = os.O_RDWR | os.O_CREAT + # File socket of the config.ini file. + with os.fdopen(os.open(config_path, flags, modes), 'w+') as configini: + config.write(configini) + # Executing Build and Compile Commands + cmd = shlex.split('python build/build.py build') + proc = subprocess.Popen(cmd) + proc.wait() + ret_code = proc.returncode + if ret_code != 0: + raise Exception("CI {} failed, return code is {}".format(cmd, ret_code)) + + +def move_file(source_file, new_filename): + print(f"start move_file") + target_file = os.path.join(f'../../archives', new_filename) + os.chmod(source_file, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) + try: + # 移动并重命名文件 + shutil.move(source_file, target_file) + os.chmod(target_file, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH) + print(f"文件 {source_file} 移动并重命名为 {target_file} 成功。") + except FileNotFoundError: + print(f"找不到文件 {source_file}") + except PermissionError: + print(f"权限错误,无法移动文件。") + except Exception as e: + print(f"发生错误:{str(e)}") + +def delete_file(directory, filename): + # 拼接文件路径 + file_path = os.path.join(directory, filename) + + # 检查文件是否存在 + if os.path.isfile(file_path): + try: + # 删除文件 + os.remove(file_path) + print(f"文件 {filename} 已被成功删除。") + except Exception as e: + print(f"删除文件时出错: {e}") + else: + print(f"文件 {filename} 不存在于目录 {directory} 中。") + +def remove_lines(file_path, start_line, end_line): + try: + with open(file_path, 'r') as file: + lines = file.readlines() + + # 删除指定范围的行 + if start_line > 0 and end_line <= len(lines): + del lines[start_line-1:end_line] + else: + print("行号超出范围") + return + + with open(file_path, 'w') as file: + file.writelines(lines) + + print(f"已删除文件 {file_path} 中第 {start_line} 行到第 {end_line} 行的内容。") + except Exception as e: + print(f"处理文件时出错: {e}") + +def has_main_h(directory, file): + for root, dirs, files in os.walk(directory): + if file in files: + return True + return False + +def differ_file_copy(copy_chip, copy_path, tools_path, source_directory): + ''' + Function description: Projection generation for different chip + ''' + un_alltools(tools_path) + # Detach the chip package + + copy_code(copy_chip, copy_path) + os.chdir(pathlib.Path(copy_path).resolve()) + target_pathconfigsource = pathlib.Path().cwd().joinpath('chip', copy_chip, 'target') + target_pathconfigdest = pathlib.Path().cwd().joinpath('chip', 'target') + # Target file replace + if pathlib.Path(target_pathconfigsource).exists(): + shutil.rmtree(target_pathconfigdest) + shutil.copytree(target_pathconfigsource, target_pathconfigdest) + # write the path of the full package tool to the config.ini file. + config_path = pathlib.Path().cwd().joinpath('build', 'config.ini') + config = ConfigParser() + config.read(config_path) + config.set('gn_args', 'tools_path', tools_path) + flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC + modes = stat.S_IWUSR | stat.S_IRUSR + flagsone = os.O_RDWR | os.O_CREAT + # File socket of the config.ini file. + with os.fdopen(os.open(config_path, flags, modes), 'w+') as configini: + config.write(configini) + # Executing Build and Compile Commands + + print(f"start compile_sdk_and_save_log") + current_dir = os.getcwd() + print(f"Current working directory: {current_dir}") + delete_file("middleware/thirdparty/sysroot/lib", 'libnostask.a') + if copy_chip == '3061m' or copy_chip == '3065h': + remove_lines("middleware/hisilicon/nostask/kernel/nos_amp_task.c", 48, 63) + if has_main_h(source_directory, "main.h"): + delete_file("generatecode", "main.h") + if has_main_h(source_directory, "system_init.c"): + delete_file("generatecode", "system_init.c") + if has_main_h(source_directory, "feature.h"): + delete_file("generatecode", "feature.h") + if has_main_h(source_directory, "main.c"): + delete_file("application/user", "main.c") + shutil.copytree(source_directory, "generatecode", dirs_exist_ok=True) + # 创建目录archives + if not os.path.exists("../../archives"): + os.mkdir("../../archives") + args = ['build/build.py', "build"] + try: + # 打开日志文件准备写入 + # 使用 subprocess.Popen() 执行命令,并将标准输出和标准错误重定向到日志文件 + start_time = time.time() + subprocess.Popen(['python'] + args, text=False) + end_time = time.time() + # 计算运行时间 + elapsed_time = end_time - start_time + time.sleep(2) + print(f"程序运行时间: {elapsed_time:.2f} 秒") + print(f"Finished: SUCCESS") + move_file("out/build.log", f'{global_combined}.log') + time.sleep(2) + move_file("out/bin/target.bin", f'{global_combined}.bin') + parent_dir = os.path.abspath(os.path.join(current_dir, os.pardir)) + os.chdir(parent_dir) + shutil.rmtree(copy_path) + except Exception as e: + print(f"An error occurred: {str(e)}") + + +def ci_entry(input_list): + ''' + Function description: ci entry function + ''' + os.chdir(build_directory_path) + tools_path = str(pathlib.Path().cwd().joinpath('tools', 'toolchain')) + print(f"start sample_build_prepare") + print(f"[sample_build_prepare] input_list: {input_list}") + global global_combined + for string in input_list: + parts = string.split('+') + sample_file_path = parts[0] + build_target = parts[1] + sample_name = parts[2] + platfor_name = parts[3] + remaining_parts = parts[1:4] + global_combined = '_'.join(remaining_parts) + if len(parts) >= 5: + global_combined += '_' + build_def_sha = hashlib.sha256('-'.join(parts[4:]).encode('utf-8',errors='ignore')) + global_combined += build_def_sha.hexdigest()[:32] + # 获取sample目录路径,并复制到指定目录 + # 截取目标内容 + target_string = sample_file_path.split('/build_config.json')[0] + '/' + samples = sample_name.replace('-','/') + source_directory = "../." + target_string + samples + print(f"[sample_build_prepare] source_directory: {source_directory}") + copy_path = 'mcu_' + platfor_name + '_project' + working_path = pathlib.Path.cwd() + if platfor_name == '3061M' or platfor_name == '3061m': + copy_chip = "3061m" + elif platfor_name == '3065H' or platfor_name == '3065h': + copy_chip = "3065h" + elif platfor_name == '3015' or platfor_name == '3015': + copy_chip = "3015" + elif platfor_name == '3066M' or platfor_name == '3066m': + copy_chip = "3066m" + else: + print(f"Wrong chip name\r\n") + exit(0) + differ_file_copy(copy_chip, copy_path, tools_path, source_directory) + + +def main(): + print(f"start main") + check_list = get_changed_folders_in_vendor() + input_list = process_build_info_files() + sample_name = extract_exact_match(input_list, check_list) + result_list = sample_meunconfig_modify(sample_name) + ci_entry(result_list) + print(f"all build step execute end") + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file -- Gitee