Commit b55d19ee authored by ye's avatar ye

change dd.c , add some apps to dd/example , add docs

parent 8e1b4398
ROOTDIR=../..
DEPSDIR=${ROOTDIR}/deps
ifeq ($(RTE_TARGET),)
$(error "Please define RTE_TARGET environment variable")
endif
ifeq ($(UDPDK_PATH),)
UDPDK_PATH=${ROOTDIR}
endif
VPATH = #./
ROOTDIR = /home/ddaq/udpdk
DEPSDIR = /home/ddaq/udpdk/deps
RTE_TARGET = x86_64-native-linuxapp-gcc
UDPDK_PATH = /home/ddaq/udpdk
CC = gcc
CXX = g++
CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_REENTRANT -fPIC -O2 -DPERF_OPT -g -D_DEBUG #-D_THREAD_SAFE -W -g #_Wall
CFLAGS += -I./lib -I${ROOTDIR}/udpdk -I${ROOTDIR}/udpdk/list -I${DEPSDIR}/dpdk/${RTE_TARGET}/include
CXXFLAGS = -I./lib -fPIC #D_DEBUG
LDFLAGS = -L./lib -Wl,--rpath=./lib -L${UDPDK_PATH}/udpdk -Wl,--whole-archive,-ludpdk,--no-whole-archive -L${DEPSDIR}/dpdk/${RTE_TARGET}/lib -Wl,--whole-archive,-ldpdk,--no-whole-archive
LIBS = -lpthread -lm -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread -lnuma #-static
MYLIBNAME = dd
CONS = dd_cons
PROD = dpdk_recv
SEND = dpdk_send
MYLIB = lib$(MYLIBNAME).so
TARGETS = $(MYLIB) $(PROD) $(SEND) $(CONS)
CONSOBJS = dd_cons.o
PRODOBJS = dpdk_recv.o
SENDOBJS = dpdk_send.o
MYLIBOBJS = dd.o
OBJS = $(PRODOBJS) $(CONSOBJS) $(MYLIBOBJS) $(EXTS)
CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_REENTRANT -fPIC -O2 -DPERF_OPT -g -D_DEBUG
CFLAGS += -I./lib -I${ROOTDIR}/udpdk -I${ROOTDIR}/udpdk/list -I${DEPSDIR}/dpdk/${RTE_TARGET}/include
LDFLAGS = -L./lib -Wl,--rpath=./lib -L${UDPDK_PATH}/udpdk -Wl,--whole-archive,-ludpdk,--no-whole-archive \
-L${DEPSDIR}/dpdk/${RTE_TARGET}/lib -Wl,--whole-archive,-ldpdk,--no-whole-archive
LIBS = -lpthread -lm -lrt -ldl -lcrypto -lnuma
.PHONY:all
all: $(TARGETS)
# 库名和路径
MYLIB = libdd.so
LIB_PATH = lib/$(MYLIB)
$(PROD): $(PRODOBJS) $(EXTS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -l$(MYLIBNAME) $(LIBS) -o $@ #-lstdc++
.PHONY: all clean example
$(SEND): $(SENDOBJS) $(EXTS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -l$(MYLIBNAME) $(LIBS) -o $@ #-lstdc++
all: $(LIB_PATH)
$(CONS): $(CONSOBJS) $(EXTS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -l$(MYLIBNAME) $(LIBS) -o $@ #-lstdc++
# 构建共享库
$(LIB_PATH): dd.c
$(CC) $(CFLAGS) -shared -fPIC $< -o $@
mkdir -p lib
$(MYLIB): $(MYLIBOBJS)
$(CC) -shared $^ -o $@
cp $@ lib/
# 递归构建 example
example:
$(MAKE) -C example
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
.cpp.o:
$(CXX) $(CXXFLAGS) -c $< -o $@
.PHONY:clean
clean:
rm -f *.o $(OBJS) $(TARGETS) lib/$(MYLIB)
rm -rf lib/
$(MAKE) -C example clean
distclean: clean
rm -f *.o
\ No newline at end of file
ROOTDIR=../..
DEPSDIR=${ROOTDIR}/deps
ifeq ($(RTE_TARGET),)
$(error "Please define RTE_TARGET environment variable")
endif
ifeq ($(UDPDK_PATH),)
UDPDK_PATH=${ROOTDIR}
endif
VPATH = #./
CC = gcc
CXX = g++
CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_REENTRANT -fPIC -O2 -DPERF_OPT -g -D_DEBUG #-D_THREAD_SAFE -W -g #_Wall
CFLAGS += -I./lib -I${ROOTDIR}/udpdk -I${ROOTDIR}/udpdk/list -I${DEPSDIR}/dpdk/${RTE_TARGET}/include
CXXFLAGS = -I./lib -fPIC #D_DEBUG
LDFLAGS = -L./lib -Wl,--rpath=./lib -L${UDPDK_PATH}/udpdk -Wl,--whole-archive,-ludpdk,--no-whole-archive -L${DEPSDIR}/dpdk/${RTE_TARGET}/lib -Wl,--whole-archive,-ldpdk,--no-whole-archive
LIBS = -lpthread -lm -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread -lnuma #-static
MYLIBNAME = dd
CONS = dd_cons
PROD = dpdk_recv
SEND = dpdk_send
MYLIB = lib$(MYLIBNAME).so
TARGETS = $(MYLIB) $(PROD) $(SEND) $(CONS)
CONSOBJS = dd_cons.o
PRODOBJS = dpdk_recv.o
SENDOBJS = dpdk_send.o
MYLIBOBJS = dd.o
OBJS = $(PRODOBJS) $(CONSOBJS) $(MYLIBOBJS) $(EXTS)
.PHONY:all
all: $(TARGETS)
$(PROD): $(PRODOBJS) $(EXTS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -l$(MYLIBNAME) $(LIBS) -o $@ #-lstdc++
$(SEND): $(SENDOBJS) $(EXTS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -l$(MYLIBNAME) $(LIBS) -o $@ #-lstdc++
$(CONS): $(CONSOBJS) $(EXTS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ -l$(MYLIBNAME) $(LIBS) -o $@ #-lstdc++
$(MYLIB): $(MYLIBOBJS)
$(CC) -shared $^ -o $@
mkdir -p lib
cp $@ lib/
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
.cpp.o:
$(CXX) $(CXXFLAGS) -c $< -o $@
.PHONY:clean
clean:
rm -f *.o $(OBJS) $(TARGETS) lib/$(MYLIB)
......@@ -7,8 +7,8 @@ lcores_secondary=4
n_mem_channels=2
[port0]
mac_addr=24:42:53:30:28:27
ip_addr=172.31.100.2
mac_addr=6c:b3:11:21:c5:37
ip_addr=192.168.2.100
[port0_dst]
mac_addr=24:42:53:30:29:37
mac_addr=02:00:00:00:00:00
......@@ -42,22 +42,24 @@ typedef struct {
struct buf_ring *br;
ADC_SAMPLE *sample;
uint32_t sample_tail; //single producer
uint32_t last_sample_tail; // used to compare with sample_tail
uint32_t sample_blob_last;
uint32_t channel_num;
uint32_t blob_size; //number of sample group
uint32_t stream_mode;
uint32_t blob_id;
uint32_t blob_id_pop;
} DD_Context;
static DD_Context g_ctx[JOB_NUM_MAX];
typedef struct {
uint32_t data_blob_sample_cnt;
uint32_t blob_size;
uint16_t blob_id;
uint16_t slice_id; //one UDP is a slice
uint32_t sample_rate;
uint8_t sample_group_count; //number of sample group(a group consists of all channels' sample)
uint8_t channels_enabled;
uint16_t slice_size;
uint8_t channel_enable;
uint8_t downsampling;
uint8_t job_id;
uint8_t tmp[3]; // 保留字段
} DD_PayloadHeader;
//utility functions
......@@ -99,13 +101,17 @@ int32_t dd_init(uint32_t mode, uint32_t ring_size, uint32_t job_id)
}
mem = (void*)mmap(0, size + sizeof(SHM_HEADER), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if(mem == MAP_FAILED) {
printf("mmap failed!\n");
exit(0);
}
if (mem == MAP_FAILED) {
printf("mmap failed!\n");
close(shm_fd);
return -1;
}
g_ctx[job_id].pHeader = (SHM_HEADER *)mem;
g_ctx[job_id].br = &(g_ctx[job_id].pHeader->br);
g_ctx[job_id].blob_id = 0;
g_ctx[job_id].blob_id_pop = 0;
g_ctx[job_id].last_sample_tail = -1;
if(mode == MODE_PRODUCER) {
g_ctx[job_id].pHeader->magic = DD_SHM_MAGIC;
memset(&(g_ctx[job_id].pHeader->br), 0, sizeof(struct buf_ring));
......@@ -152,18 +158,40 @@ int32_t dd_status(uint32_t job_id)
return 0;
}
// int32_t dd_get_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id)
// {
// int64_t ret;
// while(num_group--) {
// ret = (int64_t)buf_ring_dequeue_mc(g_ctx[job_id].br);
// if(ret != -1) {
// memcpy(pSample, &g_ctx[job_id].sample[ret * g_ctx[job_id].channel_num], sizeof(ADC_SAMPLE) * g_ctx[job_id].channel_num);
// }
// else return -1;
// }
// return (int32_t)ret;
// }
// added by ye
int32_t dd_get_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id)
{
int64_t ret;
while(num_group--) {
ret = (int64_t)buf_ring_dequeue_mc(g_ctx[job_id].br);
if(ret != -1) {
memcpy(pSample, &g_ctx[job_id].sample[ret * g_ctx[job_id].channel_num], sizeof(ADC_SAMPLE) * g_ctx[job_id].channel_num);
}
else return -1;
ADC_SAMPLE *current = pSample;
while (num_group--) {
ret = (int64_t)buf_ring_dequeue_mc(g_ctx[job_id].br);
if (ret == -1) {
return -1;
}
memcpy(current,
&g_ctx[job_id].sample[ret * g_ctx[job_id].channel_num],
sizeof(ADC_SAMPLE) * g_ctx[job_id].channel_num);
current += g_ctx[job_id].channel_num;
}
return (int32_t)ret;
return 0;
}
int32_t dd_put_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id)
......@@ -182,7 +210,7 @@ int32_t dd_put_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id)
return 0;
}
int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id)
int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id)
{
int64_t ret;
uint32_t prod_tail, sample_tail, sample_start, count;
......@@ -194,6 +222,13 @@ int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id)
count = g_ctx[job_id].blob_size;
// get blob_id by comparing sample_tail with last_sample_tail
if(sample_tail!=g_ctx[job_id].last_sample_tail){
g_ctx[job_id].blob_id++;
}
g_ctx[job_id].last_sample_tail=sample_tail;
*blob_id=g_ctx[job_id].blob_id;
while(count--) {
memcpy(pSample, &g_ctx[job_id].sample[sample_start * g_ctx[job_id].channel_num], sizeof(ADC_SAMPLE) * g_ctx[job_id].channel_num);
sample_start = (sample_start + 1) & g_ctx[job_id].br->br_prod_mask;
......@@ -203,6 +238,65 @@ int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id)
return 0;
}
int32_t dd_get_blob_pop(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id)
{
int64_t ret;
ADC_SAMPLE *current = pSample;
uint32_t count = g_ctx[job_id].blob_size;
while (count--) {
ret = (int64_t)buf_ring_dequeue_mc(g_ctx[job_id].br);
if (ret == -1) {
return -1;
}
memcpy(current,
&g_ctx[job_id].sample[ret * g_ctx[job_id].channel_num],
sizeof(ADC_SAMPLE) * g_ctx[job_id].channel_num);
current += g_ctx[job_id].channel_num;
}
g_ctx[job_id].blob_id_pop++;
*blob_id=g_ctx[job_id].blob_id_pop;
return 0;
}
int32_t dd_get_blob_sync(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id)
{
struct buf_ring *br = g_ctx[job_id].br;
uint32_t blob_size = g_ctx[job_id].blob_size;
uint32_t channel_num = g_ctx[job_id].channel_num;
ADC_SAMPLE *sample = g_ctx[job_id].sample;
// 1. 获取当前 ring 中已写入的 sample 总数
uint32_t total_written = buf_ring_count(br);
// 2. 计算完整 blob 数量
if (total_written < blob_size) {
return -1; // 没有完整 blob
}
uint32_t complete_blobs = total_written / blob_size;
*blob_id = complete_blobs;
// 3. 最后一个完整 blob 在 ring 中的起始位置
uint32_t blob_start_ring_idx = (br->br_cons_head + (complete_blobs - 1) * blob_size) & br->br_prod_mask;
// 4. 逐个读取 blob_size 个 sample indices,并拷贝数据
for (uint32_t i = 0; i < blob_size; i++) {
uint32_t ring_idx = (blob_start_ring_idx + i) & br->br_prod_mask;
uint32_t sample_idx = (uint32_t)(uintptr_t)br->br_ring[ring_idx]; // 假设存的是 index
memcpy(pSample,
&sample[sample_idx * channel_num],
sizeof(ADC_SAMPLE) * channel_num);
pSample += channel_num;
}
return 0;
}
uint32_t dd_count(uint32_t job_id)
{
return buf_ring_count(g_ctx[job_id].br);
......
......@@ -21,7 +21,9 @@ int32_t dd_status(uint32_t job_id);
int32_t dd_config(uint32_t channel_num, uint32_t blob_size, uint32_t stream_mode, uint32_t job_id);
int32_t dd_get_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id);
int32_t dd_put_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id);
int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id); //risky
int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id); //risky
int32_t dd_get_blob_pop(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id);
int32_t dd_get_blob_sync(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id);
//int32_t dd_release_blob(ADC_SAMPLE *pSample);
int32_t dd_get_blob_copy(ADC_SAMPLE *buf, uint32_t offset, uint32_t count);
uint32_t dd_count(uint32_t job_id);
......
# udpdk_api
这是udpdk dd 项目的api文档
## api文档
api总览
```dotnetcli
int32_t dd_init(uint32_t mode, uint32_t ring_size, uint32_t job_id);
int32_t dd_status(uint32_t job_id);
int32_t dd_config(uint32_t channel_num, uint32_t blob_size, uint32_t stream_mode, uint32_t job_id);
int32_t dd_get_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id);
int32_t dd_put_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id);
int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id); //risky
int32_t dd_get_blob_pop(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id);
int32_t dd_get_blob_sync(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id);
int32_t dd_get_blob_copy(ADC_SAMPLE *buf, uint32_t offset, uint32_t count);
uint32_t dd_count(uint32_t job_id);
uint32_t dd_close();
```
1. 初始化函数
```c
int32_t dd_init(uint32_t mode, uint32_t ring_size, uint32_t job_id);
```
参数:
`mode`目前有生产者,消费者两种模式,生产者指往buffer ring里面写数据,消费者指从buffer ring读数据
```c
enum {
MODE_PRODUCER = 0,
MODE_CONSUMER
};
```
`ring_size`默认填0即可,会使用默认值`DEFAULT_RING_SIZE`,即128KB
```c
#define DEFAULT_RING_SIZE (128*1024)
```
job_id则注意一致性,同一个采集任务的采集发送的job_id,生产者进程的job_id和消费者进程的job_id这三个要对应一致
2. 查询buffer ring状态
```c
int32_t dd_status(uint32_t job_id);
```
根据提供的job_id查询对应的buffer_ring的状态:使用,head,tail,丢弃
3. 配置buffer ring
```c
int32_t dd_config(uint32_t channel_num, uint32_t blob_size, uint32_t stream_mode, uint32_t job_id);
```
主要是按照16字节header里面的信息配置怎么读写buffer ring,注意这里生产者和消费者都需要配置,而且需要注意同一个采集任务的参数一致性
4. dd_put_slice
```c
int32_t dd_put_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id);
```
这个api是给生产者用的,消费者无需关注,就是往buffer ring里面写采集数据
pSample为要put的数据
num_group,我更愿意叫做slice sample num,就是一个slice有几个点
job_id见上
5. dd_get_slice
```c
int32_t dd_get_slice(ADC_SAMPLE *pSample, uint32_t num_group, uint32_t job_id)
```
就是dd_put_slice的消费者版本,往buffer ring里面读采集数据,一次读一个slice的数据,参数和dd_put_slice是一致的
6. dd_get_blob
```c
int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id)
```
我们想要给用户提供的获取数据的api
用户提供一个pSample的缓冲区(注意要够这个blob数据的大小),然后把最新的一个blob的数据填进去,这个函数的返回值是0
```c
int32_t dd_get_blob(ADC_SAMPLE *pSample, uint32_t job_id)
{
// 1. 获取队列中最后一个有效索引(最新写入的)
uint32_t prod_tail = (br->br_prod_tail - 1) & mask;
uint32_t sample_tail = (uint32_t)br->br_ring[prod_tail]; // 最新的 sample 索引
// 2. 计算 blob 起始位置:从 sample_tail 往前推 blob_size 个
uint32_t sample_start = (sample_tail - g_ctx[job_id].blob_size - 1) & mask;
// 3. 连续拷贝 blob_size 个 sample
uint32_t count = g_ctx[job_id].blob_size;
while(count--) {
memcpy(pSample, &sample[sample_start * channel_num], ...);
sample_start = (sample_start + 1) & mask; // 环形递增
pSample += channel_num;
}
return 0;
}
```
![point_move](./pointmove.png)
我们之前提到的Blob模式,Slice模式
其中Slice模式就是现在的dd_get_blob
7. dd_get_blob_pop
参数和dd_get_blob完全一致,就是返回的数据内容不同
```c
int32_t dd_get_blob_pop(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id)
```
队列的思路,就是从队列里pop一个blob的数据
![pop](./dd_get_blob_pop.png)
8. dd_get_blob_sync
参数和dd_get_blob完全一致,就是返回的数据内容不同
```c
int32_t dd_get_blob_pop(ADC_SAMPLE *pSample, uint32_t job_id, uint32_t *blob_id)
```
按 blob 对齐、非滑动、非覆盖的历史块读取,即只有当第 N 个完整的 blob(连续 blob_size 个 sample)写入后,才能读取它;否则只能读取上一个完整 blob(N-1)
对应图片中的Blob模式
......@@ -12,20 +12,21 @@
#include <udpdk_api.h>
#include "dd.h"
typedef struct {
uint32_t data_blob_sample_cnt;
uint32_t blob_size;
uint16_t blob_id;
uint16_t slice_id;
uint32_t sample_rate;
uint8_t sample_group_count;
uint8_t channels_enabled;
uint16_t slice_size;
uint8_t channel_enable;
uint8_t downsampling;
uint8_t job_id;
uint8_t tmp[3]; // 保留字段
} DD_PayloadHeader;
#define PORT_PING 10000
#define PORT_PONG 10001
#define IP_PONG "172.31.100.1"
#define PORT_PING 1234
#define PORT_PONG 8010
#define IP_PONG "192.168.2.100"
#define MAX_SAMPLES 1000
static volatile int app_alive = 1;
......@@ -88,22 +89,24 @@ static void dd_recv(void)
if (n > 0) {
DD_PayloadHeader *pHeader = (DD_PayloadHeader *)buf;
printf("=Received UDP packet: %d bytes...\n", n);
printf("data_blob_sample_cnt: %d\n", pHeader->data_blob_sample_cnt);
printf("blob_size: %d\n", pHeader->blob_size);
printf("blob_id: %d\n", pHeader->blob_id);
printf("slice_id: %d\n", pHeader->slice_id);
printf("sample_rate: %d\n", pHeader->sample_rate);
printf("sample_group_count: %d\n", pHeader->sample_group_count);
printf("channels_enabled: %d\n", pHeader->channels_enabled);
printf("slice_size: %d\n", pHeader->slice_size);
uint32_t blob_id = pHeader->data_blob_sample_cnt/pHeader->blob_size+1;
uint32_t slice_id = pHeader->data_blob_sample_cnt%pHeader->blob_size/pHeader->slice_size+1;
printf("blob_id: %d\n", blob_id);
printf("slice_id: %d\n", slice_id);
printf("channel_enable: %d\n", pHeader->channel_enable);
printf("downsampling: %d\n", pHeader->downsampling);
printf("job_id: %d\n", pHeader->job_id);
#if 1
if(dd_status(pHeader->job_id) < 0) { //first time
printf("=dd_init()\n");
dd_init(MODE_PRODUCER, 0, pHeader->job_id);
dd_config(pHeader->channels_enabled, pHeader->blob_size, 0, pHeader->job_id);
dd_config(pHeader->channel_enable, pHeader->blob_size, 0, pHeader->job_id);
}
dd_put_slice((ADC_SAMPLE *)(buf + 16), pHeader->sample_group_count, pHeader->job_id);
dd_put_slice((ADC_SAMPLE *)(buf + 16), pHeader->slice_size, pHeader->job_id);
#endif
}
}
......@@ -152,6 +155,7 @@ int main(int argc, char *argv[])
// Initialize UDPDK
retval = udpdk_init(argc, argv);
if (retval < 0) {
printf("udpdk init failed\n");
goto _end;
return -1;
}
......
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0008 1008 2008 3008 4008 5008 6008 7008
8008 9008 a008 b008 c008 d008 e008 f008
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
0009 1009 2009 3009 4009 5009 6009 7009
8009 9009 a009 b009 c009 d009 e009 f009
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000a 100a 200a 300a 400a 500a 600a 700a
800a 900a a00a b00a c00a d00a e00a f00a
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000b 100b 200b 300b 400b 500b 600b 700b
800b 900b a00b b00b c00b d00b e00b f00b
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000c 100c 200c 300c 400c 500c 600c 700c
800c 900c a00c b00c c00c d00c e00c f00c
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000d 100d 200d 300d 400d 500d 600d 700d
800d 900d a00d b00d c00d d00d e00d f00d
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000e 100e 200e 300e 400e 500e 600e 700e
800e 900e a00e b00e c00e d00e e00e f00e
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
000f 100f 200f 300f 400f 500f 600f 700f
800f 900f a00f b00f c00f d00f e00f f00f
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0010 1010 2010 3010 4010 5010 6010 7010
8010 9010 a010 b010 c010 d010 e010 f010
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
0011 1011 2011 3011 4011 5011 6011 7011
8011 9011 a011 b011 c011 d011 e011 f011
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001d 101d 201d 301d 401d 501d 601d 701d
801d 901d a01d b01d c01d d01d e01d f01d
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001e 101e 201e 301e 401e 501e 601e 701e
801e 901e a01e b01e c01e d01e e01e f01e
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
001f 101f 201f 301f 401f 501f 601f 701f
801f 901f a01f b01f c01f d01f e01f f01f
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0020 1020 2020 3020 4020 5020 6020 7020
8020 9020 a020 b020 c020 d020 e020 f020
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0021 1021 2021 3021 4021 5021 6021 7021
8021 9021 a021 b021 c021 d021 e021 f021
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0022 1022 2022 3022 4022 5022 6022 7022
8022 9022 a022 b022 c022 d022 e022 f022
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0023 1023 2023 3023 4023 5023 6023 7023
8023 9023 a023 b023 c023 d023 e023 f023
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0024 1024 2024 3024 4024 5024 6024 7024
8024 9024 a024 b024 c024 d024 e024 f024
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0025 1025 2025 3025 4025 5025 6025 7025
8025 9025 a025 b025 c025 d025 e025 f025
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
0026 1026 2026 3026 4026 5026 6026 7026
8026 9026 a026 b026 c026 d026 e026 f026
# 回到上一级目录获取配置
ROOT_DIR := ..
ROOTDIR = /home/ddaq/udpdk
DEPSDIR = /home/ddaq/udpdk/deps
RTE_TARGET = x86_64-native-linuxapp-gcc
UDPDK_PATH = /home/ddaq/udpdk
CC = gcc
CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -D_REENTRANT -O2 -DPERF_OPT -g -D_DEBUG
CFLAGS += -I$(ROOT_DIR) -I$(ROOTDIR)/udpdk -I$(ROOTDIR)/udpdk/list -I$(DEPSDIR)/dpdk/$(RTE_TARGET)/include
LDFLAGS = -L$(ROOT_DIR)/lib -Wl,--rpath=$(ROOT_DIR)/lib \
-L$(UDPDK_PATH)/udpdk -Wl,--whole-archive,-ludpdk,--no-whole-archive \
-L$(DEPSDIR)/dpdk/$(RTE_TARGET)/lib -Wl,--whole-archive,-ldpdk,--no-whole-archive
LIBS = -lpthread -lm -lrt -ldl -lcrypto -lnuma
# 自动发现 example/ 下所有 .c 文件(排除非示例)
APP_C_FILES := $(wildcard *.c)
APPS := $(patsubst %.c, %, $(APP_C_FILES))
.PHONY: all clean
all: $(APPS)
# 每个应用依赖上层的 libdd.so
%: %.c
$(CC) $(CFLAGS) $(LDFLAGS) $< -ldd $(LIBS) -o $@
clean:
rm -f $(APPS)
\ No newline at end of file
# example文件夹说明
该目录下都是一些消费者应用程序(从buffer ring里面读数据),有源代码和可执行程序和配置文件
程序通常命名为`dd_example`格式
执行方式
```dotnetcli
sudo ./dd_exampleapp -c config.yml
```
把dd_example替换为你想要执行的程序名
建议阅读源码并执行`dd_dumpblob`以熟悉
\ No newline at end of file
# Configuration for dd_cons
job_id: 5
channels_enabled: 192
blob_size: 10
# 支持注释
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/types.h>
#include <math.h>
#include <getopt.h>
#include <sched.h>
#include <pthread.h>
#include "dd.h"
#define THREAD_NUM 1
// 声明配置参数(将在配置文件中读取)
static uint32_t job_id = 0;
static uint32_t channels_enabled = 0;
static uint32_t blob_size = 0;
static int32_t exitRequested = 0;
static pthread_t threads[THREAD_NUM];
/*
* sigintHandler --
*
* SIGINT handler, so we can gracefully exit when the user hits ctrl-C.
*/
static void
sigintHandler(int signum)
{
switch(signum) {
case SIGINT:
exitRequested = 1;
break;
case SIGUSR1:
break;
}
}
static void print_usage(const char *prog)
{
printf("Usage: %s -c config.yml\n", prog);
puts(
" -c <file> configuration file (YAML format)\n"
" -v verbose mode (optional)\n"
);
exit(1);
}
// 工具函数:跳过空白字符
static char* skip_whitespace(char *p)
{
while (*p && isspace(*p)) p++;
return p;
}
// 工具函数:跳过行尾注释(# 开头)
static char* skip_comment(char *p)
{
char *cmt = strchr(p, '#');
if (cmt) *cmt = '\0'; // 截断注释
return p;
}
// 从文件中读取并解析 config.yml(极简YAML键值解析)
// 支持格式:key: value
int read_config_from_file(const char *filename)
{
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Error: Cannot open config file '%s': %s\n", filename, strerror(errno));
return -1;
}
char line[256];
int found_job_id = 0;
int found_channels = 0;
int found_blob = 0;
while (fgets(line, sizeof(line), fp)) {
char *p = skip_whitespace(line);
if (*p == '\0' || *p == '#') continue; // 空行或注释
// 去除行尾换行
p[strcspn(p, "\n")] = '\0';
skip_comment(p);
// 查找冒号
char *colon = strchr(p, ':');
if (!colon) continue;
*colon = '\0';
char *key = skip_whitespace(p);
char *value = skip_whitespace(colon + 1);
if (strcmp(key, "job_id") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 250) {
fprintf(stderr, "Invalid value for job_id: '%s'\n", value);
fclose(fp);
return -1;
}
job_id = (uint32_t)val;
found_job_id = 1;
}
else if (strcmp(key, "channels_enabled") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 192) { // 假设最多192通道
fprintf(stderr, "Invalid value for channels_enabled: '%s'\n", value);
fclose(fp);
return -1;
}
channels_enabled = (uint32_t)val;
found_channels = 1;
}
else if (strcmp(key, "blob_size") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1) {
fprintf(stderr, "Invalid value for blob_size: '%s'\n", value);
fclose(fp);
return -1;
}
blob_size = (uint32_t)val;
found_blob = 1;
}
// 忽略其他键
}
fclose(fp);
// 校验是否都读取到了
if (!found_job_id) {
fprintf(stderr, "Error: Missing 'job_id' in config file.\n");
return -1;
}
if (!found_channels) {
fprintf(stderr, "Error: Missing 'channels_enabled' in config file.\n");
return -1;
}
if (!found_blob) {
fprintf(stderr, "Error: Missing 'blob_size' in config file.\n");
return -1;
}
return 0;
}
static void parse_opts(int argc, char *argv[])
{
char *config_file = NULL;
int opt;
while ((opt = getopt(argc, argv, "c:v")) != -1) {
switch (opt) {
case 'c':
config_file = optarg;
break;
case 'v':
// 可选:启用详细输出(此处未实现日志细节)
printf("Verbose mode enabled.\n");
break;
default:
print_usage(argv[0]);
}
}
if (!config_file) {
fprintf(stderr, "Missing required option: -c <config.yml>\n");
print_usage(argv[0]);
}
if (read_config_from_file(config_file) != 0) {
fprintf(stderr, "Failed to parse configuration file.\n");
exit(EXIT_FAILURE);
}
}
static void *cons_proc(void *param)
{
int32_t index, i;
ADC_SAMPLE sample[192]; // 注意:这里数组大小固定为192,若 channels_enabled > 192 需动态分配
while(!exitRequested) {
index = dd_get_slice(sample, 1, job_id);
if(index != -1) {
printf("thread #%ld: get index: %d\n", (int64_t)param, index);
printf("\t first 4 channel sample data:\n");
for(i = 0; i < 4 && i < channels_enabled; i++) {
printf("\t channel #%3d: 0x%4x\n", i, sample[i]);
}
}
usleep(200000); // 200ms
}
return NULL;
}
int main(int argc, char **argv) {
int ret, i;
parse_opts(argc, argv);
signal(SIGINT, sigintHandler);
printf("dd_cons\n");
ret = dd_init(MODE_CONSUMER, 0, job_id);
printf("dd_init(): %d\n", ret);
dd_config(channels_enabled, blob_size, 0, job_id);
dd_status(job_id);
// 创建线程消费数据
for(i = 0; i < THREAD_NUM; i++) {
ret = pthread_create(&threads[i], NULL, cons_proc, (void*)(uint64_t)i);
if(ret != 0) {
printf("Create thread #%d failed!\n", i);
return -1;
}
}
// 等待所有线程结束
for(i = 0; i < THREAD_NUM; i++) {
if (pthread_join(threads[i], NULL) == 0) {
printf("Thread #%d finished\n", i);
}
}
return 0;
}
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/types.h>
#include <math.h>
#include <getopt.h>
#include <sched.h>
#include <pthread.h>
#include "dd.h"
#define THREAD_NUM 1
// 声明配置参数
static uint32_t job_id = 0;
static uint32_t channels_enabled = 0;
static uint32_t blob_size = 0;
static int32_t exitRequested = 0;
static pthread_t threads[THREAD_NUM];
static void sigintHandler(int signum)
{
switch(signum) {
case SIGINT:
exitRequested = 1;
break;
case SIGUSR1:
break;
}
}
static void print_usage(const char *prog)
{
printf("Usage: %s -c config.yml\n", prog);
puts(
" -c <file> configuration file (YAML format)\n"
" -v verbose mode (optional)\n"
);
exit(1);
}
// 工具函数:跳过空白字符
static char* skip_whitespace(char *p)
{
while (*p && isspace(*p)) p++;
return p;
}
// 工具函数:跳过行尾注释(# 开头)
static char* skip_comment(char *p)
{
char *cmt = strchr(p, '#');
if (cmt) *cmt = '\0';
return p;
}
int read_config_from_file(const char *filename)
{
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Error: Cannot open config file '%s': %s\n", filename, strerror(errno));
return -1;
}
char line[256];
int found_job_id = 0;
int found_channels = 0;
int found_blob = 0;
while (fgets(line, sizeof(line), fp)) {
char *p = skip_whitespace(line);
if (*p == '\0' || *p == '#') continue;
p[strcspn(p, "\n")] = '\0';
skip_comment(p);
char *colon = strchr(p, ':');
if (!colon) continue;
*colon = '\0';
char *key = skip_whitespace(p);
char *value = skip_whitespace(colon + 1);
if (strcmp(key, "job_id") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 250) {
fprintf(stderr, "Invalid value for job_id: '%s'\n", value);
fclose(fp);
return -1;
}
job_id = (uint32_t)val;
found_job_id = 1;
}
else if (strcmp(key, "channels_enabled") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 192) {
fprintf(stderr, "Invalid value for channels_enabled: '%s'\n", value);
fclose(fp);
return -1;
}
channels_enabled = (uint32_t)val;
found_channels = 1;
}
else if (strcmp(key, "blob_size") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1) {
fprintf(stderr, "Invalid value for blob_size: '%s'\n", value);
fclose(fp);
return -1;
}
blob_size = (uint32_t)val;
found_blob = 1;
}
}
fclose(fp);
if (!found_job_id || !found_channels || !found_blob) {
fprintf(stderr, "Error: Missing required config keys.\n");
return -1;
}
return 0;
}
static void parse_opts(int argc, char *argv[])
{
char *config_file = NULL;
int opt;
while ((opt = getopt(argc, argv, "c:v")) != -1) {
switch (opt) {
case 'c':
config_file = optarg;
break;
case 'v':
printf("Verbose mode enabled.\n");
break;
default:
print_usage(argv[0]);
}
}
if (!config_file) {
fprintf(stderr, "Missing required option: -c <config.yml>\n");
print_usage(argv[0]);
}
if (read_config_from_file(config_file) != 0) {
fprintf(stderr, "Failed to parse configuration file.\n");
exit(EXIT_FAILURE);
}
}
// 获取当前时间字符串,用于文件名
static void get_timestamp_str(char *buf, size_t len)
{
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(buf, len, "%Y%m%d_%H%M%S", tm_info);
}
static void *cons_proc(void *param)
{
// 动态分配足够大的 buffer 存储整个 blob
ADC_SAMPLE *sample_buffer = malloc(blob_size * channels_enabled * sizeof(ADC_SAMPLE));
if (!sample_buffer) {
fprintf(stderr, "Failed to allocate sample buffer\n");
exitRequested = 1;
return NULL;
}
char filename[256];
get_timestamp_str(filename, sizeof(filename) - 20);
snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), "_blob.txt");
FILE *fp = NULL;
int written = 0;
uint32_t blob_id = 0;
while (!exitRequested) {
// 尝试获取一个完整的 blob
int32_t ret = dd_get_blob(sample_buffer, job_id, &blob_id);
if (ret == 0) {
if (!written) {
fp = fopen(filename, "w");
if (!fp) {
perror("fopen");
free(sample_buffer);
exitRequested = 1;
return NULL;
}
// 所有 sample 数据平铺,每行 8 个十六进制值(无 0x)
uint32_t total_values = blob_size * channels_enabled;
printf("Total samples:%d,blod id:%d\n",total_values,blob_id);
for (uint32_t i = 0; i < total_values; i++) {
if (i > 0 && i % 8 == 0) {
fprintf(fp, "\n");
}
fprintf(fp, "%04x ", sample_buffer[i]);
if(i<8){
printf("%04x ",sample_buffer[i]);
}
}
fprintf(fp, "\n");
fclose(fp);
printf("Blob data written to: %s\n", filename);
written = 1;
exitRequested = 1;
}
} else {
// blob 尚未准备好,稍等
usleep(100000); // 100ms
}
}
free(sample_buffer);
return NULL;
}
int main(int argc, char **argv) {
parse_opts(argc, argv);
signal(SIGINT, sigintHandler);
printf("dd_dumpblob: waiting for shm (job_id=%u) to be created by producer...\n", job_id);
int ret;
// 轮询初始化,直到成功或用户中断
while (!exitRequested) {
ret = dd_init(MODE_CONSUMER, 0, job_id);
if (ret == 0) {
break; // 初始化成功
}
printf("shm not ready (file missing or invalid). Retrying in 1 second... (Press Ctrl+C to quit)\n");
sleep(1);
}
if (exitRequested) {
printf("\nInterrupted by user. Exiting.\n");
return 0;
}
// 初始化成功,继续配置
printf("dd_init(): success\n");
dd_config(channels_enabled, blob_size, 0, job_id);
dd_status(job_id);
// 创建消费线程
ret = pthread_create(&threads[0], NULL, cons_proc, NULL);
if (ret != 0) {
fprintf(stderr, "Failed to create thread\n");
return -1;
}
pthread_join(threads[0], NULL);
printf("Dump completed.\n");
return 0;
}
\ No newline at end of file
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/types.h>
#include <math.h>
#include <getopt.h>
#include <sched.h>
#include <pthread.h>
#include "dd.h"
#define THREAD_NUM 1
// 声明配置参数
static uint32_t job_id = 0;
static uint32_t channels_enabled = 0;
static uint32_t blob_size = 0;
static int32_t exitRequested = 0;
static pthread_t threads[THREAD_NUM];
static void sigintHandler(int signum)
{
switch(signum) {
case SIGINT:
exitRequested = 1;
break;
case SIGUSR1:
break;
}
}
static void print_usage(const char *prog)
{
printf("Usage: %s -c config.yml\n", prog);
puts(
" -c <file> configuration file (YAML format)\n"
" -v verbose mode (optional)\n"
);
exit(1);
}
// 工具函数:跳过空白字符
static char* skip_whitespace(char *p)
{
while (*p && isspace(*p)) p++;
return p;
}
// 工具函数:跳过行尾注释(# 开头)
static char* skip_comment(char *p)
{
char *cmt = strchr(p, '#');
if (cmt) *cmt = '\0';
return p;
}
int read_config_from_file(const char *filename)
{
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Error: Cannot open config file '%s': %s\n", filename, strerror(errno));
return -1;
}
char line[256];
int found_job_id = 0;
int found_channels = 0;
int found_blob = 0;
while (fgets(line, sizeof(line), fp)) {
char *p = skip_whitespace(line);
if (*p == '\0' || *p == '#') continue;
p[strcspn(p, "\n")] = '\0';
skip_comment(p);
char *colon = strchr(p, ':');
if (!colon) continue;
*colon = '\0';
char *key = skip_whitespace(p);
char *value = skip_whitespace(colon + 1);
if (strcmp(key, "job_id") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 250) {
fprintf(stderr, "Invalid value for job_id: '%s'\n", value);
fclose(fp);
return -1;
}
job_id = (uint32_t)val;
found_job_id = 1;
}
else if (strcmp(key, "channels_enabled") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 192) {
fprintf(stderr, "Invalid value for channels_enabled: '%s'\n", value);
fclose(fp);
return -1;
}
channels_enabled = (uint32_t)val;
found_channels = 1;
}
else if (strcmp(key, "blob_size") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1) {
fprintf(stderr, "Invalid value for blob_size: '%s'\n", value);
fclose(fp);
return -1;
}
blob_size = (uint32_t)val;
found_blob = 1;
}
}
fclose(fp);
if (!found_job_id || !found_channels || !found_blob) {
fprintf(stderr, "Error: Missing required config keys.\n");
return -1;
}
return 0;
}
static void parse_opts(int argc, char *argv[])
{
char *config_file = NULL;
int opt;
while ((opt = getopt(argc, argv, "c:v")) != -1) {
switch (opt) {
case 'c':
config_file = optarg;
break;
case 'v':
printf("Verbose mode enabled.\n");
break;
default:
print_usage(argv[0]);
}
}
if (!config_file) {
fprintf(stderr, "Missing required option: -c <config.yml>\n");
print_usage(argv[0]);
}
if (read_config_from_file(config_file) != 0) {
fprintf(stderr, "Failed to parse configuration file.\n");
exit(EXIT_FAILURE);
}
}
// 获取当前时间字符串,用于文件名
static void get_timestamp_str(char *buf, size_t len)
{
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(buf, len, "%Y%m%d_%H%M%S", tm_info);
}
static void *cons_proc(void *param)
{
// 动态分配足够大的 buffer 存储整个 blob
ADC_SAMPLE *sample_buffer = malloc(blob_size * channels_enabled * sizeof(ADC_SAMPLE));
if (!sample_buffer) {
fprintf(stderr, "Failed to allocate sample buffer\n");
exitRequested = 1;
return NULL;
}
char filename[256];
get_timestamp_str(filename, sizeof(filename) - 20);
snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), "_blob.txt");
FILE *fp = NULL;
int written = 0;
uint32_t blob_id = 0;
while (!exitRequested) {
// 尝试获取一个完整的 blob
int32_t ret = dd_get_blob_pop(sample_buffer, job_id, &blob_id);
if (ret == 0) {
if (!written) {
fp = fopen(filename, "w");
if (!fp) {
perror("fopen");
free(sample_buffer);
exitRequested = 1;
return NULL;
}
// 所有 sample 数据平铺,每行 8 个十六进制值(无 0x)
uint32_t total_values = blob_size * channels_enabled;
printf("Total samples:%d,blod id:%d\n",total_values,blob_id);
for (uint32_t i = 0; i < total_values; i++) {
if (i > 0 && i % 8 == 0) {
fprintf(fp, "\n");
}
fprintf(fp, "%04x ", sample_buffer[i]);
if(i<8){
printf("%04x ",sample_buffer[i]);
}
}
fprintf(fp, "\n");
fclose(fp);
printf("Blob data written to: %s\n", filename);
written = 1;
exitRequested = 1;
}
} else {
// blob 尚未准备好,稍等
usleep(100000); // 100ms
}
}
free(sample_buffer);
return NULL;
}
int main(int argc, char **argv) {
parse_opts(argc, argv);
signal(SIGINT, sigintHandler);
printf("dd_dumpblob: waiting for shm (job_id=%u) to be created by producer...\n", job_id);
int ret;
// 轮询初始化,直到成功或用户中断
while (!exitRequested) {
ret = dd_init(MODE_CONSUMER, 0, job_id);
if (ret == 0) {
break; // 初始化成功
}
printf("shm not ready (file missing or invalid). Retrying in 1 second... (Press Ctrl+C to quit)\n");
sleep(1);
}
if (exitRequested) {
printf("\nInterrupted by user. Exiting.\n");
return 0;
}
// 初始化成功,继续配置
printf("dd_init(): success\n");
dd_config(channels_enabled, blob_size, 0, job_id);
dd_status(job_id);
// 创建消费线程
ret = pthread_create(&threads[0], NULL, cons_proc, NULL);
if (ret != 0) {
fprintf(stderr, "Failed to create thread\n");
return -1;
}
pthread_join(threads[0], NULL);
printf("Dump completed.\n");
return 0;
}
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/types.h>
#include <math.h>
#include <getopt.h>
#include <sched.h>
#include <pthread.h>
#include "dd.h"
#define THREAD_NUM 1
// 声明配置参数
static uint32_t job_id = 0;
static uint32_t channels_enabled = 0;
static uint32_t blob_size = 0;
static int32_t exitRequested = 0;
static pthread_t threads[THREAD_NUM];
static void sigintHandler(int signum)
{
switch(signum) {
case SIGINT:
exitRequested = 1;
break;
case SIGUSR1:
break;
}
}
static void print_usage(const char *prog)
{
printf("Usage: %s -c config.yml\n", prog);
puts(
" -c <file> configuration file (YAML format)\n"
" -v verbose mode (optional)\n"
);
exit(1);
}
// 工具函数:跳过空白字符
static char* skip_whitespace(char *p)
{
while (*p && isspace(*p)) p++;
return p;
}
// 工具函数:跳过行尾注释(# 开头)
static char* skip_comment(char *p)
{
char *cmt = strchr(p, '#');
if (cmt) *cmt = '\0';
return p;
}
int read_config_from_file(const char *filename)
{
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Error: Cannot open config file '%s': %s\n", filename, strerror(errno));
return -1;
}
char line[256];
int found_job_id = 0;
int found_channels = 0;
int found_blob = 0;
while (fgets(line, sizeof(line), fp)) {
char *p = skip_whitespace(line);
if (*p == '\0' || *p == '#') continue;
p[strcspn(p, "\n")] = '\0';
skip_comment(p);
char *colon = strchr(p, ':');
if (!colon) continue;
*colon = '\0';
char *key = skip_whitespace(p);
char *value = skip_whitespace(colon + 1);
if (strcmp(key, "job_id") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 250) {
fprintf(stderr, "Invalid value for job_id: '%s'\n", value);
fclose(fp);
return -1;
}
job_id = (uint32_t)val;
found_job_id = 1;
}
else if (strcmp(key, "channels_enabled") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 192) {
fprintf(stderr, "Invalid value for channels_enabled: '%s'\n", value);
fclose(fp);
return -1;
}
channels_enabled = (uint32_t)val;
found_channels = 1;
}
else if (strcmp(key, "blob_size") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1) {
fprintf(stderr, "Invalid value for blob_size: '%s'\n", value);
fclose(fp);
return -1;
}
blob_size = (uint32_t)val;
found_blob = 1;
}
}
fclose(fp);
if (!found_job_id || !found_channels || !found_blob) {
fprintf(stderr, "Error: Missing required config keys.\n");
return -1;
}
return 0;
}
static void parse_opts(int argc, char *argv[])
{
char *config_file = NULL;
int opt;
while ((opt = getopt(argc, argv, "c:v")) != -1) {
switch (opt) {
case 'c':
config_file = optarg;
break;
case 'v':
printf("Verbose mode enabled.\n");
break;
default:
print_usage(argv[0]);
}
}
if (!config_file) {
fprintf(stderr, "Missing required option: -c <config.yml>\n");
print_usage(argv[0]);
}
if (read_config_from_file(config_file) != 0) {
fprintf(stderr, "Failed to parse configuration file.\n");
exit(EXIT_FAILURE);
}
}
// 获取当前时间字符串,用于文件名
static void get_timestamp_str(char *buf, size_t len)
{
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(buf, len, "%Y%m%d_%H%M%S", tm_info);
}
static void *cons_proc(void *param)
{
// 动态分配足够大的 buffer 存储整个 blob
ADC_SAMPLE *sample_buffer = malloc(blob_size * channels_enabled * sizeof(ADC_SAMPLE));
if (!sample_buffer) {
fprintf(stderr, "Failed to allocate sample buffer\n");
exitRequested = 1;
return NULL;
}
char filename[256];
get_timestamp_str(filename, sizeof(filename) - 20);
snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), "_blob.txt");
FILE *fp = NULL;
int written = 0;
uint32_t blob_id = 0;
while (!exitRequested) {
// 尝试获取一个完整的 blob
int32_t ret = dd_get_blob_sync(sample_buffer, job_id, &blob_id);
if (ret == 0) {
if (!written) {
fp = fopen(filename, "w");
if (!fp) {
perror("fopen");
free(sample_buffer);
exitRequested = 1;
return NULL;
}
// 所有 sample 数据平铺,每行 8 个十六进制值(无 0x)
uint32_t total_values = blob_size * channels_enabled;
printf("Total samples:%d,blod id:%d\n",total_values,blob_id);
for (uint32_t i = 0; i < total_values; i++) {
if (i > 0 && i % 8 == 0) {
fprintf(fp, "\n");
}
fprintf(fp, "%04x ", sample_buffer[i]);
if(i<8){
printf("%04x ",sample_buffer[i]);
}
}
fprintf(fp, "\n");
fclose(fp);
printf("Blob data written to: %s\n", filename);
written = 1;
exitRequested = 1;
}
} else {
// blob 尚未准备好,稍等
usleep(100000); // 100ms
}
}
free(sample_buffer);
return NULL;
}
int main(int argc, char **argv) {
parse_opts(argc, argv);
signal(SIGINT, sigintHandler);
printf("dd_dumpblob: waiting for shm (job_id=%u) to be created by producer...\n", job_id);
int ret;
// 轮询初始化,直到成功或用户中断
while (!exitRequested) {
ret = dd_init(MODE_CONSUMER, 0, job_id);
if (ret == 0) {
break; // 初始化成功
}
printf("shm not ready (file missing or invalid). Retrying in 1 second... (Press Ctrl+C to quit)\n");
sleep(1);
}
if (exitRequested) {
printf("\nInterrupted by user. Exiting.\n");
return 0;
}
// 初始化成功,继续配置
printf("dd_init(): success\n");
dd_config(channels_enabled, blob_size, 0, job_id);
dd_status(job_id);
// 创建消费线程
ret = pthread_create(&threads[0], NULL, cons_proc, NULL);
if (ret != 0) {
fprintf(stderr, "Failed to create thread\n");
return -1;
}
pthread_join(threads[0], NULL);
printf("Dump completed.\n");
return 0;
}
#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/types.h>
#include <math.h>
#include <getopt.h>
#include <sched.h>
#include <pthread.h>
#include "dd.h"
#define THREAD_NUM 1
// 声明配置参数
static uint32_t job_id = 0;
static uint32_t channels_enabled = 0;
static uint32_t blob_size = 0;
static int32_t exitRequested = 0;
static pthread_t threads[THREAD_NUM];
static void sigintHandler(int signum)
{
switch(signum) {
case SIGINT:
exitRequested = 1;
break;
case SIGUSR1:
break;
}
}
static void print_usage(const char *prog)
{
printf("Usage: %s -c config.yml\n", prog);
puts(
" -c <file> configuration file (YAML format)\n"
" -v verbose mode (optional)\n"
);
exit(1);
}
// 工具函数:跳过空白字符
static char* skip_whitespace(char *p)
{
while (*p && isspace(*p)) p++;
return p;
}
// 工具函数:跳过行尾注释(# 开头)
static char* skip_comment(char *p)
{
char *cmt = strchr(p, '#');
if (cmt) *cmt = '\0';
return p;
}
int read_config_from_file(const char *filename)
{
FILE *fp = fopen(filename, "r");
if (!fp) {
fprintf(stderr, "Error: Cannot open config file '%s': %s\n", filename, strerror(errno));
return -1;
}
char line[256];
int found_job_id = 0;
int found_channels = 0;
int found_blob = 0;
while (fgets(line, sizeof(line), fp)) {
char *p = skip_whitespace(line);
if (*p == '\0' || *p == '#') continue;
p[strcspn(p, "\n")] = '\0';
skip_comment(p);
char *colon = strchr(p, ':');
if (!colon) continue;
*colon = '\0';
char *key = skip_whitespace(p);
char *value = skip_whitespace(colon + 1);
if (strcmp(key, "job_id") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 250) {
fprintf(stderr, "Invalid value for job_id: '%s'\n", value);
fclose(fp);
return -1;
}
job_id = (uint32_t)val;
found_job_id = 1;
}
else if (strcmp(key, "channels_enabled") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1 || val > 192) {
fprintf(stderr, "Invalid value for channels_enabled: '%s'\n", value);
fclose(fp);
return -1;
}
channels_enabled = (uint32_t)val;
found_channels = 1;
}
else if (strcmp(key, "blob_size") == 0) {
char *end;
long val = strtol(value, &end, 10);
if (*end != '\0' || val < 1) {
fprintf(stderr, "Invalid value for blob_size: '%s'\n", value);
fclose(fp);
return -1;
}
blob_size = (uint32_t)val;
found_blob = 1;
}
}
fclose(fp);
if (!found_job_id || !found_channels || !found_blob) {
fprintf(stderr, "Error: Missing required config keys.\n");
return -1;
}
return 0;
}
static void parse_opts(int argc, char *argv[])
{
char *config_file = NULL;
int opt;
while ((opt = getopt(argc, argv, "c:v")) != -1) {
switch (opt) {
case 'c':
config_file = optarg;
break;
case 'v':
printf("Verbose mode enabled.\n");
break;
default:
print_usage(argv[0]);
}
}
if (!config_file) {
fprintf(stderr, "Missing required option: -c <config.yml>\n");
print_usage(argv[0]);
}
if (read_config_from_file(config_file) != 0) {
fprintf(stderr, "Failed to parse configuration file.\n");
exit(EXIT_FAILURE);
}
}
// 获取当前时间字符串,用于文件名
static void get_timestamp_str(char *buf, size_t len)
{
time_t now = time(NULL);
struct tm *tm_info = localtime(&now);
strftime(buf, len, "%Y%m%d_%H%M%S", tm_info);
}
const int SAMPLE_NUM=5;
static void *cons_proc(void *param)
{
// 动态分配足够大的 buffer 存储整个 blob
ADC_SAMPLE *sample_buffer = malloc(SAMPLE_NUM * channels_enabled * sizeof(ADC_SAMPLE));
if (!sample_buffer) {
fprintf(stderr, "Failed to allocate sample buffer\n");
exitRequested = 1;
return NULL;
}
char filename[256];
get_timestamp_str(filename, sizeof(filename) - 20);
snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), "_blob.txt");
FILE *fp = NULL;
int written = 0;
while (!exitRequested) {
int32_t ret = dd_get_slice(sample_buffer, SAMPLE_NUM, job_id);
if (ret != -1) {
if (!written) {
fp = fopen(filename, "w");
if (!fp) {
perror("fopen");
free(sample_buffer);
exitRequested = 1;
return NULL;
}
// 所有 sample 数据平铺,每行 8 个十六进制值(无 0x)
uint32_t total_values = SAMPLE_NUM * channels_enabled;
printf("Total samples:%d\n",total_values);
for (uint32_t i = 0; i < total_values; i++) {
if (i > 0 && i % 8 == 0) {
fprintf(fp, "\n");
}
fprintf(fp, "%04x ", sample_buffer[i]);
if(i<8){
printf("%04x ",sample_buffer[i]);
}
}
fprintf(fp, "\n");
fclose(fp);
printf("Blob data written to: %s\n", filename);
written = 1;
exitRequested = 1;
}
} else {
// blob 尚未准备好,稍等
usleep(100000); // 100ms
}
}
free(sample_buffer);
return NULL;
}
int main(int argc, char **argv) {
parse_opts(argc, argv);
signal(SIGINT, sigintHandler);
printf("dd_dumpblob: dumping blob to file\n");
int ret = dd_init(MODE_CONSUMER, 0, job_id);
printf("dd_init(): %d\n", ret);
dd_config(channels_enabled, blob_size, 0, job_id);
dd_status(job_id);
// 创建消费线程
ret = pthread_create(&threads[0], NULL, cons_proc, NULL);
if (ret != 0) {
fprintf(stderr, "Failed to create thread\n");
return -1;
}
pthread_join(threads[0], NULL);
printf("Dump completed.\n");
return 0;
}
\ No newline at end of file
......@@ -7,8 +7,9 @@ lcores_secondary=4
n_mem_channels=2
[port0]
mac_addr=24:42:53:30:28:27
ip_addr=172.31.100.2
pci_addr=0000:03:00.1
mac_addr=6c:b3:11:21:c5:37
ip_addr=192.168.1.100
[port0_dst]
mac_addr=24:42:53:30:29:37
......@@ -135,14 +135,14 @@ static int init_port(uint16_t port_num)
const struct rte_eth_conf port_conf = {
.rxmode = {
.mq_mode = ETH_MQ_RX_RSS,
.max_rx_pkt_len = 3000, //RTE_MIN(JUMBO_FRAME_MAX_SIZE, dev_info.max_rx_pktlen),
.max_rx_pkt_len = RTE_MIN(JUMBO_FRAME_MAX_SIZE, dev_info.max_rx_pktlen),
.split_hdr_size = 0,
.offloads = 0 //(DEV_RX_OFFLOAD_CHECKSUM) // |
//DEV_RX_OFFLOAD_SCATTER |
//DEV_RX_OFFLOAD_JUMBO_FRAME),
.offloads = (DEV_RX_OFFLOAD_CHECKSUM |
DEV_RX_OFFLOAD_SCATTER |
DEV_RX_OFFLOAD_JUMBO_FRAME),
},
.txmode = {
.offloads = 0 //DEV_TX_OFFLOAD_MULTI_SEGS,
.offloads = DEV_TX_OFFLOAD_MULTI_SEGS,
}
};
......@@ -396,7 +396,7 @@ void udpdk_cleanup(void)
// Kill the poller process
RTE_LOG(INFO, CLOSE, "Killing the poller process (%d)...\n", poller_pid);
//kill(poller_pid, SIGTERM);
kill(poller_pid, SIGTERM);
pid = waitpid(poller_pid, NULL, 0);
if (pid < 0) {
RTE_LOG(WARNING, CLOSE, "Failed killing the poller process\n");
......
......@@ -331,8 +331,7 @@ static inline void reassemble(struct rte_mbuf *m, uint16_t portid, uint32_t queu
eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
//if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) { //vmxnet3 has no checksum offload for IP packet
if (1) {
if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
ip_hdr = (struct rte_ipv4_hdr *)(eth_hdr + 1);
......@@ -473,8 +472,7 @@ void poller_body(void)
// Free the original mbuf
rte_pktmbuf_free(pkt);
// Checksum must be recomputed
//ol_flags = (PKT_TX_IPV4 | PKT_TX_IP_CKSUM);
ol_flags = (PKT_TX_IPV4);
ol_flags = (PKT_TX_IPV4 | PKT_TX_IP_CKSUM);
if (unlikely(n_fragments < 0)) {
RTE_LOG(ERR, POLLBODY, "Failed to fragment a packet\n");
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment