整合

http://blog.csdn.net/huangxianxinalice/article/details/9997981

Ethercat 程序与完整的EtherCAT 应用程序存在着区别。

[cpp]  view plain  copy
  1. unsigned short Ecat_Open(void)  
  2. {  
  3.     UINT16 result = 0;  
  4.     //开始函数应该被调用一次  
  5.     if(HardwareOpened != 0)  
  6.         return 1;  
  7.     u32Input = 0;  
  8.     u32Output = 0;  
  9.     pApplication = NULL;  
  10.     result = HW_Init();  
  11.     if(result == 0)  
  12.     {   MainInit();  
  13.         HardwareOpened = 1;  
  14.     }  
  15.    return result;  
  16. }  


[cpp]  view plain  copy
  1. /  
  2. /** 
  3. <span style="white-space:pre">  </span>\return   0 如果初始化成功的话,则返回0  
  4. <span style="white-space:pre">  </span>\brief  文件:Tieschw.c里面 
  5.         \brief  这个函数初始化EtherCAT的从站接口. 
  6. *////  
  7.   
  8. Uint8 HW_Init(void)  
  9. {  
  10.     Uint8 i;  
  11.     Uint16 u16PdiCtrl;  
  12.     /* ESC的内存接口,ESC的中断和给看门狗检测的ECAT定时器应该在这里被初始化微控制器的特殊区域 */  
  13.     bsp_init();  
  14.     /* 我们在这里等待,直到ESC完全启动 */  
  15.     do {  
  16.         HW_EscReadWord(u16PdiCtrl, ESC_ADDR_PDI_CONTROL);  
  17.         u16PdiCtrl = SWAPWORD(u16PdiCtrl) & 0xFF;  
  18.        } while (u16PdiCtrl != 0x80);        //寻找线上总线  
  19.   
  20.     //printf ("Detected ESC Onchip Bus interface\n");  
  21.   
  22.     /* 初始化AL_Event Mask 寄存器 */  
  23.     /* AL Event-Mask 寄存器是被初始化为0,因此没有ESC中断产生,AL Event-Mask寄存器将被适应在函数StartInputHandler在ecatslv.c这个文件里面。当状态转换从PREOP到SAFEOP状态 */  
  24.     nAlEventMask = 0;  
  25.     HW_ResetALEventMask(0);  
  26.     bsp_start_esc_isr();  
  27.   
  28.     /* 禁止所有的SM通道 */  
  29.     for (i = 0; i < MAX_SYNC_MAN; i++)  
  30.         HW_DisableSyncManChannel(i);  
  31.   
  32.     return 0;  
  33. }  


