imx6获取和同步时间

编程入门 行业动态 更新时间:2024-10-28 09:29:07

imx6获取和同步<a href=https://www.elefans.com/category/jswz/34/1771441.html style=时间"/>

imx6获取和同步时间

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

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

代码

发送端:

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <fcntl.h>     //文件io必须定义这个#define RTC_ALM_SET	_IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
#define RTC_ALM_READ	_IOR('p', 0x08, struct rtc_time) /* Read alarm time */
#define RTC_RD_TIME	_IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
#define RTC_SET_TIME	_IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
#define RTC_IRQP_READ	_IOR('p', 0x0b, unsigned long)	 /* Read IRQ rate   */
#define RTC_IRQP_SET	_IOW('p', 0x0c, unsigned long)	 /* Set IRQ rate    */
#define RTC_EPOCH_READ	_IOR('p', 0x0d, unsigned long)	 /* Read epoch      */
#define RTC_EPOCH_SET	_IOW('p', 0x0e, unsigned long)	 /* Set epoch       *///前面这些RTC_xxx是定义的io控制,这些要去rtc驱动的.c或者.h里面找#define SERVER_IP "192.168.100.3"	//IP号之间不能有空格void ClientDataHandle_connect_read_write(int socketfd)
{/*int byte, cnt = 0;unsigned char data[1024];struct rtc_device rtc;struct rtc_time tm;while(1){data=rtc_read_time(&rtc,&tm);memset(data, 0, 1024);sprintf(data, "client send data cnt:%d", ++cnt);write(socketfd, data, strlen(data));printf("client write to server successful\n");memset(data, 0, 1024);byte = read(socketfd, data, 1024);	//读取server数据,有数据更新才读取,否则阻塞if(byte == 0){perror("read over");break;}if(byte < 0){perror("read failed");break;}printf("server-->client datelen:%d info:%s\r\n",byte, data);	sleep(5);		}	return;*/
}void ClientDataHandle_connect_recvfrom_sendto(int socketfd)
{/*int cnt = 0, byte = 0;unsigned char data[1024];while(1){memset(data, 0, 1024);sprintf(data, "client send data cnt:%d\n", ++cnt); //sendto(socketfd, data, strlen(data), 0, NULL, 0);memset(data, 0, 1024);//读取server数据,有数据更新才读取,否则阻塞byte = recvfrom(socketfd, data, 1024, 0, NULL, NULL);if(byte == 0){perror("read over");break;}if(byte < 0){perror("read failed");break;}printf("server-->client datelen:%d info:%s\r\n",byte, data);	sleep(5);	}	*/
}int main(int argc, void *argv[] )
{int socketfd = -1;struct sockaddr_in servaddr;int rtcfd = -1;const char *rtcdev = "/dev/rtc0";int ret = 0; 
//	struct rtc_device rtc;struct rtc_time tm;char buf[1024];   //时间保存到这个buf里面,是char,字符memset(&servaddr,0,sizeof(servaddr));servaddr.sin_family=AF_INET;servaddr.sin_addr.s_addr=inet_addr(SERVER_IP);servaddr.sin_port=htons(1025);if( (socketfd = socket(AF_INET, SOCK_DGRAM, 0) ) ==  -1)	//socket函数类似于open函数,打开并创建一个socket,AF_INET使用IPV4协议族,SOCK_STREAM为TCP套接口{perror("socket create failed!\n");return -1;}if(connect(socketfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0){perror("socket connect failed\n");return -1;}rtcfd = open(rtcdev,O_RDWR);if(rtcfd == -1){perror("open rtc error!");}while(1){ret = ioctl(rtcfd, RTC_RD_TIME, &tm);    //获取时间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);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);sleep(1);/*memset(&servaddr, 0, sizeof(servaddr) );servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = inet_addr(SERVER_IP);servaddr.sin_port = htons(1025);   //1024以后的端口号是动态的可随意取用if(connect(socketfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 ){perror("socket connect failed!");return -1;}*/}//ClientDataHandle_connect_read_write(socketfd);//效果与下方函数一样//ClientDataHandle_connect_recvfrom_sendto(socketfd);return 0;	
}

