• imx6获取和同步时间


    1.imx6上面直接在ubuntu上用arm-linux-交叉编译工具编译,编完看是直接U盘还是ssh+scp搞出来;imx8到自己客制的文件夹目录里面,配置好当前层的mk和设备树的mk后,到顶部目录export导入环境变量,然后source ,lunch,之后到对应的修改好的目录里面mm单编,编成功后的Log会提示编出来的东西在哪个目录里,一般是out/里面

    1. $ export AARCH64_GCC_CROSS_COMPILE=/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu/bin/aarch64-linux-gnu-
    2. $ export CLANG_PATH=/opt/prebuilt-android-clang
    3. $ export ARMGCC_DIR=/opt/gcc-arm-none-eabi-7-2018-q2-update //这三条是导入环境变量
    4. $ source build/envsetup.sh //回顶层目录source和lunch
    5. $ bash build/envsetup.sh //source一样,source 不行的时候用bash
    6. $ lunch mek_8q_car-userdebug
    7. $去对应的目录mm

    2.暂且用网线连接imx6和imx8,二者的通讯暂用udp;imx6发imx8接,并且把接到的rtc时间同步(写入)到自己的里面作为自己时间。收的这边固定设IP为192.168.100.3

    注意:

    1)imx8这边把编好的应用程序直接adb push进去,这时候确保先adb root ,之后adb remount,然后再进去;

    2)adb push进去的时候,不要push到imx8的/storage下面,去这下面跑应用程序是permission denied,最后是挪到/data下面才跑通的,确保跑之前把应用程序chmod 777一下

    代码

    发送端:

    1. #include
    2. #include
    3. #include in.h>
    4. #include
    5. #include
    6. #include <string.h>
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include //文件io必须定义这个
    12. #define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time) /* Set alarm time */
    13. #define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
    14. #define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time) /* Read RTC time */
    15. #define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time) /* Set RTC time */
    16. #define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long) /* Read IRQ rate */
    17. #define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long) /* Set IRQ rate */
    18. #define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
    19. #define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
    20. //前面这些RTC_xxx是定义的io控制,这些要去rtc驱动的.c或者.h里面找
    21. #define SERVER_IP "192.168.100.3" //IP号之间不能有空格
    22. void ClientDataHandle_connect_read_write(int socketfd)
    23. {
    24. /*int byte, cnt = 0;
    25. unsigned char data[1024];
    26. struct rtc_device rtc;
    27. struct rtc_time tm;
    28. while(1)
    29. {
    30. data=rtc_read_time(&rtc,&tm);
    31. memset(data, 0, 1024);
    32. sprintf(data, "client send data cnt:%d", ++cnt);
    33. write(socketfd, data, strlen(data));
    34. printf("client write to server successful\n");
    35. memset(data, 0, 1024);
    36. byte = read(socketfd, data, 1024); //读取server数据,有数据更新才读取,否则阻塞
    37. if(byte == 0)
    38. {
    39. perror("read over");
    40. break;
    41. }
    42. if(byte < 0)
    43. {
    44. perror("read failed");
    45. break;
    46. }
    47. printf("server-->client datelen:%d info:%s\r\n",byte, data);
    48. sleep(5);
    49. }
    50. return;*/
    51. }
    52. void ClientDataHandle_connect_recvfrom_sendto(int socketfd)
    53. {
    54. /*int cnt = 0, byte = 0;
    55. unsigned char data[1024];
    56. while(1)
    57. {
    58. memset(data, 0, 1024);
    59. sprintf(data, "client send data cnt:%d\n", ++cnt); //
    60. sendto(socketfd, data, strlen(data), 0, NULL, 0);
    61. memset(data, 0, 1024);
    62. //读取server数据,有数据更新才读取,否则阻塞
    63. byte = recvfrom(socketfd, data, 1024, 0, NULL, NULL);
    64. if(byte == 0)
    65. {
    66. perror("read over");
    67. break;
    68. }
    69. if(byte < 0)
    70. {
    71. perror("read failed");
    72. break;
    73. }
    74. printf("server-->client datelen:%d info:%s\r\n",byte, data);
    75. sleep(5);
    76. }
    77. */
    78. }
    79. int main(int argc, void *argv[] )
    80. {
    81. int socketfd = -1;
    82. struct sockaddr_in servaddr;
    83. int rtcfd = -1;
    84. const char *rtcdev = "/dev/rtc0";
    85. int ret = 0;
    86. // struct rtc_device rtc;
    87. struct rtc_time tm;
    88. char buf[1024]; //时间保存到这个buf里面,是char,字符
    89. memset(&servaddr,0,sizeof(servaddr));
    90. servaddr.sin_family=AF_INET;
    91. servaddr.sin_addr.s_addr=inet_addr(SERVER_IP);
    92. servaddr.sin_port=htons(1025);
    93. if( (socketfd = socket(AF_INET, SOCK_DGRAM, 0) ) == -1) //socket函数类似于open函数,打开并创建一个socket,AF_INET使用IPV4协议族,SOCK_STREAM为TCP套接口
    94. {
    95. perror("socket create failed!\n");
    96. return -1;
    97. }
    98. if(connect(socketfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0){
    99. perror("socket connect failed\n");
    100. return -1;
    101. }
    102. rtcfd = open(rtcdev,O_RDWR);
    103. if(rtcfd == -1){
    104. perror("open rtc error!");
    105. }
    106. while(1){
    107. ret = ioctl(rtcfd, RTC_RD_TIME, &tm); //获取时间
    108. printf("[app] ret= %d , tm_sec=%d,tm_min=%d,tm_hour=%d\r\n",ret, tm.tm_sec, tm.tm_min,tm.tm_hour);
    109. memset(buf,0,1024);
    110. sprintf(buf,"%d:%d:%d\n",tm.tm_hour,tm.tm_min,tm.tm_sec); //这里确保打印出的是字符
    111. sendto(socketfd,buf,sizeof(buf),0,NULL,0);
    112. sleep(1);
    113. /*memset(&servaddr, 0, sizeof(servaddr) );
    114. servaddr.sin_family = AF_INET;
    115. servaddr.sin_addr.s_addr = inet_addr(SERVER_IP);
    116. servaddr.sin_port = htons(1025); //1024以后的端口号是动态的可随意取用
    117. if(connect(socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 )
    118. {
    119. perror("socket connect failed!");
    120. return -1;
    121. }*/
    122. }
    123. //ClientDataHandle_connect_read_write(socketfd);//效果与下方函数一样
    124. //ClientDataHandle_connect_recvfrom_sendto(socketfd);
    125. return 0;
    126. }

    接收端:

    1. #include
    2. #include
    3. #include in.h>
    4. #include
    5. #include
    6. #include <string.h>
    7. #include
    8. #include
    9. #include
    10. #define BUF_SIZE 1024
    11. #define SERVER_IP "192.168.100.3"
    12. #define FILE_NAME "1.txt"
    13. void ServerDataHandle_recvform_sendto(int fd)
    14. {
    15. int byte = 0, cnt = 0;
    16. char buf[BUF_SIZE] = {0};
    17. socklen_t len = sizeof(struct sockaddr_in);
    18. struct sockaddr_in clientaddr;
    19. int file_fd=0;
    20. file_fd=open(FILE_NAME,O_TRUNC|O_WRONLY); //这里的打开方式很重要不能改
    21. if(file_fd<0){
    22. perror("open file err");
    23. return ;
    24. }
    25. if(fd <= 0)
    26. {
    27. perror("socket fd value err");
    28. return ;
    29. }
    30. while(1)
    31. {
    32. memset(buf, 0, BUF_SIZE );
    33. byte = recvfrom(fd, buf, BUF_SIZE, 0, (struct sockaddr *)&clientaddr, &len); //读取client数据,有数据更新才读取,否则阻塞
    34. if(byte == 0) //客户端关闭时,读取数据个数为0
    35. {
    36. printf("sockfd:%d read over\n", fd);
    37. break;
    38. }
    39. if(byte < 0)
    40. {
    41. perror("read failed");
    42. break;
    43. }
    44. printf("client IP:%s, port:%d, datalen:%d, info:%s\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, byte, buf );
    45. write(file_fd,buf,byte);
    46. write(file_fd,"\n",1);
    47. fsync(file_fd);
    48. memset(buf, 0, BUF_SIZE );
    49. sprintf(buf, "server send cnt:%d\n", ++cnt);
    50. sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
    51. //sleep(5);
    52. //
    53. ioctl(listenfd,RTC_SET_TIME,&tm);
    54. }
    55. close(fd);
    56. close(file_fd);
    57. }
    58. int main()
    59. {
    60. int listenfd, opt = 1;
    61. struct sockaddr_in serveraddr;
    62. int time_buf[]={0};
    63. listenfd = socket(AF_INET, SOCK_DGRAM, 0);
    64. if(listenfd < 0)
    65. {
    66. perror("Create socket fail.");
    67. return -1;
    68. }
    69. memset( (void*)&serveraddr,0,sizeof(struct sockaddr_in) );
    70. serveraddr.sin_family = AF_INET;
    71. serveraddr.sin_port = htons(1025);
    72. //serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    73. serveraddr.sin_addr.s_addr = inet_addr(SERVER_IP); //自动生成自身IP做服务器IP给客户端连接
    74. if(bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_in))<0) //绑定
    75. {
    76. perror("bind error.");
    77. return -1;
    78. }
    79. ServerDataHandle_recvform_sendto(listenfd); //注意这里传进来的listenfd对应前面的fd
    80. return 0;
    81. }

    对应接收端,imx8这边的还需要按上面所说的配mk

    一个是设备树的:

    1. # -------@block_infrastructure-------
    2. CONFIG_REPO_PATH := device/nxp
    3. CURRENT_FILE_PATH := $(lastword $(MAKEFILE_LIST))
    4. IMX_DEVICE_PATH := $(strip $(patsubst %/, %, $(dir $(CURRENT_FILE_PATH))))
    5. # -------@block_kernel_bootimg-------
    6. # Don't enable vendor boot for Android Auto with M4 EVS for now
    7. TARGET_USE_VENDOR_BOOT ?= false
    8. # -------@block_storage-------
    9. # Android Auto with M4 EVS does not use dynamic partition
    10. TARGET_USE_DYNAMIC_PARTITIONS ?= false
    11. # -------@block_infrastructure-------
    12. include $(IMX_DEVICE_PATH)/mek_8q.mk
    13. # -------@block_common_config-------
    14. # Overrides
    15. PRODUCT_NAME := mek_8q_car
    16. PRODUCT_PACKAGE_OVERLAYS += $(IMX_DEVICE_PATH)/overlay_car
    17. # -------@block_app-------
    18. PRODUCT_COPY_FILES += \
    19. $(IMX_DEVICE_PATH)/privapp-permissions-imx.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/permissions/privapp-permissions-imx.xml
    20. # Add Google prebuilt services
    21. PRODUCT_PACKAGES += \
    22. HeadUnit \
    23. privapp_permissions_google_auto
    24. # -------@block_camera-------
    25. # Add Car related HAL
    26. PRODUCT_PACKAGES += \
    27. android.hardware.automotive.vehicle@2.0-service \
    28. android.automotive.sv.service@1.0-impl \
    29. sv_app
    30. # -------@block_miscellaneous-------
    31. PRODUCT_COPY_FILES += \
    32. packages/services/Car/car_product/init/init.bootstat.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.bootstat.rc \
    33. packages/services/Car/car_product/init/init.car.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.car.rc \
    34. # ONLY devices that meet the CDD's requirements may declare these features
    35. PRODUCT_COPY_FILES += \
    36. frameworks/native/data/etc/android.hardware.screen.landscape.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.screen.landscape.xml \
    37. frameworks/native/data/etc/android.hardware.type.automotive.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.type.automotive.xml
    38. ifeq ($(PRODUCT_IMX_CAR_M4),false)
    39. # Simulate the vehical rpmsg register event for non m4 car image
    40. PRODUCT_PROPERTY_OVERRIDES += \
    41. vendor.vehicle.register=1 \
    42. vendor.evs.video.ready=1
    43. else
    44. #open bootanimation
    45. PRODUCT_PROPERTY_OVERRIDES += \
    46. debug.sf.nobootanimation=0
    47. endif # PRODUCT_IMX_CAR_M4
    48. #isoftstone
    49. PRODUCT_PACKAGES += \
    50. spidev_test \
    51. uartdev_test \
    52. RTCdev_test \
    53. sensor_test \
    54. memtester \
    55. badblocks \
    56. SmartCockpitLauncher \
    57. ApaCamera2 \
    58. Upgrade
    59. PRODUCT_COPY_FILES += \
    60. vendor/isoftstone/product/media/bootanimation.zip:$(TARGET_COPY_OUT_PRODUCT)/media/bootanimation.zip \
    61. vendor/isoftstone/idc/Vendor_1a86_Product_e2e4.idc:$(TARGET_COPY_OUT_VENDOR)/usr/idc/Vendor_1a86_Product_e2e4.idc \
    62. vendor/isoftstone/idc/Vendor_1a86_Product_e5e3.idc:$(TARGET_COPY_OUT_VENDOR)/usr/idc/Vendor_1a86_Product_e5e3.idc

    还有就是对应的目录下面的mk:

    1. LOCAL_PATH:= $(call my-dir)
    2. include $(CLEAR_VARS)
    3. LOCAL_SRC_FILES:=imx8_time.c
    4. LOCAL_MODULE:=RTC_test
    5. include $(BUILD_EXECUTABLE)

    注意:

    接收方:
    1. 先touch 1.txt 手动  如果报open错误
    2. open file的方式 O_TRUNC | O_WRONLY ,如果改成仅仅O_TRUNC,1.txt里面会没东西

     

    发送方:
    3.发送字符,而不是发送结构体,循环里改成(类似的在main之前被注释掉的函数里有写):
                                    memset(buf,0,1024);
            
            sprintf(buf,"%d:%d:%d\n",tm.tm_hour,tm.tm_min,tm.tm_sec);
            
            sendto(socketfd, buf, sizeof(buf), 0, NULL, 0);

    这里如果不确保是发送字符而是发送结构体的话,那么不论收到的还是保存数据1.txt里面都会是乱码:

     

     

     

    4.struct rtc_device rtc 这里如果报错应该是和rtc.h里面重复定义了

    5.几个fd,  还有几个定义的fd,包括,listenfd,fd,rtcfd,file_fd不要搞混了,然后各个的判断如fd<0不要忘记写。

    if(file_fd < 0)
    {
     perror("open file err");
      return ;
    }

     

    发送里面这个不能忘记写,写在if(fd<0)前面


    6.进去板子里跑应用程序的时候,imx8这边不要Push到/storage下面,这下面哪怕chmod 777 了也跑不了,会报permission denied,最后是去/data下面跑通的

    接下来要把imx8收到的rtc时钟信息保存到自己的时间里面,目前的话,想的是通过date命令,然后看了date命令的 date --help是这样:

     最后今天学到的:set nu可以显示代码的行号

  • 相关阅读:
    Maven版本管理
    Redis使用基础教程
    强化深度学习中利用时序差分法中的Sarsa算法解决风险投资问题实战(附源码 超详细必看)
    vscode使用CSScomb插件
    迅为iTOP-2K1000开发板龙芯中科国产64位Loognix系统工业核心主板
    C++ Reference: Standard C++ Library reference: C Library: cctype: isalpha
    软件测试的方法总结
    解决VSCode下载速度很慢
    漏洞复现--Juniper Networks Junos OS EX远程命令执行漏洞(CVE-2023-36845)
    常用免费api推荐,提升开发效率
  • 原文地址:https://blog.csdn.net/weixin_51431342/article/details/127656988