[cpp]  view plain  copy
  1. void bsp_init(void)  
  2. {  
  3.     Semaphore_Params semParams;  
  4. #ifndef USE_ECAT_TIMER      
  5.     Types_FreqHz  frg;  
  6. #endif      
  7.     t_mdio_params mdioParamsInit;       
  8.   
  9.     // 初始化定时器数据  
  10.     current_low = current_high = 0;  
  11.     pd_read_addr_err = pd_write_addr_err = 0;  
  12.     pdi_read_fail_cnt = pdi_write_fail_cnt = 0;  
  13.     prev_low = prev_high = 0;  
  14.     tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;  
  15. #ifndef USE_ECAT_TIMER  
  16.     BIOS_getCpuFreq(&frg);  
  17.     ecat_timer_inc_p_ms = (frg.lo/1000);  
  18. #endif      
  19.     pEsc = (Uint8*) PRUSS_SHAREDRAM_BASE;                   //初始化参数数据  
  20.     pHost2PruIntfc = (volatile t_host_interface *) DATARAM0_PHYS_BASE;  
  21.     pRegPerm = (volatile t_register_properties *) DATARAM1_PHYS_BASE;  
  22.     pIep = (volatile void *) PRUSS_IEP_BASE;  
  23.     pMdio =(volatile void *)PRUSS_MDIO_BASE;  
  24.   
  25. #ifdef ENABLE_PRUSS_HW_FIREWALL  
  26.     PRUSSDRVFireWallInit();  
  27. #endif      
  28.     bsp_hwspinlock_init();  
  29.       
  30.     if(get_app_reload_flag() != 0xAA)  
  31.     {  
  32.     ENABLE_PRUSS_ACCESS_FROM_HOST  
  33.   
  34.     prussdrv_pruintc_init(&pruss_intc_initdata);  
  35.   
  36.     /* 初始化ESC DPRAM指针 微控制器的特殊区域指向ESC物理内存的开始部分 
  37.        结构体MAKE_PTR_TO_ESC应该被定义在tieschw.h里面 */  
  38.     memset ((void*)sm_properties, 0, sizeof(sm_properties));  
  39.       
  40.     memset (pEsc, 0, 12*1024); //初始化ICSS的共享内存  
  41.     memset ((void*)pHost2PruIntfc, 0, 8*1024); //初始化PRU0的数据内存  
  42.     memset ((void*)pRegPerm, 0, 1024); //初始化PRU1的数据内存  
  43.     memset ((void*)&pRegPerm->reg_properties, 3, 4*1024);//初始化PRU1的数据内存  
  44.     bsp_pruss_cmd_intfc_write_word(0xFF, &pHost2PruIntfc->cmdhigh);  
  45.     bsp_pruss_cmd_intfc_write_word(0xFF, &pHost2PruIntfc->cmdlow);  
  46.       
  47.     bsp_write_word(TIESC_PORT0_TX_DELAY, ESC_ADDR_TI_PORT0_TX_START_DELAY);  
  48.     bsp_write_word(TIESC_PORT1_TX_DELAY, ESC_ADDR_TI_PORT1_TX_START_DELAY);  
  49.     
  50.     mdioParamsInit.clkdiv = TIESC_MDIO_CLKDIV;  
  51.     mdioParamsInit.addr0 = TIESC_MDIO_PHY0_ADDR;  
  52.     mdioParamsInit.addr1 = TIESC_MDIO_PHY1_ADDR;  
  53.     mdioParamsInit.enhancedlink_enable = TIESC_MDIO_RX_LINK_ENABLE;  
  54.     if(TIESC_MDIO_RX_LINK_ENABLE == mdioParamsInit.enhancedlink_enable)  
  55.     {  
  56.         //增强链接检测使能  
  57.         mdioParamsInit.link0pol = TIESC_LINK_POL_ACTIVE_LOW;  
  58.         mdioParamsInit.link1pol = TIESC_LINK_POL_ACTIVE_LOW;        
  59.     }  
  60.     else  
  61.     {  
  62.         //增强型连接检查禁止  
  63.         mdioParamsInit.link0pol = TIESC_LINK_POL_ACTIVE_HIGH;  
  64.         mdioParamsInit.link1pol = TIESC_LINK_POL_ACTIVE_HIGH;          
  65.     }  
  66.       
  67.     bsp_pruss_mdio_init (&mdioParamsInit);  
  68.       
  69.     bsp_esc_reg_perm_init();  
  70.     //触发PDI的看门狗在LATCH_IN里面,或者每个命令发送内固件  
  71.     bsp_set_pdi_wd_trigger_mode(PDI_WD_TRIGGER_LATCH_IN);  
  72.     prussdrv_pru_reset(0);  
  73.     prussdrv_pru_reset(1);  
  74.   
  75.     if((NULL != pru_frame_proc ) &&  
  76.        (NULL != pru_host_proc ) &&  
  77.        (0 != pru_frame_proc_len ) &&  
  78.        (0 != pru_host_proc_len))  
  79.     {  
  80.        /* PRU的固件被载入作为一个头文件在应用程序里面  */  
  81.         PRUSSDRVSetPRUBuffer(0, (Uint32*)pru_frame_proc, pru_frame_proc_len);  
  82.         PRUSSDRVSetPRUBuffer(1, (Uint32*)pru_host_proc, pru_host_proc_len);  
  83.         prussdrv_exec_program(1, "./ecat_host_interface.bin");  
  84.         prussdrv_exec_program(0, "./ecat_frame_handler.bin");  
  85.     }  
  86.     else  
  87.     {  
  88.         /* PRU 固件存储在SPI的flash里面. */  
  89.         PRUSSDRVLoadBinary(0,SPI_PRU0_BINARY_OFFSET);  
  90.         PRUSSDRVLoadBinary(1,SPI_PRU1_BINARY_OFFSET);  
  91.     }  
  92.     }  
  93.     set_app_reload_flag(0);  
  94.     bsp_eeprom_emulation_init();        //载入eeprom的文件到内存  
  95.     if(bsp_eeprom_load_esc_registers(0) == -1)  
  96.     {  
  97.         Uint16 EEPROMReg = 0;  
  98.         HW_EscReadWord(EEPROMReg,ESC_ADDR_EEPROM_CTRL);  
  99.         EEPROMReg = SWAPWORD(EEPROMReg);  
  100.         EEPROMReg |= ESC_EEPROM_ERROR_CRC;  
  101.         EEPROMReg = SWAPWORD(EEPROMReg);  
  102.     bsp_write_word (EEPROMReg, ESC_ADDR_EEPROM_CTRL);  
  103.     }  
  104.       
  105.     Semaphore_Params_init(&semParams);  
  106.     semParams.mode = Semaphore_Mode_BINARY;  
  107.     semcmdhigh_handle = Semaphore_create(1, &semParams, NULL);  
  108.     semcmdlow_handle = Semaphore_create(1, &semParams, NULL);  
  109.     escGlobalGateHandle = GateAll_create (NULL, NULL);  
  110. #ifdef PROFILE_SEND_CMD_TO_FIRMWARE  
  111.     memset (cmd_profile_array, 0, sizeof(cmd_profile_array));  
  112. #endif  
  113.       
  114.   
  115. }  



文件:Tiescbsp.c

[cpp]  view plain  copy
  1. void bsp_start_esc_isr(void)  
  2. {  
  3.     /* 使能ESC-中断微控制器的特殊领域,这个数据结构ENABLE_ESC_INT应该被ecat_def.h定义 */  
  4.     // 使能RTOS中断     
  5.     PRUSSDRVRegisterIrqHandler(HOST_AL_EVENT, 1, &EcatIsr);     
  6.     PRUSSDRVRegisterIrqHandler(HOST_CMD_HIGH_ACK_EVENT, 1, &EscCmdAckIsr);  
  7.     PRUSSDRVRegisterIrqHandler(HOST_CMD_LOW_ACK_EVENT, 1, &EscCmdLowAckIsr);  
  8.     PRUSSDRVRegisterIrqHandler(HOST_SYNC1_EVENT, 0, &Sync1Isr);  
  9. }  


[cpp]  view plain  copy
  1. /  
  2. /** 
  3.  \param     pObjectDictionary   指针指向应用程序特殊的对象字典 
  4.                                 NULL 如果没有特殊的对象可用 
  5.  \return     0 如果初始化成功的话 
  6.  
  7.  \brief    这个函数初始化EtherCAT的参考代码 
  8.  
  9. *////  
  10.   
  11. UINT16 MainInit()  
  12. {  
  13.     UINT16 Error = 0;  
  14.     /*硬件初始化函数需要在应用程序层被调用*/  
  15.     /* 初始化EtherCAT从站接口 */  
  16.     ECAT_Init();  
  17.     /* 初始化对象 */  
  18.     COE_ObjInit();  
  19.   
  20. #if DIAGNOSIS_SUPPORTED  
  21.     /*initialize Diagnose Message memory*/  
  22.     Diag_InitMemory();  
  23. #endif  
  24.   
  25. #if COE_SUPPORTED  
  26.     /*定时器的初始化*/  
  27.     u16BusCycleCntMs = 0;  
  28.     StartTimerCnt = 0;  
  29.     bCycleTimeMeasurementStarted = FALSE;  
  30. #endif  
  31.   
  32. #if ESC_EEPROM_ACCESS_SUPPORT  
  33.     /*重置PDI的接口*/  
  34.     {  
  35.     UINT32 eepromConfigControl = 0; //register (0x0500 : 0x0503) values  
  36.   
  37.     HW_EscReadDWord(eepromConfigControl,ESC_EEPROM_CONFIG_OFFSET);  
  38.   
  39.     /*清除接入寄存器(0x0501)*/  
  40.     eepromConfigControl &= SWAPDWORD(0xFFFF00FF);  
  41.   
  42.     HW_EscWriteDWord(eepromConfigControl,ESC_EEPROM_CONFIG_OFFSET);  
  43.     }  
  44. #endif  
  45. /*应用程序的初始化应该在应用层被调用*/  
  46.      return Error;  
  47. }  



