BSP做过的IC项目工程:红外、环境光、距离传感器IC项目I2DR读写,ICM20608芯片多轴传感器项目,指纹项目,多点电容触摸屏,PWM配置占位比操控背光项目,Camera模组 OV264n、OV564n、OV7725。
UBoot烧写linux
linux (驱动|裸机)项目:
1.配置设备启动方式(boot_mode:fuses、serial downlaoder、internal boot[USB、MicroSD、EMMC、NAND])。
2.熟悉8路PLL和8路PFD原理图:配置ARM PLL、USB PLL、 AHB、IPG 、System PLL寄存器给各种设备提供信源,配置SCTLR开启MMU和caches,加载boot_CFG,设定DDR数据开始位置,写入IVT和Boot Data,解析DCD(1768B)等。
3.PLL与时间操控方案实现:EPIT芯片,PWM芯片、SysTick_clk硬件方案GPT(CR、PR、SR、IR、OCR、ICR、CNT)。
4.自定义startup,设定SystemInt,设置FLASH_BASE,自定义start.S配置(_bss_start )中断向量表VBAR、EXTIO_IRQHandler处理与EXTIO性能调试,熟悉Cortex-A7的8个中断模式,编写FIQ_Handler(VFIQ VIRQ FIQ IRQ),配置处理器选择SPIs、PPIs、SGI,给处理器提供中断优先级处理流程,熟悉GICC_IAR、GICC_EOIR 等参数传递流程;熟悉GPIO_ICR执行逻辑(GPIO_ISR、GPIO_EDGE_SEL、GPIO_EDGE_IMR),如电平读取,ISR写1清除,IMR取反禁用中断等。配置PMU(128 IRQ ID SOC相关)等。
5.熟悉Cortex-A的9中运行模式(User、FIQ、Supervisor、Monitor、Abort、Hyp、Undef、System),常用处理器指令如[(MRC|MCR) {cond} core_type, <opc1>,<Rt>,<CRn>,<CRm>,<opc2>],熟悉VBAR处理DMB、DSB、ISB逻辑,以及SVC模式处理,熟悉ARM指令流程:取指,译指,执行细节。
6.搭建UART通讯进行人机指令交互,USART连接设备芯片实现USART数据转USB数据,以及性能调试。UART配置项RTS、IREN、doze、DMA、idle_interrupt、ADBR、sRST等。配置对应的时钟源匹配选择器配置有CSCDR1[UART_CLK_SEL]、CSCDR1[UART_CLK_PODF]等。通过UFCR、UBMR和UBIR计算出BaudRate,TX/RX设定为同一个SETPINCONFIG,细节处理如数据位、奇偶验证等。
7.SRAM和RAM对linux很重要,熟悉DDR3L/1.35v,通过PLL选择PFD,CBCDR[FABRIC_MMDC_PODF] 等配置clk,精通DDR3L超频以及测试、校准(tRCD、CL、tRC、tRAS).
8.常用LCD接口:MIPI、LVDS、MCU、RGB,如RGB的DOTCLK和VSYNC模式。精通HSYNC与VSYNC处理流程与原理,如:HSYNC_clk(行时间)计算:HSPW+HBP+WIDTH+HFP。LCDIF_VDCTRL0n极性配置,显存空间设定:H*W*4bit等.
9.精通LCD信源配置PLLn_CLK(Fref*DIV_SELECT),CCM_ANALOG_PLL_VIDEO、CCM_ANALOG_MISC2、CCM_ANALOG_PLL_VIDEO_NUM、CCM_ALALOG_PLL_VIDEO_DENOM,(厂商配置参数如:height、width、vspw、sbpd、vfpd、hspw、hbpd、hfpd)
10.熟悉LCD读点打点以及GUI_lib库引用。
熟悉UBOOT,精通部分版本的Uboot:
配置U-boot.lds进入_start对应/arch/arm/lib/verctors.S配置资源入口,生成uboot.map信息。
__image_copy_start存放arch/arm/cpu/armv7/start.o 部分流程实现如arch/arm/cpu/armv7/start.S
1.配置save_boot_params 调用重置函数执行(teq r1, 0x1a)配置Cortex-A运行模式为Hyp,然后再进入SVC模式。
2.读取处理器SCTLR值,配置CR_V实现向量表配置VBAR
3.进入cpu_init初始化CPU,cpu_init_crit停止MMU初始化内存,配置lowlevel_init.S,调用CONFIG_SYS_INIT_SP_ADDR表示从CONFIG_SYS_INIT_RAM_SIZE到GENERATED_GBL_DATA_SIZE(IRAM_SIZE-IRAM_BASE_ADDR)都是OCRAM。
整个流程就是关闭中断初始化换中断向量表,初始化CPU。
熟悉main函数主要调用board_init_f,relcate_code,relocate_vectors,board_init_r
在main函数中执行board_init,初始化外设,加载gd数据到内存,重定位DRAM到linux数据之后的内存区域,然后初始化DDR寄存器,调用relocate函数把uboot写入DDR中。
board_init_f:(board_early_init_f, timer_init,env_init,init_baudrate serial_init,console_init_f,display_banner, dram_init)
board_init_r:(初始化NORFLASH,NANDFLASH,ONENAND FLASH,初始化环境变量,初始化PCI,设置IP地址,初始化各类外设:IIC、LCD、键盘、USB,初始化控制台,建立IRQ中断堆栈,初始化以太网)
main_loop:(cli_init,run_preboot_environment_command,bootdelay_process,autoboot_command),期间通过fdt函数解析指令加载设备树,设置zimage幻数的地址,执行bootz指令。bootz_setup调用do_bootz设置images.os.os=IH_OS_LINUX,调用do_boot_states启动linux OS。调用boot_prep_linux设定bootargs。最后通过boot_jump_linux调用到kernel_entry 启动linux。
熟悉uboot厂商版本定制或移植,修改编译资源等,各厂商独有编译指南如:
1.uboot/uboot-targetVersion/board/boardType/target_emmc/Kconfig编译板子配置。
2.uboot/uboot-targetVersion/arch/arm/cpu/armv7/mx6/Kconfig配置图行界面support对应编译脚本。
移植过2个uboot项目与烧写测试成功。
LCD驱动
修改目录 uboot/uboot-targetVersion/configs/下的boardVersion_emmc.h, boardVersion_emmc.c
当前c文件可配置nand_pads,uart1_pads,usDHC_pads,sdcard_pads,fec1_pads,fec2_pads.找到lcd_pads.
相同目录下有boardVersion_pins.h,这个文件定义好相关的gpio变量.在lcd_pads中定义了所有的宏变量,对应底板检查lcd的宏变量,如屏幕背光引脚等。
同样找到display_info_t 会有fb_framemode构造声明pixclk等。
boardVersion_emmc.c 中有display[]
1.定义bus为boardVersion_LCDIF1_BASE_ADDR.这个地址是AIPS2_ARB_BASE_ADDR+0x80000+0x48000指向LCD设备的开始地址,这个必须对应参考文档确定。
2.enable 设定LCD为高电平时工作。
3.mode就是匹配屏幕厂商参数如:pixclock,型号等。
uboot网络驱动(KSZ8081|LAN8720A)没有MAC芯片的网络芯片使用DM9000方案
LAN8720A通过MDIO接口管理32个PHY芯片。
根据IC厂商修改PHY地址。首先删除uboot中原有的网卡驱动以及宏定义(根据对应的GPIO可以找到相应的网卡配置),配置fec1和fec2 都修改 ENET1_RESET ENT2_RESET初始化gpio引脚,
在/drivers/net/phy/phy.c 中的 genphy_update_link函数中写入BMSR寄存器数据,添加厂商设定的宏定义如(CONFIG_PHY_SMSC)添加软复位功能,代码实现比较通用。
配置LAN8720A寄存器,检查CONFIG_CMD_NET,CONFIG_FEC_ENET_DEV 确定FEC_BASE的值正确
include/configs/boardVersion_evk.h定义内存开始地址0x80000000,bootcmd,bootargs,I2C,PMIC等宏控.
uboot/uboot-targetVersion/include/env_default.h 配置默认环境变量 bootargs,bootcmd,ramboot,nfsboot,baudrate,fdt等,这两个文件组成bootz zImage执行指令.
熟悉uboot DDR初始化流程,了解IVT与DCD数据构造,检测DDR 寄存器校准。
编译linux kernel 的zImage(/arch/arm/boot/zImage)和.dtb(./arch/arm/boot/dts/***.dtb)编译流程
如(dtb编译:make ***.dtb \ zImage编译 make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/zImage)
执行指令启动linux kernel:tfpt 80800000 zImage \ tftp 83000000 ***.dtb \ bootz 80800000 - 83000000
Linux kernel
1.熟悉linux编译流程(scripts/kconfig,scripts/link-vmlinux.sh,built-in.o,zImage)与启动流程(arch/arm/kernel/vmlinux.lds)
2.启动流程简述:vmlinux.lds 调用ENTRY(stext),上面描述过裸机操作MMU关闭与清空D cache,执行do_boot_linux函数调用kernel_entry传递通过ro,r1(machine nr),r2(Atags|dtb)
3.目录linux/kernel/arch/arm/kernel/head-common.S
__lookup_processor_type 执行__lookup_processor_type_data入栈R5=procinfo,调用__vet_atags取到R1 machine id, R2:atags|dtb设备树, r8:物理偏移地址, r9:cupid, r10:cpu描述cpu struct bl __create_page_tables的R13保留 __mmap_switched,继续执行b __enable_mmu, 然后就是b start_kernel.
4.start_kernel会调用大量的init函数如lockdep_init,set_task_stack_end_magic,smp_setup_processor_id,lock_irq_disable,boot_cpu_init,page_address_init,setup_nr_cpu_ids,setup_per_cpu_areas,sched_init,rcu_init等,其中会调用rest_init函数操作rcu_scheduler_starting,运行kernel_thread,init_idle_bootup_task最后调用cpu_startup_entry,函数内部会调用cpu_idle_loop,熟悉ARMv7-A处理器。
5.kernel_init 调用ramdisk_execute_command判断linux os是否存在init,/sbin/init,ect/init 等资源
定制EMMC|NAND版本linux kernel zImage
1.定制linux kernel Image:自定义arch/arm/configs/vendortype_defconfig, 添加到arch/arm/boot/dts/Makefile编译出dtb,linux kernel编译出客制化zImage。
2.CPU超频配置:arch/arm/configs/vendortype_defconfig配置CPU_FREQ ,arch/arm/boot/dts/vendor_type.dtsi 修改cpu属性[operating-points],[soc-operating-points]添加主频配置值,编译dtb验证。
3.linux网卡驱动(LAN8720)以及dts配置。
5.多种方式搭建rootfs。
6.熟悉dsp项目移植,soc项目移植。