1 创建工程
在Vitis中, 使用design_A1eg3_22071515.xsa创建空白工程, 替换src目录文件.
再bsp中设置打开lwip,并将lwip的pbuf_pool_size参数修改为2048
在.\工程目录\design_A1eg3_22071515\psu_cortexa53_0\domain_psu_cortexa53_0\bsp\psu_cortexa53_0\libsrc\lwip211_v1_2\src\contrib\ports\xilinx\netif
替换以下文件:
xemacpsif_hw.c
xemacpsif_physpeed.c
xadapter.c
在.\工程目录\design_A1eg3_22071515\psu_cortexa53_0\domain_psu_cortexa53_0\bsp\psu_cortexa53_0\libsrc\emacps_v3_11\src
替换以下文件:
xemacps_control.c
2 函数分析:从main开始
for循环 0~10 pFrames是指向帧缓冲区的指针数组 并使用memset 将所有的元素置为0 元素个数为2* 1024 pFrames指向10行2*1024列的二维数组frames
强制64字节对齐
Xil_DCacheFlushRange把Cache里的数据Flush出去,清空Cache,将Cache的内容推到DDR中去
点云数据发送的缓存
中断初始化
InterruptInit(XPAR_SCUGIC_0_DEVICE_ID,&XScuGicInstance); 参数:设备id、结构体指针
&XScuGicInstance是指向结构体XScuGic的指针,结构体包含设备初始化状态isready、UnhandledInterrupts、和XScuGic_config配置指针
配置内容为:设备id、cpu接口寄存器基地址、分发服务器注册基址、中断处理程序矢量表(xilinx中断处理函数 handler,回调函数实例指针)
typedef void (*Xil_InterruptHandler)(void *data);
typedef struct
{
Xil_InterruptHandler Handler;
void *CallBackRef;
} XScuGic_VectorTableEntry;
typedef struct
{
u16 DeviceId; /**< Unique ID of device */
u32 CpuBaseAddress; /**< CPU Interface Register base address */
u32 DistBaseAddress; /**< Distributor Register base address */
XScuGic_VectorTableEntry HandlerTable[XSCUGIC_MAX_NUM_INTR_INPUTS];/**< Vector table of interrupt handlers */
} XScuGic_Config;
typedef struct
{
XScuGic_Config *Config; /**< Configuration table entry */
u32 IsReady; /**< Device is initialized and ready */
u32 UnhandledInterrupts; /**< Intc Statistics */
} XScuGic;
中断控制器初始化:
XScuGic_LookupConfig函数:返回指向 XScuGic_Config*
1. for循环查找目前的可用设备:目前数量1,设备号为0U XPAR_PSU_ACPU_GIC_BASEADDR:0xF9020000U
XPAR_PSU_ACPU_GIC_HIGHADDR:0xF9020FFFU XPAR_PSU_ACPU_GIC_DIST_BASEADDR:0xF9010000U
XScuGic_CfgInitialize
2. 判断XScuGic初始化状态:
2.1 Xil_AssertNonvoid 断言函数,判断参数输入InstancePtr、ConfigPtr指针是否正确,不为NULL
2.2 判断XPAR_CPU_ID==0x01 不相等跳过不进入
2.3 判断XScuGic的IsReady 是否与0x11111111U 不相等 进入条件 设置isready:0U InstancePtr->config指针指向XScuGic_Config 的配置
for循环 0U~195U 一直循环到Zynq Ultrascale Mp定义的最大中断数
又判断 中断处理矢量表的headler 是否为NULL 条件为真 则赋值为 StubHandler的headler
CPUInitialize 函数 基地址(0xF9020000U)+cpu_offset + 不同值
isready=0x11111111U
中断初始化状态success
InterruptSystemSetup函数
3. 中断系统设置
3.1 注册GIC中断处理程序 进行XExc_VectorTable的handler、data复制操作
中断初始化状态success 完成
定时器
m25s_irq_init
XScuGic_LookupConfig函数:返回指向 XScuGic_Config* 参数:0U
1. for循环查找目前的可用设备:目前数量1,设备号为0U XPAR_PSU_ACPU_GIC_BASEADDR:0xF9020000U
XPAR_PSU_ACPU_GIC_HIGHADDR:0xF9020FFFU XPAR_PSU_ACPU_GIC_DIST_BASEADDR:0xF9010000U
PS_timer_init(&Timer, XPAR_XTTCPS_1_DEVICE_ID ,40); 返回值:void 参数:结构体 XTtcPs* 、1U、频率40(25ms)
typedef struct {
u16 DeviceId; /**< Unique ID for device */
u32 BaseAddress; /**< Base address for device */
u32 InputClockHz; /**< Input clock frequency */
} XTtcPs_Config;
/**
* The XTtcPs driver instance data. The user is required to allocate a
* variable of this type for each PS timer/counter device in the system. A
* pointer to a variable of this type is then passed to various driver API
* functions.
*/
typedef struct {
XTtcPs_Config Config; /**< Configuration structure */
u32 IsReady; /**< Device is initialized and ready */
XTtcPs_StatusHandler StatusHandler;
void *StatusRef; /**< Callback reference for status handler */
} XTtcPs;
对比与中断初始化
相同点:1. 结构体内容非常相似,比如:都有设备id、基地址、isready(判断初始化完成状态)、reference、headler
2. 设置过程类似,都是上来for循环查找设备id,同时初始化基地址(XScuGic_LookupConfig函数)
再去初始化配置(XTtcPs_CfgInitialize),判断输入是否合规,再进行赋值操作,比如:DeviceId、BaseAddress、Handler
3. 对不同设备对应的寄存器操作类似,基地址+地址偏移量+具体的值(根据寄存器设置)
2. 定时器赋值后,开启定时器 0XFF110004U 0x0000000CU 0x00000001U 如果启用预缩放,计数率除以2^(N+1)
#define XTtcPs_IsStarted(InstancePtr) ((InstReadReg((InstancePtr), XTTCPS_CNT_CNTRL_OFFSET) & XTTCPS_CNT_CNTRL_DIS_MASK) == 0U)
将TTC 寄存器的值读出来并与1进行 & 位运算 同时进行对比判断启动是否成功
3. 条件判断 启动成功则状态被设置:5L 启动成功;假 1. 重置之前设置的寄存器 2. 重新写入 时钟控制、间隔计数、匹配(0、1、2)、中断启用、中断状态寄存器
IsReady为0x11111111U 表示定时已准备
并进行读写测试
功能状态XST_success
4. 调用系统API,设置TTC设置选项:计算给定频率(XTtcPs_SetOptions)、间隔和预分频器(XTtcPs_CalcIntervalFromFreq)
设置间隔模式中使用的间隔值(XTtcPs_SetInterval)、设置预分频器启用位(XTtcPs_SetPrescaler)、启用计时/计时(不重置计数器值,XTtcPs_Start)
5. InterruptConnect(XScuGicInstancePtr,XPAR_XTTCPS_1_INTR,Timer_Handler,(void *)&Timer);
根据中断向量表,当中断来时根据中断号找到相应的中断服务程序并执行,将中断服务与Timer_Handler绑定一起
liangdao123