差别
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
a40i [2023/08/13 22:34] hc |
a40i [2023/08/23 20:09] (当前版本) hc [Linux C编程指导] |
||
---|---|---|---|
行 8: | 行 8: | ||
} | } | ||
====接口布局和尺寸==== | ====接口布局和尺寸==== | ||
- | |||
- | |||
- | |||
- | |||
- | ====快速上手==== | ||
- | ===系统下载=== | ||
- | ==Linux系统== | ||
- | Buildroot: | ||
- | |||
- | ===工具链下载=== | ||
- | ==工具== | ||
- | |||
- | ===烧录工具下载=== | ||
- | ==烧录工具== | ||
- | |||
- | ===系统烧录=== | ||
- | 1、下载烧录工具: | ||
- | * | ||
- | |||
- | 2、开始烧录: | ||
- | |||
- | |||
- | |||
- | 3、完成烧录: | ||
- | * 烧录过程不需要任何操作,烧录成功后右框会显示设备自动重启,烧录完成。 | ||
行 123: | 行 98: | ||
# iperf -c 192.168.2.238 -i 1 // | # iperf -c 192.168.2.238 -i 1 // | ||
{{: | {{: | ||
- | | + | |
- | {{: | + | |
| | ||
| | ||
- | | ||
- | {{: | ||
| | ||
| | ||
- | | + | |
- | | + | |
| | ||
| | ||
| | ||
- | stty -F / | ||
- | stty -F / | ||
使用485A1/ | 使用485A1/ | ||
- | + | | |
- | | + | |
使用485A2/ | 使用485A2/ | ||
- | | + | |
- | 在接收端可以收到字符: | + | |
- | + | ||
- | {{: | + | |
| | ||
| | ||
- | RS232RX3/TX3 | + | RS232RX/TX -- /dev/ttyS4 |
- | RS232RX4/ | + | |
| | ||
- | | + | |
- | 设置串口: | + | 接收: |
+ | com_recv /dev/ttyS4 115200 | ||
- | stty -F / | + | |
- | stty -F / | + | |
- | 使用RS232RX3/ | + | |
- | cat /dev/ttyXRUSB2 | + | |
- | 使用RS232RX4/ | + | 在接收端可以收到字符: |
- | echo abcdefghijklmn >/ | + | {{: |
- | 在接收端可以收到字符: | + | |
- | {{: | ||
| | ||
- | CAN接口定义 | ||
- | {{: | ||
- | |||
- | CAN测试方法,连接CAN1L -- CAN2L ,CAN1H -- CAN2H | ||
设置can: | 设置can: | ||
行 181: | 行 142: | ||
ip link set can0 type can bitrate 125000 | ip link set can0 type can bitrate 125000 | ||
ip link set can0 up | ip link set can0 up | ||
- | |||
- | |||
- | ip link set can1 down | ||
- | ip link set can1 type can bitrate 125000 | ||
- | ip link set can1 up | ||
使用can0 接收: | 使用can0 接收: | ||
candump can0 | candump can0 | ||
- | 使用can1发送数据帧: | + | 使用can分析仪发送数据帧 |
| | ||
- | cansend can1 123# | + | |
查看接收端: | 查看接收端: | ||
行 199: | 行 155: | ||
C编程指导参考:[[np-8132-v0a# | C编程指导参考:[[np-8132-v0a# | ||
- | ===左右拨码开关使用方法=== | + | ===RUN/STOP开关使用方法=== |
- | + | 分别对应2个GPIO197、GPIO198 | |
- | [root@rk3399: | + | 拨到RUN时查看状态: |
- | No device specified, trying to scan all of / | + | |
- | Available devices: | + | |
- | / | + | |
- | / | + | |
- | / | + | |
- | / | + | |
- | Select the device event number [0-3]: 2 | + | |
- | Input driver version is 1.0.1 | + | |
- | Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100 | + | |
- | Input device name: " | + | |
- | Supported events: | + | |
- | Event type 0 (EV_SYN) | + | |
- | Event type 1 (EV_KEY) | + | |
- | Event code 105 (KEY_LEFT) | + | |
- | Event code 106 (KEY_RIGHT) | + | |
- | Properties: | + | |
- | Testing ... (interrupt to exit) | + | |
- | Event: time 1654670127.676876, | + | |
- | Event: time 1654670127.676876, | + | |
- | Event: time 1654670127.693874, | + | |
- | Event: time 1654670127.693874, | + | |
- | Event: time 1654670128.597949, | + | |
- | Event: time 1654670128.597949, | + | |
- | Event: time 1654670128.610192, | + | |
- | Event: time 1654670128.610192, | + | |
- | + | ||
- | C编程指导参考:[[np-8132-v0a# | + | |
- | + | ||
- | | + | |
- | 设置看门狗timeout超时时间 | + | |
- | + | ||
- | i2ctransfer -y -f 4 w3@0x15 0x00 0x02 0x01 | + | |
- | + | ||
- | 以此类比 0x01=1分钟 | + | |
- | + | ||
- | 打开watchdog | + | |
- | | + | |
+ | 为1 | ||
+ | cat / | ||
+ | 为0 | ||
| | ||
- | 喂狗: | + | |
- | | + | |
+ | 为0 | ||
+ | cat / | ||
+ | 为1 | ||
- | ===LED使用方法=== | + | |
+ | ===DODI使用方法=== | ||
- | {{: | + | C源代码参考/root/dido/dido.c |
- | + | ||
- | 系统共有8个LED,pwr_led不可以控制其中7个LED均可控,系统下对应的设备接口为: | + | ===移位寄存器的使用方法=== |
- | + | ||
- | [root@rk3399: | + | |
- | [root@rk3399:/sys/class/ | + | |
- | mmc1:: | + | |
- | 控制work_led1熄灭 | + | |
- | + | ||
- | echo 0 >/ | + | |
- | + | ||
- | 控制work_led1点亮 | + | |
- | + | ||
- | echo 1 >/sys/class/leds/ | + | |
- | + | ||
- | | + | |
| | ||
行 283: | 行 201: | ||
Wed Jun 8 17:02:30 CST 2022 | Wed Jun 8 17:02:30 CST 2022 | ||
- | | ||
- | |||
- | 接入TFCARD,如果TFCARD有分区,系统会自动挂载到/ | ||
- | |||
- | [root@rk3399:/ | ||
- | Filesystem | ||
- | / | ||
- | devtmpfs | ||
- | tmpfs 1963920 | ||
- | tmpfs 1963920 | ||
- | tmpfs 1963920 | ||
- | / | ||
- | |||
- | ===十段位编码开关使用方法=== | + | ===FUN编码开关使用方法=== |
- | + | ||
- | | + | C代码参考 |
- | No device specified, trying to scan all of /dev/input/ | + | |
- | Available devices: | + | |
- | / | + | |
- | / | + | |
- | / | + | |
- | / | + | |
- | Select the device event number [0-3]: 1 | + | |
- | Input driver version is 1.0.1 | + | |
- | Input device ID: bus 0x19 vendor 0x0 product 0x0 version 0x0 | + | |
- | Input device name: " | + | |
- | | + | |
- | Event type 0 (EV_SYN) | + | |
- | Event type 3 (EV_ABS) | + | |
- | Event code 0 (ABS_X) | + | |
- | | + | |
- | | + | |
- | | + | |
- | Properties: | + | |
- | Testing ... (interrupt to exit) | + | |
- | Event: time 1654670726.561933, | + | |
- | Event: time 1654670726.561933, | + | |
- | Event: time 1654670728.565864, | + | |
- | Event: time 1654670728.565864, | + | |
- | Event: time 1654670729.567865, | + | |
- | Event: time 1654670729.567865, | + | |
- | Event: time 1654670731.571873, | + | |
- | Event: time 1654670731.571873, | + | |
- | + | ||
- | C编程指导参考:[[np-8132-v0a# | + | |
| | ||
- | GPO1~GPO16 对应的GPIO编号依次为480~495 | ||
- | GPI1~GPI16 | + | |
- | + | | |
- | 系统支持Linux标准的sysfs gpio操作,以GPO1(480)为例: | + | |
- | + | ||
- | [root@rk3399: | + | |
- | [root@rk3399:/sys/class/ | + | |
- | | + | |
- | [root@rk3399:/ | + | |
- | + | ||
- | C编程指导参考:[[np-8132-v0a# | + | |
| | ||
| | ||
- | | + | |
- | | + | |
- | / | + | |
- | devtmpfs | + | |
- | tmpfs 1963920 | + | |
- | tmpfs 1963920 | + | |
- | tmpfs 1963920 | + | |
- | / | + | |
- | + | ||
- | | + | |
- | 系统已支持Fully Preemptible Kernel(RT), | + | |
- | [root@rk3399:/ | ||
- | | ||
- | 如下图为实时系统连接8台伺服间隔1ms运行效果: | ||
- | |||
- | {{: | ||
- | |||
- | CPU core分布: | ||
- | |||
- | cpu0:linux system | ||
- | cpu1:none | ||
- | cpu2:none | ||
- | cpu3:task | ||
- | cpu4: eth0 | ||
- | cpu5: codecsys run time task | ||
- | | ||
- | | ||
- | ---- | ||
| | ||
=== 交叉编译环境 === | === 交叉编译环境 === | ||
行 381: | 行 221: | ||
| | ||
2. 下载安装交叉编译工具链: | 2. 下载安装交叉编译工具链: | ||
- | apt install -y crossbuild-essential-arm64 | + | apt install -y crossbuild-essential-armhf |
3. 查看是否安装正确: | 3. 查看是否安装正确: | ||
- | aarch64-linux-gnu-gcc -v | + | arm-linux-gnueabihf-gcc -v |
系统有打印Gcc 版本即为正常: | 系统有打印Gcc 版本即为正常: | ||
- | {{:pasted:20220719-004327.png}} | + | {{:pasted:20230823-200954.png}} |
- | === GPIO应用编程 === | + | |
- | 系统下操作GPIO的方式参考[[np-8132-v0a# | + | |
- | + | ||
- | C参考代码如下: | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | static char gpio_path[100]; | + | |
- | // | + | |
- | static int gpio_config(const char *file, const char *value) | + | |
- | { | + | |
- | char config_path[100]; | + | |
- | int len; | + | |
- | int fd; | + | |
- | sprintf(config_path, | + | |
- | if (0 > (fd = open(config_path, | + | |
- | { | + | |
- | perror(" | + | |
- | return fd; | + | |
- | } | + | |
- | len = strlen(value); | + | |
- | if (len != write(fd, value, len)) | + | |
- | { | + | |
- | perror(" | + | |
- | close(fd); | + | |
- | return -1; | + | |
- | } | + | |
- | close(fd); | + | |
- | return 0; | + | |
- | } | + | |
- | // | + | |
- | static int gpio_get(const char *file) | + | |
- | { | + | |
- | char get_path[100]; | + | |
- | char buf[10]={" | + | |
- | int len; | + | |
- | int fd; | + | |
- | sprintf(get_path, | + | |
- | if (0 > (fd = open(get_path, | + | |
- | { | + | |
- | perror(" | + | |
- | return fd; | + | |
- | } | + | |
- | if ( 0 > read(fd, | + | |
- | { | + | |
- | perror(" | + | |
- | return fd; | + | |
- | } | + | |
- | printf(" | + | |
- | close(fd); | + | |
- | return 0; | + | |
- | } | + | |
- | int main(int argc, char *argv[]) | + | |
- | { | + | |
- | if (4 != argc) | + | |
- | { | + | |
- | if (3 != argc) | + | |
- | { | + | |
- | fprintf(stderr, | + | |
- | fprintf(stderr, | + | |
- | exit(-1); | + | |
- | } | + | |
- | } | + | |
- | sprintf(gpio_path, | + | |
- | if (access(gpio_path, | + | |
- | { | + | |
- | printf(" | + | |
- | int fd; | + | |
- | int len; | + | |
- | if (0 > (fd = open("/ | + | |
- | { | + | |
- | perror(" | + | |
- | } | + | |
- | len = strlen(argv[1]); | + | |
- | if (len != write(fd, argv[1], len)) | + | |
- | { | + | |
- | perror(" | + | |
- | close(fd); | + | |
- | exit(-1); | + | |
- | } | + | |
- | close(fd); | + | |
- | } | + | |
- | if (gpio_config(" | + | |
- | exit(-1); | + | |
- | if ( 0 == strcmp(" | + | |
- | { | + | |
- | if(gpio_config(" | + | |
- | exit(-1); | + | |
- | } | + | |
- | printf(" | + | |
- | if (gpio_get(" | + | |
- | exit(-1); | + | |
- | if (gpio_get(" | + | |
- | exit(-1); | + | |
- | exit(0); | + | |
- | } | + | |
- | + | ||
- | 交叉编译源码: | + | |
- | + | ||
- | aarch64-linux-gnu-gcc -o gpio gpio.c | + | |
- | + | ||
- | | + | |
- | + | ||
- | 使用方法: | + | |
- | set gpio out : ./gpio < | + | |
- | set gpio in : ./gpio < | + | |
- | + | ||
- | | + | |
- | + | ||
- | === Switch应用编程 === | + | |
- | 参考系统下操作Switch的方法:[[np-8132-v0a# | + | |
- | / | + | |
- | + | ||
- | C参考代码如下: | + | |
- | + | ||
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #define INPUT_DEVICE "/ | + | |
- | int main(int argc, char **argv){ | + | |
- | int fd; | + | |
- | struct input_event event; | + | |
- | ssize_t bytesRead; | + | |
- | int ret; | + | |
- | fd_set readfds; | + | |
- | if ( 0 > (fd = open(INPUT_DEVICE, | + | |
- | { | + | |
- | perror(" | + | |
- | return fd; | + | |
- | } | + | |
- | while(1){ | + | |
- | FD_ZERO(& | + | |
- | FD_SET(fd,& | + | |
- | ret = select(fd + 1, & | + | |
- | if (ret == -1){ | + | |
- | fprintf(stderr," | + | |
- | break; | + | |
- | } | + | |
- | if(FD_ISSET(fd,& | + | |
- | bytesRead = read(fd, & | + | |
- | if(bytesRead == -1 ) | + | |
- | fprintf(stderr," | + | |
- | } | + | |
- | + | ||
- | if (event.type == EV_KEY && event.code == KEY_RIGHT){ | + | |
- | if(event.value == 1) | + | |
- | printf(" | + | |
- | } | + | |
- | if (event.type == EV_KEY && event.code == KEY_LEFT){ | + | |
- | if(event.value == 1) | + | |
- | printf(" | + | |
- | } | + | |
- | } | + | |
- | close(fd); | + | |
- | return EXIT_SUCCESS; | + | |
- | } | + | |
- | + | ||
- | 交叉编译源码: | + | |
- | aarch64-linux-gnu-gcc -o switch switch.c | + | |
- | 将编译好的程序使用scp 拷贝到8132 主板上,执行测试,拨动switch打印如下: | + | |
- | + | ||
- | {{: | + | |
- | + | ||
- | === Rotary应用编程 === | + | |
- | 参考系统下操作Rotary的方法:[[np-8132-v0a# | + | |
- | / | + | |
- | C参考代码如下: | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #define INPUT_DEVICE "/ | + | |
- | int main(int argc, char **argv){ | + | |
- | int fd; | + | |
- | struct input_event event; | + | |
- | ssize_t bytesRead; | + | |
- | int ret; | + | |
- | fd_set readfds; | + | |
- | if ( 0 > (fd = open(INPUT_DEVICE, | + | |
- | { | + | |
- | perror(" | + | |
- | return fd; | + | |
- | } | + | |
- | while(1){ | + | |
- | FD_ZERO(& | + | |
- | FD_SET(fd,& | + | |
- | ret = select(fd + 1, & | + | |
- | if (ret == -1){ | + | |
- | fprintf(stderr," | + | |
- | break; | + | |
- | } | + | |
- | if(FD_ISSET(fd,& | + | |
- | bytesRead = read(fd, & | + | |
- | if(bytesRead == -1 ) | + | |
- | fprintf(stderr," | + | |
- | } | + | |
- | if (event.type == EV_ABS && event.code == ABS_X){ | + | |
- | printf(" | + | |
- | } | + | |
- | } | + | |
- | close(fd); | + | |
- | return EXIT_SUCCESS; | + | |
- | } | + | |
- | 交叉编译源码: | + | |
- | aarch64-linux-gnu-gcc -o rotary rotary.c | + | |
- | 将编译好的程序使用scp 拷贝到8132 主板上,执行测试,拨动rotary打印如下 | + | |
- | + | ||
- | {{: | + | |
- | === CAN应用编程 === | + | |
- | 参考系统下操作CANBUS的方法:[[np-8132-v0a# | + | |
- | ip link set can0 down | + | |
- | ip link set can0 type can bitrate 125000 | + | |
- | ip link set can0 up | + | |
- | ip link set can1 down | + | |
- | ip link set can1 type can bitrate 125000 | + | |
- | ip link set can1 up | + | |
- | + | ||
- | | + | |
- | + | ||
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | #include < | + | |
- | int main(int argc, char **argv) | + | |
- | { | + | |
- | struct ifreq ifr_recv = {0}; | + | |
- | struct ifreq ifr_send = {0}; | + | |
- | struct sockaddr_can addr_recv = {0}; | + | |
- | struct sockaddr_can addr_send = {0}; | + | |
- | struct can_frame frame_recv = {0}; | + | |
- | struct can_frame frame_send = {0}; | + | |
- | int sockfd_r = -1; | + | |
- | int sockfd_s = -1; | + | |
- | int ret, i; | + | |
- | if ( 3 != argc ) | + | |
- | { | + | |
- | fprintf(stderr, | + | |
- | exit(EXIT_FAILURE); | + | |
- | } | + | |
- | if ( 0 > (sockfd_r = socket(PF_CAN, | + | |
- | { | + | |
- | perror(" | + | |
- | exit(EXIT_FAILURE); | + | |
- | } | + | |
- | if ( 0 > (sockfd_s = socket(PF_CAN, | + | |
- | { | + | |
- | perror(" | + | |
- | exit(EXIT_FAILURE); | + | |
- | } | + | |
- | strcpy(ifr_recv.ifr_name, | + | |
- | ioctl(sockfd_r, | + | |
- | addr_recv.can_family = AF_CAN; | + | |
- | addr_recv.can_ifindex = ifr_recv.ifr_ifindex; | + | |
- | strcpy(ifr_send.ifr_name, | + | |
- | ioctl(sockfd_s, | + | |
- | addr_send.can_family = AF_CAN; | + | |
- | addr_send.can_ifindex = ifr_send.ifr_ifindex; | + | |
- | ret = bind(sockfd_r, | + | |
- | if (0 > ret) | + | |
- | { | + | |
- | perror(" | + | |
- | close(sockfd_r); | + | |
- | exit(EXIT_FAILURE); | + | |
- | } | + | |
- | ret = bind(sockfd_s, | + | |
- | if (0 > ret) | + | |
- | { | + | |
- | perror(" | + | |
- | close(sockfd_s); | + | |
- | exit(EXIT_FAILURE); | + | |
- | } | + | |
- | setsockopt(sockfd_s, | + | |
- | frame_send.data[0] = 0xAA; | + | |
- | frame_send.data[1] = 0xBB; | + | |
- | frame_send.data[2] = 0xCC; | + | |
- | frame_send.data[3] = 0xDD; | + | |
- | frame_send.data[4] = 0xEE; | + | |
- | frame_send.data[5] = 0xFF; | + | |
- | frame_send.data[6] = 0x11; | + | |
- | frame_send.data[7] = 0x22; | + | |
- | frame_send.can_dlc = 8; | + | |
- | frame_send.can_id = 0x123; | + | |
- | while(1) | + | |
- | { | + | |
- | ret = write(sockfd_s, | + | |
- | if(sizeof(frame_send) != ret) | + | |
- | { | + | |
- | perror(" | + | |
- | goto out; | + | |
- | } | + | |
- | printf(" | + | |
- | for (i = 0; i < frame_send.can_dlc; | + | |
- | printf(" | + | |
- | sleep(1); | + | |
- | if (0 > read(sockfd_r, | + | |
- | { | + | |
- | perror(" | + | |
- | break; | + | |
- | } | + | |
- | if (frame_recv.can_id & CAN_ERR_FLAG) | + | |
- | { | + | |
- | printf(" | + | |
- | break; | + | |
- | } | + | |
- | printf(" | + | |
- | for (i = 0; i < frame_recv.can_dlc; | + | |
- | printf(" | + | |
- | printf(" | + | |
- | } | + | |
- | out: | + | |
- | close(sockfd_r); | + | |
- | close(sockfd_s); | + | |
- | exit(EXIT_SUCCESS); | + | |
- | } | + | |
- | 交叉编译源码: | + | |
- | aarch64-linux-gnu-gcc -o cantest cantest.c | + | |
- | 将编译好的程序使用scp 拷贝到8132 主板上,对接CAN0-CAN1执行测试: | + | |
- | {{: | ||