1、本實驗過程來自博b站大神《神電測控》,原文地址:
EPICS實戰(上位機篇):基于LV ZYNQ實現的EPICS通信系統(大物理) - 嗶哩嗶哩https://www.bilibili.com/opus/933476043369480224EPICS實戰(下位機篇):基于LV ZYNQ實現的EPICS通信系統(重點) - 嗶哩嗶哩
https://www.bilibili.com/opus/933487674120994835/?from=readlist2、CA下載地址,選擇32位的,安裝過程見b站大神的上位機篇。
Downloads - Helmholtz-Zentrum Berlin (HZB)Downloads of CA Labhttps://www.helmholtz-berlin.de/zentrum/organisation/it/calab/downloads_en.html3、SD卡分區。這個是Alinx產品自帶的,自帶debian8操作系統,有需要的聯系我即可。
4、測試安裝
a、使用筆記本給7020聯網(全網唯一)
(1)在筆記本上將無線和網口建立網橋;
(2)將網線把筆記本和另一臺電腦連起來;
(3)拔掉網線,將網線插入7020,7020即可聯網。
注意:直接給7020插入網線,7020可能會因為ip配置錯誤,導致無法聯網。
b、安裝EPICS
下載epics 3.16.2,也可以去官網直接下載,然后通過winscp傳上去
#下載epics
cd /.mkdir epicscd /epics/wget https://epics.anl.gov/download/base/base-3.16.2.tar.gz
#解壓并重命名為 basetar vxfz base-3.16.2.tar.gzmv base-3.16.2 base
#配置系統環境變量,vi模式下新建一個.bash_profil
cd ~vi .bash_profile
輸入內容:export EPICS_HOST_ARCH=$(/epics/base/startup/EpicsHostArch)
按下esc鍵盤,然后:wq!退出
#激活設置,執行source指令激活剛剛寫入的環境變量配置source .bash_profile
#查看設置,出現linux-arm則配置成功echo $EPICS_HOST_ARCH#返回:linux-arm
#進入base目錄下進行編譯(大約20min)cd /epics/basemake
出現下圖則為編譯成功
向bash_profile添加linux-arm的路徑
cd ~vi .bash_profile
輸入內容:export PATH=$PATH:/epics/base/bin/linux-arm
按下esc鍵盤,然后:wq!退出
#然后激活一下:source .bash_profile
cd /epics/base/bin/linux-arm softIoc#返回:epics>
出現下圖說明安裝成功
c、利用caget或者caput或者camonitor測試EPICS base環境是否正常
5、建立一個epics例子程序
# 導入環境
cd ~
source .bash_profile# 建立測試工程,在/epics/APP 目錄下
cd ~
cd /epics
mkdir APP
cd APP
# 創建工程
mkdir myApp1
cd myApp1
makeBaseApp.pl -t example myApp
makeBaseApp.pl -i -t example myApp# 編譯工程
make
?不出意外的話,成功如下圖所示
然后啟動epics例子程序
# 進入iocmyApp文件夾
cd iocBoot/iocmyApp
ls
# 啟動st.cmd
../../bin/linux-arm/my st.cmd
不出意外。成功的話是這樣的
?輸入? dbl 可以看到所有的管道
經過上述的操作,相信大家已經對epics有了一個大致的了解,下面我們將編寫aiRecord的驅動程序,包括dbd文件和C語言源代碼,然后編譯并啟動IOC,最后通過通道訪問查看運行結果,實現每秒生成0-999隨機數的功能,此教程來自博客:
EPICS aiRecord記錄的驅動程序開發實例_epics ioc 驅動開發-CSDN博客文章瀏覽閱讀1k次。本文詳細介紹了如何在EPICS(ExperimentalPhysicsandIndustrialControlSystem)環境中創建一個IOC(Input/OutputController),編寫aiRecord的驅動程序,包括dbd文件和C語言源代碼,然后編譯并啟動IOC,最后通過通道訪問查看運行結果,實現每秒生成0-999隨機數的功能。https://blog.csdn.net/yuyuyuliang00/article/details/1182283446、aiRecord的程序編寫(需要3.15版本以上的epics)
cd ~source .bash_profilecd /epics/APP
創建aiDriver文件夾
mkdir aiDriver
cd aiDriver
創建名為aiDriver的例子程序
makeBaseApp.pl -t ioc aiDriver
makeBaseApp.pl -i -t ioc aiDriver# 名字寫 aiDriver
查看生成例子程序內容
root@zynq:/epics/APP/aiDriver# ls -R
.:
aiDriverApp configure iocBoot Makefile./aiDriverApp:
Db Makefile src./aiDriverApp/Db:
Makefile./aiDriverApp/src:
aiDriverMain.cpp Makefile./configure:
CONFIG CONFIG_SITE Makefile RELEASE RULES RULES_DIRS RULES.ioc RULES_TOP./iocBoot:
iocaiDriver Makefile./iocBoot/iocaiDriver:
Makefile st.cmd
編寫驅動程序devAiDriver.c,在aiDriverApp/src目錄下 。注意,如果按照博主的代碼,在本環境下無法編譯。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
#include "epicsMath.h"
#include "recGbl.h"
#include "devSup.h"
#include "aiRecord.h"
#include "epicsExport.h"
#include "dbLink.h"/* Create the dset for devAiRandom */
static long init_record(void *precord);
static long get_ioint_info(int cmd, dbCommon *prec, IOSCANPVT *ppvt);
static long read_ai(aiRecord *prec);struct {long number;DEVSUPFUN report;DEVSUPFUN init;DEVSUPFUN init_record;DEVSUPFUN get_ioint_info;DEVSUPFUN read_ai;
} devAiDriver= {6,NULL,NULL,init_record,get_ioint_info,read_ai
};// 導出這個驅動程序,名稱為devAiDriver
epicsExportAddress(dset, devAiDriver);static long init_record(void *precord)
{aiRecord *prec = precord;srand((unsigned)time(NULL));prec->udf = FALSE;printf("init_record_ai called for %p\n", precord);return 0;
}static long readLocked(struct link *pinp, void *userPvt)
{aiRecord *prec = (aiRecord *)userPvt;if (!prec) {return S_db_badField; // 或其他適當的錯誤碼}// 產生一個0-999之間的隨機數prec->rval = rand() % 1000;if (dbLinkIsConstant(&prec->tsel) &&prec->tse == epicsTimeEventDeviceTime)dbGetTimeStamp(pinp, &prec->time);return 0;
}static long get_ioint_info(int cmd, dbCommon *prec, IOSCANPVT *ppvt) {printf("get_ioint_info called cmd=%d, prec=%p\n", cmd, prec);return 0;
}static long read_ai(aiRecord *prec)
{long status = dbLinkDoLocked(&prec->inp, readLocked, prec);if (status == S_db_noLSET)status = readLocked(&prec->inp, prec);printf("read_ai called, prec=%p\n", prec);return status;
}
在同級目錄下創建devAiDriver.dbd文件:(如果你看過第5步驟生成的myApp例子文件可以知道,每個c文件都會有一個dbd文件與之對應,并且都在src文件夾下)
# 與devAiDriver.c中的DSET的devAiDriver對應
# 起一個叫 Random Ai 的名字
device(ai,INST_IO,devAiDriver, "Random Ai")
?修改同一級目錄下的Makefile文件,添加以下兩行:(注意,一定要在對應位置添加)
aiDriver_DBD += devAiDriver.dbd
aiDriver_SRCS += devAiDriver.c
進入目錄aiDriver/aiDriverApp/Db中創建aiTest.db文件
record(ai, "$(TEST):AiRandom")# 起一個叫 $(TEST):AiRandom 的PV
{field(DESC, "Test Ai Driver")field(SCAN, "1 second") # 1 秒掃描一次field(DTYP, "Random Ai") # 指定設備驅動,與前文起的名字一致field(ASLO, "1.0")field(LINR, "NO CONVERSION")
}
相同路徑下的Makefile中添加以下一行:
DB += aiTest.db
?切換目錄并且編譯
cd ~cd /epics/APP/aiDriver# 將所有文件時間設置為當前時間
find . -type f -exec touch {} +make cleanmake
出現下圖則是編譯成功了
進入啟動目錄aiDriver/iocBoot/iocaiDriver,修改啟動腳本st.cmd
#!../../bin/linux-arm/aiDriver#- You may have to change aiDriver to something else
#- everywhere it appears in this file< envPathscd "${TOP}"## Register all support components
dbLoadDatabase "dbd/aiDriver.dbd"
aiDriver_registerRecordDeviceDriver pdbbase## 裝載記錄實例
dbLoadRecords("db/aiTest.db","TEST=Random")cd "${TOP}/iocBoot/${IOC}"
iocInit
啟動程序
cd /epics/APP/aiDriver/iocBoot/iocaiDriver
# debug模式下進行
gdb --args ../../bin/linux-arm/aiDriver st.cmd
# 輸入run即可執行,如果代碼有錯,會自動停止
正常情況下,再啟動一個putty,即可看到這些輸出?
#命令,Random:AiRandom這個名字是在db中生成的
camonitor Random:AiRandom