[cpp]  view plain  copy
  1. /  
  2. /** 
  3.  \brief     这个函数初始化几个对象字典 
  4. *////  
  5.   
  6. void COE_ObjInit(void)  
  7. {  
  8.     /* 初始化SM 输出参数对象 0x1C32 */  
  9.     sSyncManOutPar.subindex0         = 32;  
  10.     /*子索引subindex 1 包含实际的同步模式,它可以被主站写来转换ECAT自由运行模式到ECAT同步运行模式 
  11.       如果从站支持两种模式的话,这个值将会被重写位SYNCTYPE_DCSYNC0或者SYNCTYPE_DCSYNC1在DC分布时钟模式当中 */  
  12.      /*缺省的模式是ECAT同步运行模式 */  
  13.     sSyncManOutPar.u16SyncType     = SYNCTYPE_SYNCHRON;  
  14.     /* 子索引subindex 2 包含应用程序的周期时间,在ECAT 自由运行模式下,它可以被用做一个定时器中断来运行应用程序,在同步模式下,它可以被主站写用它的本地周期时间,从站可以检查是否这个周期时间被支持,在分布时钟模式下,这个值将会被覆盖用它的DC周期寄存器 */  
  15.     sSyncManOutPar.u32CycleTime     = 0;  
  16.     /* 只是给DC模式:子索引3包含时间偏移在SYNC0(SYNC1)之间和当输出到硬件来允许来精确得计算延迟时间, 
  17.         (在这个例子,我们将使ESC中断程序里面做在线的测量) */  
  18.     sSyncManOutPar.u32ShiftTime     = 0;  
  19.     /* 子索引 subindex 4 包含支持的同步类型 */  
  20.     sSyncManOutPar.u16SyncTypesSupported    = SYNCTYPE_TIMESVARIABLE         /* 根据连接的模块,可执行的定时器 */  
  21.                                                         | SYNCTYPE_FREERUNSUPP            /* ECAT 自由运行模式被支持 */  
  22.                                                         | SYNCTYPE_SYNCHRONSUPP            /* ECAT 同步模式被支持 */  
  23. #if DC_SUPPORTED  
  24.                                                         | SYNCTYPE_DCSYNC0SUPP            /* DC 同步模式被支持 */  
  25. #endif  
  26.     ;  
  27.     /* 子索引5包含从站可以支持的最小的周期时间,它将会被动态得计算,因为它是根据连接的模块的,(在这个例子里,我们将在ESC中断处理里面实现在线测量)对于例子程序里面,这个值是MIN_PD_CYCLE_TIME*/  
  28.     sSyncManOutPar.u32MinCycleTime = MIN_PD_CYCLE_TIME;  
  29.     /* 只有在DC模式上,子索引6包含从站需要的在接收到SM2事件以后的最小的延迟时间在SYNC0(SYNC1)可以接收之前,没有延迟,它将被动态得计算因为它是根据连接模块的(在这个例子我们将是在线测量在ESC中断处理中完成) */  
  30.     sSyncManOutPar.u32CalcAndCopyTime = (PD_OUTPUT_CALC_AND_COPY_TIME);  
  31.   
  32.     /*subindex 8: 触发周期时间测量*/  
  33.     sSyncManOutPar.u16GetCycleTime = 0;  
  34.   
  35.     /*subindex 9: 从开始输出到输出有效的时间*/  
  36.     sSyncManOutPar.u32DelayTime = (PD_OUTPUT_DELAY_TIME);  
  37.   
  38.     /*subindex 32: 指示是否同步错误发生*/  
  39.     sSyncManOutPar.u16SyncError = 0;  
  40.   
  41.     /* 初始化SM的输入参数对象0x1C33 */  
  42.     sSyncManInPar.subindex0         = 32;  
  43.     /* 缺省的模式是ECAT同步模式,如果输出大小是大于0,输入被SM2事件更新 */  
  44.     sSyncManInPar.u16SyncType         = SYNCTYPE_SM2INT;  
  45.     /* subindex 2: 与 0x1C32:02相一样 */  
  46.     sSyncManInPar.u32CycleTime     = sSyncManOutPar.u32CycleTime;  
  47.     /* only for DC Mode important: subindex 3 包含时间偏移在SYNC0(SYNC1)信号当输入已经到了硬件,允许主站精确得计算延迟时间,将会动态得计算,更具它连接的模块(在例子里面我们将在ESC中断处理里面做在线测量) */  
  48.     sSyncManInPar.u32ShiftTime     = 0;  
  49.     /* subindex 4: same as 0x1C32:04 */  
  50.     sSyncManInPar.u16SyncTypesSupported    = sSyncManOutPar.u16SyncTypesSupported;  
  51.     /* subindex 5: same as 0x1C32:05 */  
  52.     sSyncManInPar.u32MinCycleTime = sSyncManOutPar.u32MinCycleTime;  
  53.     /* subindex 6: delay read inputs, calculation and copy to SM buffer*/  
  54.     sSyncManInPar.u32CalcAndCopyTime = (PD_INPUT_CALC_AND_COPY_TIME);  
  55.     /*subindex 8: t触发周期时间的测量 */  
  56.     sSyncManInPar.u16GetCycleTime = 0;  
  57.     /*subindex 9: 准备输入的延迟delay to prepare input latch*/  
  58.     sSyncManInPar.u32DelayTime = (PD_INPUT_DELAY_TIME);  
  59.   
  60.     /*subindex 32: 如果同步错误发生的话,它将增加*/  
  61.     sSyncManInPar.u16SyncError = 0;  
  62.   
  63. #if !STATIC_OBJECT_DIC && COE_SUPPORTED  
  64.     {  
  65.     UINT16 result = COE_ObjDictionaryInit();  
  66.     if(result != 0)  
  67.     {  
  68.         /*清除已经存在的连接对象*/  
  69.         COE_ClearObjDictionary();  
  70.     }  
  71.     }  
  72. #endif  
  73.   
  74. #if SDO_RES_INTERFACE  
  75. /* ECATCHANGE_START(V5.01) SDO6*/  
  76.     u8PendingSdo = 0;  
  77.     bStoreCompleteAccess = FALSE;  
  78.     u16StoreIndex   =   0;  
  79.     u8StoreSubindex = 0;  
  80.     u32StoreDataSize = 0;  
  81.     pStoreData = NULL;  
  82.     pSdoPendFunc    = NULL;  
  83. /* ECATCHANGE_END(V5.01) SDO6*/  
  84. #endif  
  85.   
  86. #if SEGMENTED_SDO_SUPPORTED  
  87.     pSdoSegData = NULL;  
  88. #endif  
  89. }  


