最终解决方式在结尾。
模板测试
之前新建project,用lwip模板测是成功通信的。
但是把它移植到大程序里面,就ping不通。但是配置、速率自适应等都没问题:
mmu_table.s
然后前前后后也修改了很多部分:
mmu_table.s —— AHB_SRAM uncachable
.icf ——程序放到DDR运行(因为网口程序太大了,默认的AHB_SRAM放不下)
bsp中移除mmu_table.s(但是不删除文件),在main.c所在的文件夹内添加 mmu_table.s
.icf如下:
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000;
define symbol __ICFEDIT_region_ROM_end__ = 0x1ffff;
//define symbol __ICFEDIT_region_RAM_start__ = 0x20000;
define symbol __ICFEDIT_region_RAM_start__ = 0x24000;
define symbol __ICFEDIT_region_RAM_end__ = 0x5FFFF;
/* The AHB sram is uncacheable in default in the mmu_table.s */
define symbol __AHB_SRAM_START = 0xE1FE0000;
define symbol __AHB_SRAM_END = 0xE1FFFFFF;
define symbol __AXI_DDR_UNCACHE_START = 0x00100000;
define symbol __AXI_DDR_UNCACHE_END = 0x001FFFFF;
//define symbol __AXI_DDR_CACHE_START = 0x00200000;
define symbol __AXI_DDR_CACHE_START = 0x00204000;
define symbol __AXI_DDR_CACHE_END = 0x3FFFFFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_vectors__ = 0x100;
define symbol __ICFEDIT_size_freertos_vectors__ = 0x100;
define symbol __ICFEDIT_size_cstack__ = 0x4000;
define symbol __ICFEDIT_size_irqstack__ = 0x8000;
define symbol __ICFEDIT_size_fiqstack__ = 0x100;
define symbol __ICFEDIT_size_abtstack__ = 0x100;
define symbol __ICFEDIT_size_undstack__ = 0x100;
define symbol __ICFEDIT_size_heap__ = 0x600000;
/*-Exports-*/
export symbol __ICFEDIT_region_RAM_start__;
export symbol __ICFEDIT_region_RAM_end__;
export symbol __ICFEDIT_size_vectors__;
export symbol __ICFEDIT_size_cstack__;
export symbol __ICFEDIT_size_irqstack__;
export symbol __ICFEDIT_size_fiqstack__;
export symbol __ICFEDIT_size_heap__;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region VEC_region = mem:[from __AXI_DDR_CACHE_START size __ICFEDIT_size_vectors__];
define region VEC_freertos_region = mem:[from __AXI_DDR_CACHE_START +__ICFEDIT_size_vectors__ size __ICFEDIT_size_freertos_vectors__];
define region RAM_region = mem:[from __AXI_DDR_CACHE_START+__ICFEDIT_size_vectors__+__ICFEDIT_size_freertos_vectors__ to __AXI_DDR_CACHE_END];
define region AHB_SRAM_region = mem:[from __AHB_SRAM_START to __AHB_SRAM_END];
define region AXI_DDR_region_uncache = mem:[from __AXI_DDR_UNCACHE_START to __AXI_DDR_UNCACHE_END];
define region AXI_DDR_region_cache = mem:[from __AXI_DDR_CACHE_START to __AXI_DDR_CACHE_END];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
define block HEAP with alignment = 32, size = __ICFEDIT_size_heap__ { };
initialize by copy with packing=none { readwrite };
do not initialize { readonly section .noinit };
//define region MMU_TBL_region = mem: [from 0x20000 to 0x23FFF];
define region MMU_TBL_region = mem: [from 0x00200000 to 0x00203fff];
place in MMU_TBL_region { section .mmu_tbl };
place in VEC_freertos_region { section .freertos_vectors };
place in VEC_region { section .vectors };
place in RAM_region { readonly };
place in RAM_region { section .cstartup };
place in RAM_region { readwrite, block IRQ_STACK, block FIQ_STACK, block ABT_STACK, block UND_STACK, block CSTACK };
place in AHB_SRAM_region {section GMAC_DES};
//place in AXI_DDR_region_uncache {section GMAC_DES};
place in RAM_region {block HEAP};
//place in RAM_region { readwrite, block IRQ_STACK, block FIQ_STACK, block ABT_STACK, block UND_STACK, block CSTACK, block HEAP };
//place in AXI_DDR_region {readwrite, block IRQ_STACK, block FIQ_STACK, block ABT_STACK, block UND_STACK, block CSTACK, block HEAP };
/* all DDR */
//place in AXI_DDR_region_cache { section .mmu_tbl };
//place in AXI_DDR_region_cache {section .vectors, readonly, section .cstartup, readwrite, block IRQ_STACK, block FIQ_STACK, block ABT_STACK, block UND_STACK, block CSTACK, block HEAP };
可以发现,mmu、vectors、freetrtos、ram都放在了 DDR_cachable
程序修改
Intc名称、删除GIC初始化部分
u32 status = FMSH_SUCCESS;
//FGicPs_SetupInterruptSystem(&Intc);// 不要重复初始化
FGicPs_SetPriorityTriggerType(&Intc,GMAC0_INT_ID,0xA0,0x3);
status= FGicPs_Connect(&Intc, GMAC0_INT_ID,(FMSH_ExceptionHandler)gmac_interrupt_handler,
(void *)0);
if(status != FMSH_SUCCESS)
{
fmsh_print("Lwip irq set failed\r\n");
//return status;
}
// 不要重复初始化:
//FMSH_ExceptionRegisterHandler(FMSH_EXCEPTION_ID_FIQ_INT, (FMSH_ExceptionHandler)FGicPs_InterruptHandler_FIQ,&Intc);
FGicPs_Enable(&Intc, GMAC0_INT_ID);
就是进不去中断啊啊啊啊。。。
void FGmacPs_GmacRxCallback(FGmacPs_Instance_T *pGmac,int32_t ecode)
{
TRACE_OUT(DEBUG_OUT_EHT, "rx int\r\n");
g_rcv_cnt++;
TRACE_OUT(DEBUG_OUT_EHT, "rx cnt:%d\r\n",g_rcv_cnt);
// /* close irq */
// FGmac_Ps_SetupIntr(pGmac, gdma_irq_none);
// ethernetif_input(&Gmac_LwIP_if);
// /* poll */
// while(ethernetif_input(&Gmac_LwIP_if)!= ERR_OK);
// /* open irq */
// FGmac_Ps_SetupIntr(pGmac, gdma_irq_all);
}
g_rcv_cnt一直是0。所以进不去 if (g_rcv_cnt > 0)
寄存器对比(感觉好像并不用)
对比两个程序的GMAC0寄存器:
offset为0x1004、0x104c、0x1050、0x1054的寄存器不一样
大程序运行结果:
Lwip程序运行结果:
0xf890_1100这行为不同中断号:08位置处刚好是bit[51]置高,(GMAC0的中断号是51)
以自己目前仅有的水平,感觉GMAC和PHY的寄存器配置没问题。
那么是DMA的问题?
DMA
单步调试模板程序,DMA_Init,发现:
放到了DDR,那么在大程序中就刚好和程序位置冲突了。(调了几天,终于看到了点希望。就在自己坚持不下去想要咨询大神的时候。但是大神也没用过fmql。不得不说,fmql代码的注释是真的少)
/* 模板 */
flush_dcache_range(range_start, range_end); // RX
// range_start 0x229700
// range_end 0x2f1740
flush_dcache_range(range_start, range_end); // TX
// range_start 0x2f1700
// range_end 0x3b9740
看.map的内存使用情况,发现这部分内存是HEAP部分:
再看mmu_table.s的内存放置位置:
define symbol __ICFEDIT_size_heap__ = 0x600000;
define region RAM_region = mem:[from __AXI_DDR_CACHE_START+__ICFEDIT_size_vectors__+__ICFEDIT_size_freertos_vectors__ to __AXI_DDR_CACHE_END];
place in RAM_region {block HEAP};
大程序:
range_start和range_end都在HEAP里面。
这么说,不是这的问题喽?(好吧,又打回原形了)
PHY
所以进不去中断、ping不通的原因是什么?
PHY芯片配置不对?
隔了两周之后又来调
服了,编译不通过。。。。。。
no definition for ''GIC_SelfTest''
明明fmsh_gic.h声明,ethernet_interface.h声明,ethernet_interface.c定义。
怎么就no definition了?????之前还好好的
我真服了
然后作了如下修改:
把GIC_SelfTest放到fmsh_gic.c定义。
醉了
改成轮询模式试试★
【以下为和复旦微官方的技术人员沟通的对话简述】
可以通信。
说明是中断没配置好。
但是为啥别的模块的中断能用?
.icf改了吗?
改了。
注意程序用的DDR和lwip的DDR别冲突
这怎么看?
是否设置了USE_AMP=1
记得好像在工程的options里设置了(不知道有没有删除,只记得曾经有过这么一个操作)
单核的话,应该是USE_AMP=0
修改下试试。(打开发现并没有写USE_AMP=1,但还是把=0加上试试)
不太行。
在gic.c中的USE_AMP=1部分中,添加错误代码,看看编译能通过不
编译通过了。
那就是中断初始化的问题,或者是寄存器的问题
(啊这,没想到最后还是---可能是---中断配置的问题。)
查看寄存器状态
GMAC0:
GIC:
大程序GIC
初始化:
上图不一样。例程中有数据的地方都是0xa0
上图一样。
运行完:
上图不一样的没什么影响。中断使能
0xc和0x14、0x20、0x28的数据不一样。其中0xc代表中断应答(0x2a:CPU_ID=0,INTR_ID=0x2a)
大程序GMAC0
初始化:
0xd8的数据不一样。 SGMII/RGMII/SMII 状态寄存器
【中间没放出来的都为0 】
大程序GIC(仅lwip)
上图一样。
上图一样。
g_rcv_cnt
0x200、0x300也都是一样的现象。
没有接收中断响应。
why?中断配置不对?
中断使能和屏蔽没设对?
进中断了:
思考
能进入中断(只能进3次),说明中断配置是没问题的吧?
那就有可能是自愿冲突,比如内存重复占用。
试试改一下位置:
好吧,没用。
程序是能进三四次中断的,然后进行一次g_rcv_cnt++ ---> g_rcv_cnt --,然后就进不去中断了。
why。
延时处理★
看了下程序,发现了注释内容:
目前的状态是:否。
所以,是延时的问题?但是要怎么弄。不太会啊(延时多久,语句放在哪里)
【所以目前应该不是程序的问题,更不是中断的问题。而是例程本身就有问题。。。】
后续来了★★
是工程本身的原因。
Empty工程没有自动生成以下内容:(是我自己后来添加的)
而Lwip工程是自动生成的。
所以把所有程序移到Lwip工程下就可以了。