diff --git a/source/linux_driver/encoder_drv_test/Makefile b/source/linux_driver/encoder_drv_test/Makefile new file mode 100644 index 0000000..b188313 --- /dev/null +++ b/source/linux_driver/encoder_drv_test/Makefile @@ -0,0 +1,86 @@ +CROSS_COMPILE ?= /home/lyz/software/gcc-linaro-12.2.1-arm-linux-gnueabihf/bin/arm-linux-gnueabihf- + +TARGET := target +BUILD_DIR := build + +ifeq ("$(origin V)", "command line") + KBUILD_VERBOSE = $(V) +endif +ifndef KBUILD_VERBOSE + KBUILD_VERBOSE = 0 +endif + +ifeq ($(KBUILD_VERBOSE),1) + quiet = + Q = +else + quiet=quiet_ + Q = @ +endif + +ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4 +ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),) + quiet=silent_ +endif +else # make-3.8x +ifneq ($(filter s% -s%,$(MAKEFLAGS)),) + quiet=silent_ +endif +endif + + +SRC := $(wildcard *.c) +ASM_SRC := $(wildcard *.s) +OBJ := $(addprefix $(BUILD_DIR)/, $(notdir $(SRC:.c=.o))) +ASM_OBJ := $(addprefix $(BUILD_DIR)/, $(notdir $(ASM_SRC:.s=.o))) +DIS := $(addprefix $(BUILD_DIR)/, $(notdir $(SRC:.c=.dis))) +ASM_DIS := $(addprefix $(BUILD_DIR)/, $(notdir $(ASM_SRC:.s=.dis))) + +_TARGET := $(BUILD_DIR)/$(TARGET) +TARGET_DIS := $(BUILD_DIR)/$(TARGET).dis + +LD = $(CROSS_COMPILE)ld +CC = $(CROSS_COMPILE)gcc +CPP = $(CC) -E +AR = $(CROSS_COMPILE)ar +LDR = $(CROSS_COMPILE)ldr +STRIP = $(CROSS_COMPILE)strip +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump +CFLAGS = -g -std=gnu99 -Wall -I. +LDFLAGS = -lpthread -lc -lm -lrt + +.SECONDARY: + +.PHONY:all +all: $(_TARGET) $(DIS) $(ASM_DIS) $(TARGET_DIS) + +$(BUILD_DIR)/%.i:%.c %.h Makefile | $(BUILD_DIR) + $(Q)$(CC) -E $(CFLAGS) $< -o $@ +$(BUILD_DIR)/%.s:$(BUILD_DIR)/%.i Makefile | $(BUILD_DIR) + $(Q)$(CC) -S $(CFLAGS) $< -o $@ +$(BUILD_DIR)/%.o:$(BUILD_DIR)/%.s Makefile | $(BUILD_DIR) + $(Q)$(CC) -c $(CFLAGS) $< -o $@ +$(BUILD_DIR)/%.o:%.s Makefile | $(BUILD_DIR) + $(Q)$(CC) -c $(CFLAGS) $< -o $@ +$(BUILD_DIR)/%.dis:$(BUILD_DIR)/%.o Makefile | $(BUILD_DIR) + $(Q)$(OBJDUMP) -s -d $< > $@ +$(TARGET_DIS):$(_TARGET) Makefile | $(BUILD_DIR) + $(Q)$(OBJDUMP) -s -d $< > $@ +$(_TARGET):$(OBJ) $(ASM_OBJ) Makefile | $(BUILD_DIR) + $(Q)$(CC) $(OBJ) $(ASM_OBJ) $(LDFLAGS) -o $@ + + +.PHONY:clean +clean: + $(Q)$(RM) $(BUILD_DIR)/* -f + +.PHONY:install +install:$(TARGET) + $(Q)chmod 777 $(TARGET) + +.PHONY:$(BUILD_DIR) +$(BUILD_DIR): + $(Q)if [ ! -d $(BUILD_DIR) ]; then mkdir -p $@; fi + + \ No newline at end of file diff --git a/source/linux_driver/encoder_drv_test/common.h b/source/linux_driver/encoder_drv_test/common.h new file mode 100644 index 0000000..6578f99 --- /dev/null +++ b/source/linux_driver/encoder_drv_test/common.h @@ -0,0 +1,46 @@ +/** + * @file common.h + * @brief Common macros. + * @author miaow (3703781@qq.com) + * @version 1.0 + * @date 2022/06/12 + * @mainpage github.com/NanjingForestryUniversity + * + * @copyright Copyright (c) 2022 miaow + * + * @par Changelog: + * + *
Date Version Author Description + *
2022/06/12 1.0 miaow Write this file + *
+ */ +#ifndef __COMMON_H +#define __COMMON_H + +#include +#include + +#define ON_ERROR(res, message1, message2) \ + if (res < 0) \ + { \ + sprintf(perror_buffer, "error %d at %s:%d, %s, %s", res, __FILE__, __LINE__, message1, message2); \ + perror(perror_buffer); \ + } + +#define ON_ERROR_RET_VOID(res, message1, message2) \ + ON_ERROR(res, message1, message2); \ + if (res < 0) \ + { \ + res = 0; \ + return; \ + } + +#define ON_ERROR_RET(res, message1, message2, retval) \ + ON_ERROR(res, message1, message2); \ + if (res < 0) \ + { \ + res = 0; \ + return retval; \ + } + +#endif \ No newline at end of file diff --git a/source/linux_driver/encoder_drv_test/encoder_dev.c b/source/linux_driver/encoder_drv_test/encoder_dev.c new file mode 100644 index 0000000..05c6666 --- /dev/null +++ b/source/linux_driver/encoder_drv_test/encoder_dev.c @@ -0,0 +1,129 @@ +/** + * @file encoder_dev.c + * @brief Manage the hardware encoder unit + * @author miaow (3703781@qq.com) + * @version 1.0 + * @date 2022/06/11 + * @mainpage github.com/NanjingForestryUniversity + * + * @copyright Copyright (c) 2022 miaow + * + * @par Changelog: + * + *
Date Version Author Description + *
2022/06/11 0.9 Miaow Write this module + *
+ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ENCODER_CMD_FUNCTION_CLEAR 1 +#define ENCODER_CMD_FUNCTION_VIRT_INPUT 2 + +static int encoder_dev_fd = -1; +static char perror_buffer[128]; + +static struct { + uint32_t valve_divide_value; + uint32_t camera_a_divide_value; + uint32_t camera_b_divide_value; + uint32_t camera_c_divide_value; + uint32_t camera_d_divide_value; +} encoder_dev_divide_value_structure; + +/** + * @brief Initialize the hardware encoder unit + * @note This function just open the file descriptor of the hardware encoder unit + * @return 0 - success, other - error + */ +int encoder_dev_init() +{ + encoder_dev_fd = open(ENCODER_DEV_PATH, O_RDWR); + ON_ERROR_RET(encoder_dev_fd, "", "", -1); + return 0; +} + +/** + * @brief Set the two divider in the hareware encoder unit. + * @param valve_divide the frequency division factor between the encoder signal and valve output + * Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter + * @param camera_divide the frequency division factor between the encoder signal and camera triggle signal + * Set ENCODER_DEV_DIVIDE_NOT_TO_SET to skip changing the division facter + * + * @return 0 - success, other - error + */ +int encoder_dev_set_divide(int valve_divide, + int camera_a_divide, + int camera_b_divide, + int camera_c_divide, + int camera_d_divide) +{ + encoder_dev_divide_value_structure.valve_divide_value = valve_divide; + encoder_dev_divide_value_structure.camera_a_divide_value = camera_a_divide; + encoder_dev_divide_value_structure.camera_b_divide_value = camera_b_divide; + encoder_dev_divide_value_structure.camera_c_divide_value = camera_c_divide; + encoder_dev_divide_value_structure.camera_d_divide_value = camera_d_divide; + ssize_t size = write(encoder_dev_fd, &encoder_dev_divide_value_structure, sizeof(encoder_dev_divide_value_structure)); + int res = -(size != sizeof(encoder_dev_divide_value_structure)); + ON_ERROR_RET(res, "size=", "", -1); + + return 0; +} + +/** + * @brief Set the trig signal to internal or external. + * @param count the count of virtual trig cycles. + * @return 0 - success, other - error + */ +int encoder_dev_virtual_trig(int count) +{ + int res = ioctl(encoder_dev_fd, _IOW('D', ENCODER_CMD_FUNCTION_VIRT_INPUT, int), count); + ON_ERROR_RET(res, "", "", -1); + return 0; +} + +/** + * @brief Set the trig signal to internal or external. + * @param mode ENCODER_TRIG_MODE_EXTERNEL for externally trig, or ENCODER_TRIG_MODE_INTERNEL for internally trig + * @return 0 - success, other - error + */ +int encoder_dev_set_trigmod(int mode) +{ + int res = ioctl(encoder_dev_fd, _IOW('D', mode, int)); + ON_ERROR_RET(res, "", "", -1); + return 0; +} + +/** + * @brief Claer the cache in hardware encoder unit. + * @note The frequency division counters continutly count pluses of external/internal signal. + * This functhion clears the counters. + * @return 0 - success, other - error + */ +int encoder_dev_flush() +{ + int res = ioctl(encoder_dev_fd, _IOW('D', ENCODER_CMD_FUNCTION_CLEAR, 0)); + ON_ERROR_RET(res, "", "", -1); + return 0; +} + +/** + * @brief Deinitialize the hardware encoder unit. + * @note This function just close the file descriptor of the encoder unit. + * @return 0 - success, other - error + */ +int encoder_dev_deinit() +{ + int res = close(encoder_dev_fd); + + ON_ERROR_RET(res, "", "", -1); + return 0; +} diff --git a/source/linux_driver/encoder_drv_test/encoder_dev.h b/source/linux_driver/encoder_drv_test/encoder_dev.h new file mode 100644 index 0000000..1faa19b --- /dev/null +++ b/source/linux_driver/encoder_drv_test/encoder_dev.h @@ -0,0 +1,39 @@ +/** + * @file encoder_dev.h + * @brief Manage the hardware encoder unit + * @author miaow (3703781@qq.com) + * @version 1.0 + * @date 2022/06/11 + * + * @copyright Copyright (c) 2022 miaow + * + * @par Changelog: + * + *
Date Version Author Description + *
2022/06/11 0.9 Miaow Write this module + *
+ */ +#ifndef __ENCODER_DEV_H +#define __ENCODER_DEV_H + +#include + +#define ENCODER_DEV_PATH "/dev/encoder" + +#define ENCODER_DEV_DIVIDE_NOT_TO_SET 0 + +#define ENCODER_TRIG_MODE_EXTERNEL 100 +#define ENCODER_TRIG_MODE_INTERNEL 101 + +int encoder_dev_set_divide(int valve_divide, + int camera_a_divide, + int camera_b_divide, + int camera_c_divide, + int camera_d_divide); +int encoder_dev_flush(void); +int encoder_dev_set_trigmod(int mode); +int encoder_dev_virtual_trig(int count); +int encoder_dev_init(void); +int encoder_dev_deinit(void); + +#endif diff --git a/source/linux_driver/encoder_drv_test/main.c b/source/linux_driver/encoder_drv_test/main.c new file mode 100644 index 0000000..39420db --- /dev/null +++ b/source/linux_driver/encoder_drv_test/main.c @@ -0,0 +1,62 @@ +#include "encoder_dev.h" +#include +#include +#include +#include +#include + +static void sig_handler(int sig); + +int main(int argc, char *argv[]) +{ + unsigned int a = 100, b = 100, c = 100, d = 100; + unsigned int divider = 0; + char which[32] = {0}; + encoder_dev_init(); + encoder_dev_set_trigmod(ENCODER_TRIG_MODE_EXTERNEL); + encoder_dev_set_divide(500, 200, 100, 500, 50); + signal(SIGINT, (sig_t)sig_handler); + while (1) + { + + while (strcmp(which, "a") && strcmp(which, "b") && strcmp(which, "c") && strcmp(which, "d") && strcmp(which, "all")) + { + printf("which camera(a/b/c/d/all)? "); + scanf("%s", which); + } + + printf("divider value?(2~2^32-1)? "); + scanf("%ud", ÷r); + if (strcmp(which, "a") == 0) + { + a = divider; + } + else if (strcmp(which, "b") == 0) + { + b = divider; + } + else if (strcmp(which, "c") == 0) + { + c = divider; + } + else if (strcmp(which, "d") == 0) + { + d = divider; + } + else if (strcmp(which, "all") == 0) + { + a = b = c = d = divider; + } + encoder_dev_set_divide(500, a, b, c, d); + printf("divider of camera %s is set to %d\r\n\r\n", which, divider); + which[0] = '\0'; + } +} + +static void sig_handler(int sig) +{ + encoder_dev_set_trigmod(ENCODER_TRIG_MODE_INTERNEL); + encoder_dev_deinit(); + printf("\r\n\r\nExisting..."); + exit(0); +} \ No newline at end of file diff --git a/source/linux_driver/encoder_drv_test/main.h b/source/linux_driver/encoder_drv_test/main.h new file mode 100644 index 0000000..e69de29