[cpp]  view plain  copy
  1. /  
  2. /** 
  3.  \return    0               对象字典创建成功 
  4.             ALSTATUSCODE_XX 创建对象字典失败 
  5.  
  6.  \brief    这个函数初始化对象字典T 
  7. *////  
  8. UINT16 COE_ObjDictionaryInit(void)  
  9. {  
  10.     UINT16 result = 0;  
  11.   
  12.     /*重置对象字典的指针*/  
  13.     ObjDicList = NULL;  
  14.   
  15.     result = AddObjectsToObjDictionary((TOBJECT OBJMEM *) GenObjDic);  
  16.   
  17.     if(result != 0)  
  18.         return result;  
  19.     if(ApplicationObjDic != NULL)  
  20.     {  
  21.         result = AddObjectsToObjDictionary((TOBJECT OBJMEM *) ApplicationObjDic);  
  22.     }  
  23.   
  24.     return result;  
  25. }  
  26. #endif //#if !STATIC_OBJECT_DIC  



[cpp]  view plain  copy
  1. Parameters  
[cpp]  view plain  copy
  1. <pre name="code" class="cpp">• outputs_running: 如果设置了,只是运行在OP状态  
  2. • Return value: none  
  3. Description:函数只是用户应用程序,它更新从从站来的32位的数据输入(u32Input)和执行来自主站的32位数据输出(u32Output)。这个由Beckhoff SSC library的例子应用程序接口从SYNC0 ISR(DC同步模式)或者PDI ISR(SM同步模式)根据主站选择的同步模式。u32Input应该被设置根据8位数据I/O或者任何预先设定的数据,u32</pre><pre name="code" class="cpp">output应该被用来更新数据输出LEDs 。</pre><pre name="code" class="cpp"></pre><pre name="code" class="cpp">*pApplication</pre>void (* pApplication)(unsigned short);<br>  
  4. <pre></pre>  
  5. <br>  
  6. <br>  
  7. <p><br>  
  8. </p>  
  9. <p><br>  
  10. </p> 
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值