接收端:

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#define BUF_SIZE 1024
#define SERVER_IP "192.168.100.3"
#define FILE_NAME "1.txt"void ServerDataHandle_recvform_sendto(int fd)
{int byte = 0, cnt = 0;char buf[BUF_SIZE] = {0};socklen_t len = sizeof(struct sockaddr_in);struct sockaddr_in clientaddr;int file_fd=0;file_fd=open(FILE_NAME,O_TRUNC|O_WRONLY);  //这里的打开方式很重要不能改if(file_fd<0){perror("open file err");return ;}if(fd <= 0) {perror("socket fd value err");return ;}while(1){memset(buf, 0, BUF_SIZE );byte = recvfrom(fd, buf, BUF_SIZE, 0, (struct sockaddr *)&clientaddr, &len);	//读取client数据,有数据更新才读取,否则阻塞if(byte == 0)							//客户端关闭时,读取数据个数为0{printf("sockfd:%d read over\n", fd);break;}if(byte < 0){perror("read failed");	break;}printf("client IP:%s, port:%d, datalen:%d, info:%s\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, byte, buf );write(file_fd,buf,byte);write(file_fd,"\n",1);fsync(file_fd);memset(buf, 0, BUF_SIZE );sprintf(buf, "server send cnt:%d\n", ++cnt);sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));//sleep(5);//ioctl(listenfd,RTC_SET_TIME,&tm);	}close(fd);close(file_fd);
}int main()
{int listenfd, opt = 1;struct sockaddr_in serveraddr;int time_buf[]={0};listenfd = socket(AF_INET, SOCK_DGRAM, 0);if(listenfd < 0){perror("Create socket fail.");return -1;}	memset( (void*)&serveraddr,0,sizeof(struct sockaddr_in) );serveraddr.sin_family 	      	= AF_INET;serveraddr.sin_port		= htons(1025);//serveraddr.sin_addr.s_addr 	= inet_addr("127.0.0.1");serveraddr.sin_addr.s_addr 	= inet_addr(SERVER_IP);	//自动生成自身IP做服务器IP给客户端连接if(bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_in))<0)	//绑定{perror("bind error.");return -1;}ServerDataHandle_recvform_sendto(listenfd);   //注意这里传进来的listenfd对应前面的fdreturn 0;
}

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

一个是设备树的:

# -------@block_infrastructure-------
CONFIG_REPO_PATH := device/nxp
CURRENT_FILE_PATH :=  $(lastword $(MAKEFILE_LIST))
IMX_DEVICE_PATH := $(strip $(patsubst %/, %, $(dir $(CURRENT_FILE_PATH))))# -------@block_kernel_bootimg-------
# Don't enable vendor boot for Android Auto with M4 EVS for now
TARGET_USE_VENDOR_BOOT ?= false# -------@block_storage-------
# Android Auto with M4 EVS does not use dynamic partition
TARGET_USE_DYNAMIC_PARTITIONS ?= false# -------@block_infrastructure-------
include $(IMX_DEVICE_PATH)/mek_8q.mk# -------@block_common_config-------
# Overrides
PRODUCT_NAME := mek_8q_car
PRODUCT_PACKAGE_OVERLAYS += $(IMX_DEVICE_PATH)/overlay_car# -------@block_app-------
PRODUCT_COPY_FILES += \$(IMX_DEVICE_PATH)/privapp-permissions-imx.xml:$(TARGET_COPY_OUT_SYSTEM)/etc/permissions/privapp-permissions-imx.xml# Add Google prebuilt services
PRODUCT_PACKAGES += \HeadUnit \privapp_permissions_google_auto# -------@block_camera-------
# Add Car related HAL
PRODUCT_PACKAGES += \android.hardware.automotive.vehicle@2.0-service \android.automotive.sv.service@1.0-impl \sv_app# -------@block_miscellaneous-------
PRODUCT_COPY_FILES += \packages/services/Car/car_product/init/init.bootstat.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.bootstat.rc \packages/services/Car/car_product/init/init.car.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.car.rc \# ONLY devices that meet the CDD's requirements may declare these features
PRODUCT_COPY_FILES += \frameworks/native/data/etc/android.hardware.screen.landscape.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.screen.landscape.xml \frameworks/native/data/etc/android.hardware.type.automotive.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.type.automotive.xmlifeq ($(PRODUCT_IMX_CAR_M4),false)
# Simulate the vehical rpmsg register event for non m4 car image
PRODUCT_PROPERTY_OVERRIDES += \vendor.vehicle.register=1 \vendor.evs.video.ready=1
else
#open bootanimation
PRODUCT_PROPERTY_OVERRIDES += \debug.sf.nobootanimation=0
endif # PRODUCT_IMX_CAR_M4#isoftstone
PRODUCT_PACKAGES += \spidev_test \uartdev_test \RTCdev_test  \sensor_test \memtester \badblocks \SmartCockpitLauncher \ApaCamera2 \UpgradePRODUCT_COPY_FILES += \vendor/isoftstone/product/media/bootanimation.zip:$(TARGET_COPY_OUT_PRODUCT)/media/bootanimation.zip \vendor/isoftstone/idc/Vendor_1a86_Product_e2e4.idc:$(TARGET_COPY_OUT_VENDOR)/usr/idc/Vendor_1a86_Product_e2e4.idc \vendor/isoftstone/idc/Vendor_1a86_Product_e5e3.idc:$(TARGET_COPY_OUT_VENDOR)/usr/idc/Vendor_1a86_Product_e5e3.idc

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

LOCAL_PATH:= $(call my-dir)include $(CLEAR_VARS)LOCAL_SRC_FILES:=imx8_time.c
LOCAL_MODULE:=RTC_test
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可以显示代码的行号

更多推荐

imx6获取和同步时间

本文发布于:2023-06-29 00:34:01,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/936321.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:时间

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!