This commit is contained in:
Chinky 2024-01-23 18:07:06 +08:00
parent d29d9d4dac
commit 22420644c2
11 changed files with 123 additions and 84 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ install
/doc/html
tags
*.pyc
test/linux/eceeprom/sn.csv

1
test/linux/eceeprom/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.csv

View File

@ -8,8 +8,16 @@ set(LIB_SRC eceeprom.c)
add_library(eceeprom_lib SHARED ${LIB_SRC})
set_target_properties(eceeprom_lib PROPERTIES OUTPUT_NAME "eceeprom")
target_link_libraries(eceeprom_lib soem)
add_library(eceeprom_static STATIC ${LIB_SRC})
set_target_properties(eceeprom_static PROPERTIES OUTPUT_NAME "eceeprom")
target_link_libraries(eceeprom_static soem)
target_include_directories(eceeprom_static
PUBLIC .)
install(TARGETS eceeprom_lib LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
install(FILES eceeprom.h DESTINATION include)
install(FILES ec-eeprom.py test.sh DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES ec_eeprom.py sn.py test.sh DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
install(FILES database.py Verhoeff.py config.toml TJ30-1616DN-EEPROM.bin DESTINATION bin)

View File

@ -135,12 +135,12 @@ int main(int argc, char *argv[])
}
else if (strcmp(option, "-wsn") == 0)
{
uint32_t sn = strtoul(val, NULL, 10);
int32_t sn = strtol(val, NULL, 10);
rc = ecWriteSN(slave, sn);
}
else if (strcmp(option, "-wsnh") == 0)
{
uint32_t sn = strtoul(val, NULL, 16);
int32_t sn =(int32_t) strtoul(val, NULL, 16);
rc = ecWriteSN(slave, sn);
}
else

View File

@ -1,64 +1,19 @@
#!/root/venv/bin/python
import datetime
import Verhoeff
import sys
from ctypes import *
from database import *
from sn import *
ll = cdll.LoadLibrary
# ece = ll("../../../build/test/linux/eceeprom/libeceeprom.so")
ece = ll("../lib/libeceeprom.so")
# sn 的组成:
# [0 1] [2 3] [4 5] [6 7 8] [9]
# [设备ID] [ 年 ] [ 月 ] [顺序号] [校验码]
# sn 10位十进制数据
# 顺序号每月开始重置为 001
# 校验码算法 Verhoeff
def generate_sn(last_sn: int, prefix: int = None) -> int:
device_id = last_sn // 100000000
curr_device_id = device_id if prefix is None else prefix
today = datetime.datetime.today()
# today = datetime.datetime(2023,12,1,0,0,0)
curr_year = today.year % 100
curr_month = today.month
year = last_sn // 1000000 % 100
month = last_sn // 10000 % 100
sequence_num = last_sn // 10 % 1000
if year != curr_year or month != curr_month or device_id != curr_device_id:
sequence_num = 1
year = curr_year
month = curr_month
else:
sequence_num += 1
new_sn_without_check = (
curr_device_id * 10000000 + year * 100000 + month * 1000 + sequence_num
)
new_check = Verhoeff.checksum(str(new_sn_without_check))
return new_sn_without_check * 10 + new_check
# def write_eeprom_with_sn(slave: int, sn: int):
# ece.ecShowInfo(slave, False)
# rc = ece.ecEepromWriteSN(slave, sn)
# if rc > 0:
# print("SN %d (HEX: %8.8X) written successfully to slave %d" % (sn, sn, slave))
# ece.ecShowInfo(slave, False)
# elif rc < 0:
# print("Could not read slave EEPROM\n")
# else:
# print("SN not written\n")
# return rc
def get_new_sn(session, slave_id: int, product_name: str, prefix: int, is_force: bool):
def get_new_sn(
ece, session, slave_id: int, product_name: str, prefix: int, is_force: bool
):
if not is_force:
# check origin sn
origin_sn = ece.ecEepromGetSN(slave_id)
@ -90,11 +45,14 @@ def get_new_sn(session, slave_id: int, product_name: str, prefix: int, is_force:
def write_multi_eeprom(
count: int, session, product_name: str, eeprome_file: str, is_force: bool
):
product_code, prefix_str = get_product_info(session, product_name)
product_code_str, prefix_str = get_product_info(session, product_name)
prefix = None
if prefix_str is not None and prefix_str != "":
prefix = int(prefix_str)
else:
prefix = None
product_code = None
if product_code_str is not None and product_code_str != "":
product_code = int(product_code_str)
# 当从机数量大于1时,不写最后一个
if count == 1:
count = 2
@ -102,11 +60,11 @@ def write_multi_eeprom(
print(f"Write slave EEPROM #{i} :\n")
is_new_sn, new_sn = get_new_sn(session, i, product_name, prefix, is_force)
is_eeprom_initialized = False
is_eeprom_initialized = False
if not is_force:
e_product_code = ece.ecEepromGetProductCode(i)
# EEPROM 未初始化
if e_product_code != product_code:
if e_product_code == product_code:
is_eeprom_initialized = True
print(
f"Origin product code is {e_product_code}. Is initialized. Do NOT need update EEPROM"
@ -119,7 +77,7 @@ def write_multi_eeprom(
rc = 0
if is_eeprom_initialized:
if is_new_sn and new_sn != 0 and new_sn != 0xFFFFFFFF:
if is_new_sn and new_sn != 0 and new_sn != -1:
rc = ece.ecWriteSN(c_int(i), c_uint32(new_sn))
else:
print(f"i ={i}, eeprom_file:{eeprome_file},new_sn: {new_sn}")

View File

@ -360,7 +360,7 @@ uint32_t ecEepromGetProductCode(int slave)
}
uint32_t ecEepromGetSN(int slave)
int32_t ecEepromGetSN(int slave)
{
int ret;
ret = ecEepromToBuffer(slave, true);
@ -369,17 +369,17 @@ uint32_t ecEepromGetSN(int slave)
return 0;
}
uint16 *wbuf = (uint16 *)&ebuf[0];
return ((uint32_t) * (wbuf + 0x0F)) << 16 | *(wbuf + 0x0E);
return ((int32_t) * (wbuf + 0x0F)) << 16 | *(wbuf + 0x0E);
}
void ecUpdateSNBuff(uint32_t sn)
void ecUpdateSNBuff(int32_t sn)
{
uint16 *wbuf = (uint16 *)&ebuf[0];
*(wbuf + 0x0E) = (uint16_t)(sn & 0xffff);
*(wbuf + 0x0F) = (uint16_t)(sn >> 16);
*(wbuf + 0x0E) = (uint16_t)((uint32_t)sn & 0xffff);
*(wbuf + 0x0F) = (uint16_t)((uint32_t)sn >> 16);
}
int ecEepromWriteSN(int slave, uint32_t sn)
int ecEepromWriteSN(int slave, int32_t sn)
{
int ret;
ret = ecEepromToBuffer(slave, true);
@ -548,7 +548,7 @@ int ecWriteAlias(int slave, uint16_t alias)
return rc;
}
int ecWriteSN(int slave, uint32_t sn)
int ecWriteSN(int slave, int32_t sn)
{
printf("Write slave %d SN %u ...\n", slave, sn);
int rc = ecEepromWriteSN(slave, sn);

View File

@ -13,9 +13,9 @@ int ecBufferToIntelHex(const char *fname, int length);
int ecEepromRead(int slave, int start, int length);
int ecEepromWrite(int slave, int start, int length);
int ecEepromWriteAlias(int slave, uint16_t alias, uint16_t *crc);
void ecUpdateSNBuff(uint32_t sn);
int ecEepromWriteSN(int slave, uint32_t sn);
uint32_t ecEepromGetSN(int slave);
void ecUpdateSNBuff(int32_t sn);
int ecEepromWriteSN(int slave, int32_t sn);
int32_t ecEepromGetSN(int slave);
int ecGetSlaveCount(void);
int ecGetESize(void);
void ecShowInfo(int slave, bool isDetails);
@ -24,6 +24,6 @@ int ecEepromToBuffer(int slave, bool isFull);
int ecEepromToFile(int slave, const char *fname, bool isHex);
int ecFileToEeprom(int slave, const char *fname, bool isHex, uint32_t sn);
int ecWriteAlias(int slave, uint16_t alias);
int ecWriteSN(int slave, uint32_t sn);
int ecWriteSN(int slave, int32_t sn);
uint32_t ecEepromGetProductCode(int slave);
#endif /* __EC_EEPROM_H__ */

64
test/linux/eceeprom/sn.py Normal file
View File

@ -0,0 +1,64 @@
#!/bin/env python3
import datetime, sys
import Verhoeff
from database import *
import csv
# sn 的组成:
# [0 1] [2 3] [4 5] [6 7 8] [9]
# [设备ID] [ 年 ] [ 月 ] [顺序号] [校验码]
# sn 10位十进制数据
# 顺序号每月开始重置为 001
# 校验码算法 Verhoeff
def generate_sn(last_sn: int, prefix: int = None) -> int:
device_id = last_sn // 100000000
curr_device_id = device_id if prefix is None else prefix
today = datetime.datetime.today()
# today = datetime.datetime(2023,12,1,0,0,0)
curr_year = today.year % 100
curr_month = today.month
year = last_sn // 1000000 % 100
month = last_sn // 10000 % 100
sequence_num = last_sn // 10 % 1000
if year != curr_year or month != curr_month or device_id != curr_device_id:
sequence_num = 1
year = curr_year
month = curr_month
else:
sequence_num += 1
new_sn_without_check = (
curr_device_id * 10000000 + year * 100000 + month * 1000 + sequence_num
)
new_check = Verhoeff.checksum(str(new_sn_without_check))
return new_sn_without_check * 10 + new_check
if __name__ == "__main__":
if len(sys.argv) != 4:
print("python sn.py last_sn num csv_file")
else:
csv_file = sys.argv[3]
last_sn = int(sys.argv[1])
num = int(sys.argv[2])
print(f"last SN: {last_sn}, num: {num}")
sn_list = []
for i in range(1, num + 1):
sn = generate_sn(last_sn)
row = [i, sn]
sn_list.append(row)
last_sn = sn
print(sn_list)
with open(csv_file, "w", encoding="utf-8", newline="") as f:
csv_writer = csv.writer(f)
name = ["ID", "SN"]
csv_writer.writerow(name)
csv_writer.writerows(sn_list)
print(f"写入{csv_file}成功")
f.close()

View File

@ -2,5 +2,9 @@
dir=$(cd "$(dirname $0)";pwd)
${dir}/ec-eeprom.py
echo 请先断电,再通电
read -n 1 -s -r -p "按任意键继续..."
sleep 2
# ${dir}/ecslaveinfo enp3s0f1
${dir}/tj30_test enp3s0f1

View File

@ -1,5 +1,5 @@
set(SOURCES tj30_test.c)
add_executable(tj30_test ${SOURCES})
target_link_libraries(tj30_test soem)
target_link_libraries(tj30_test soem eceeprom_static)
install(TARGETS tj30_test DESTINATION bin)

View File

@ -24,6 +24,7 @@
#include <time.h>
#include <unistd.h>
#include "eceeprom.h"
#include "ethercat.h"
#include "osal.h"
@ -251,11 +252,10 @@ static void show_check(void)
ec_error.is_showed = true;
for (;;)
{
// 按 'q` 键退出
// 按任意键退出
int result = read(STDIN_FILENO, &ch, 1);
if (result == 1 && (ch == 'q' || ch == 'Q'))
if (result == 1 && (ch == ' ' || ch == 'q' || ch == 'x'))
{
printf("'Q' is pressed.\n");
break;
}
if (is_first)
@ -394,11 +394,11 @@ static void show_check(void)
}
else if (io_test[i].err_cnt[idx] > 999)
{
p += sprintf(p, SET_COLOR(B_YELLOW, "999+"));
p += sprintf(p, SET_COLOR(B_B_RED, "999+"));
}
else
{
p += sprintf(p, SET_COLOR(B_YELLOW, " %3lu"), io_test[i].err_cnt[idx]);
p += sprintf(p, SET_COLOR(B_B_RED, " %3lu"), io_test[i].err_cnt[idx]);
}
p += sprintf(p, "|");
}
@ -415,8 +415,8 @@ static void show_check(void)
printf("Processdata cycle %5d, cycletime %dus, Wck %3d, DCtime %12" PRId64
"ns, dt " CSI_START "K" /*擦除到行尾*/ "%6" PRId64 "ns\n",
dorun, cycletime, wkc, ec_DCtime, gl_delta);
printf("Test cycle %d, Step time %dms, Test step %3d, EC Error count %lu " SET_COLOR(
F_B_RED, "(Press 'q' to exit)\n"),
printf("Test cycle %d, Step time %dms, Test step %3d, EC Error count %lu."
" Press key SPACE or 'q' or 'x' to EXIT.\n",
test_cycle, step_time / 1000, test_step, ec_error.cnt);
fflush(stdout);
@ -454,12 +454,15 @@ void tj30_test(char *ifname)
ec_readstate();
for (cnt = 1; cnt <= ec_slavecount; cnt++)
{
int32_t sn = ecEepromGetSN(cnt);
logn(F_B_BLUE,
"Slave:%d Name:%s Output size:%3dbits Input size:%3dbits State:%2d delay:%3d DC:%2d\n",
cnt, ec_slave[cnt].name, ec_slave[cnt].Obits, ec_slave[cnt].Ibits, ec_slave[cnt].state,
(int)ec_slave[cnt].pdelay, ec_slave[cnt].hasdc);
logn(F_B_BLUE, " Out:%p,%4d In:%p,%4d\n", ec_slave[cnt].outputs,
ec_slave[cnt].Obytes, ec_slave[cnt].inputs, ec_slave[cnt].Ibytes);
"Slave:%d Name:%s SN:" CSI_START B_B_WHITE "%d" CSI_END CSI_START F_B_BLUE
" Output size:%3dbits Input size:%3dbits State:%2d delay:%3d\n",
cnt, ec_slave[cnt].name, sn, ec_slave[cnt].Obits, ec_slave[cnt].Ibits,
ec_slave[cnt].state, (int)ec_slave[cnt].pdelay);
logn(F_B_BLUE, "DC:%2d Out:%p,%4d In:%p,%4d\n", ec_slave[cnt].hasdc,
ec_slave[cnt].outputs, ec_slave[cnt].Obytes, ec_slave[cnt].inputs,
ec_slave[cnt].Ibytes);
// /* check for TJ30-1616DN */
// if (!digout && (ec_slave[cnt].eep_id == 85301616))
// {
@ -703,7 +706,7 @@ OSAL_THREAD_FUNC_RT ecatthread(void *ptr)
}
else if (dorun < 0)
{
break;
break;
}
dorun++;
wkc = ec_receive_processdata(EC_TIMEOUTRET);