当系统上电启动后,会执行应用层的逻辑,应用层的代码入口是
appvideouicvrcamera_ui.c :MiniGUIMain
1
2MiniGUIMain api_poweron_init(ui_msg_manager_cb);
应用层的初始化,主要是在函数api_poweron_init(ui_msg_manager_cb);中,实现的功能主要是系统参数的初始化,注册回调函数,以及wifi的的初始化。
下面分析具体过程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16api_poweron_init(ui_msg_manager_cb); android_usb_init();//开启adb功能 parameter_init();//初始化flash参数 video_record_init_lock(); //must before uevent init ,the function is to get camera info,and include the number of the chip camera 。directly use camerahal member function thermal_init();//this function is used for realize the related fun of temperature usb_reg_event_callback(usb_event_callback);//this function implements a callback function for registering usb-related events。 uevent_monitor_run();//Event monitoring thread,will involve some socket netlink REC_RegEventCallback(record_event_callback);//register the callback function as in file video.cpp rec_event_call set_video_init_complete_cb(notify_videos_inited);//register the callback function as in video.cpp video_rec_state sd_reg_event_callback(sd_event_callback);//register the callback function as file usb_sd_ctrl.c sdcard_evnet_call USER_RegEventCallback(user_event_callback);//the file user.cpp user_event_call VIDEOPLAY_RegEventCallback(videoplay_event_callback);//videoplay.c videoplay_event_call fs_msg_file_reg_callback(fsfile_event_callbak);//fs_msg.c fs_msg_file_call wifi_management_start();//wifi init storage_setting_reg_event_callback(storage_setting_callback);public_interface.c storage_filesize_event_call storage_setting_event_callback(0, NULL, NULL);
video_record_init_lock();
1
2
3
4video_record_init_lock(); memset(&g_test_cam_infos, 0, sizeof(g_test_cam_infos)); CamHwItf::getCameraInfos(&g_test_cam_infos);//CamHwItf.cpp the class of CamHwItf member function getCameraInfo
这里面调用的是libcamerahal库代码中的externallibcamerahalCameraHal10_ReleaseCameraHalHALsourceCamHwItf.cpp函数:CamHwItf::getCameraInfos(struct rk_cams_dev_info* cam_infos)。
这个函数实现方式是论寻dev/video%d,目录下的video设备节点,并依次打开这些设备节点,打开成功后通过ioctl系统调用的VIDIOC_QUERYCAP命令获取v4l2_capability数据内容,并通过strstr查看capability.driver中的设备类型:rkisp,cif,UVC。然后在各个设备类型下面使用ioctl的VIDIOC_ENUMINPUT获取v4l2_input的数据内容。
1
2
3
4
5
6
7
8
9snprintf(video_dev_path, sizeof(video_dev_path), "/dev/video%d", i); fd = open(video_dev_path, O_RDONLY); ioctl(fd, VIDIOC_QUERYCAP, &capability) if (strstr((char*)(capability.driver), "rkisp")) ioctl(fd, VIDIOC_ENUMINPUT, &input) else if (strstr((char*)(capability.driver), "cif")) ioctl(fd, VIDIOC_ENUMINPUT, &input) else if (strstr((char*)(capability.driver), "UVC")) ioctl(fd, VIDIOC_ENUMINPUT, &input)
只有通过上上面的调用CamHwItf::getCameraInfos(struct rk_cams_dev_info* cam_infos),以及之后调用的initrec函数的api_video_init接口初始化摄像头在飞机的的空中端口接受到拍照指令后执行的 video_record_takephoto(unsigned int num)中video_cur = getfastvideo();才会有相应的video设备节点返回。
其中api_video_init进有一次调用就是在初始化的时候,并且此时是设置为VIDEO_MODE_REC模式的,如果在初始化的时候这个地方被设置成VIDEO_MODE_PHOTO模式,拍摄的图片就会偏暗。如下图所示:
/home/highgreat-xyw2018/Documents/share-2018xyw/aa/20160121_090346_picture124A00.jpg
获取支持的camera的类型,cif isp usb,支持的个数
thermal_init();
soc的温度检测功能的初始化
usb_reg_event_callback(usb_event_callback);
这里注册的回调函数是执行在链表msg_list_manager.c中的g_listHead上的回调函数。
uevent_monitor_run();
建立监控线程,主要监控内核发送到应用层的消息,设计到netlink的使用。
REC_RegEventCallback(record_event_callback);
1
2
3
4
5
6
7
8
9
10
11
12void record_event_callback(int cmd, void *msg0, void *msg1) { switch (cmd) { case CMD_UPDATETIME: api_send_msg(MSG_VIDEO_UPDATETIME, TYPE_BROADCAST, msg0, NULL); break; break; case CMD_PHOTOEND: api_send_msg(MSG_VIDEO_PHOTO_END, TYPE_BROADCAST, msg0, msg1); break; } }
api_send_msg:执行在链表msg_list_manager.c中的g_listHead上的回调函数。
set_video_init_complete_cb(notify_videos_inited);
1
2
3
4
5
6static void notify_videos_inited(int is_record_mode) { int mode = is_record_mode ? MODE_RECORDING : MODE_PHOTO; assert(mode == cur_mode); api_send_msg(MSG_MODE_CHANGE_NOTIFY, TYPE_WIFI, (void *)pre_mode, (void *)mode); }
sd_reg_event_callback(sd_event_callback);
sd卡改变的时候,需要做的一些sd卡的挂载,初始化等操作。
USER_RegEventCallback(user_event_callback);
user_event_callback回调函数的作用处理用户事件的回调。
VIDEOPLAY_RegEventCallback(videoplay_event_callback);
videoplay_event_callback回调函数的视频播放的推出和更新。
fs_msg_file_reg_callback(fsfile_event_callbak);
fsfile_event_callbak:处理文件系统的事件
storage_setting_reg_event_callback(storage_setting_callback);
storage_setting_callback:设置文件的大小和路径。
wifi_management_start:
代码流程:
1
2
3
4
5
6
7wifi_management_start Set_CPUSerial_forSSID()//obtain ssid from cpu Set_system_Version_param();//set version param reg_msg_manager_cb();//register the function of callback wifi_msg_manager_cb in the file wifi_setting_interface.c -------msg_list_manager.c g_listHead wifi_driver_reboot_thread();// parameter_getwifiinfo(SSID, PASSWD);//get wifi ssid and passwd socket_thread_create();
这里比较重要的是socket_thread_create(void),主要是建立了几个线程。
下面主要分析此函数:
建立的线程:udp_server_thread,hg_cgi_request_thread,hg_cgi_response_thread,daemon_thread。
下面依次分析:
udp_server_thread:创建端口号为8888的udp服务端用于接收手机app发送的消息,并且解析消息中的数据数据帧,根据消息的数据帧的id调用对应的命令执行函数。
1.建立udp服务器端口号8888---创建socket udp_server_fd,bind udp sockaddr
2.创建线程UdpSend_Thread---调用hg_api_send_udp_response向app发送心跳包(1s的频率)和温度信息(10s的频率)
1
2
3
4hg_api_send_udp_response SendResultMessage(messageID, messageFlag, messageLength);//the function organizes the information to be sent sendto(udp_server_fd, GetMessageBuff(), 31*sizeof(char), 0, (struct sockaddr *)&server_add, sizeof(server_add));//send info to app memset(GetMessageBuff(), 0, sizeof(char)*1024);
3.recvMsg(udp_server_fd, data, recbytes);----从接收到的数据消息中解析出具体的完整的信息帧以0x7e 0x7e开头的,并解析出信息帧中的命令参数等信息。
1
2
3recvMsg(int nfp, char *data, int recbytes) hg_parameter_resolve(buffer); cmd_resolve(nfp, buffer);
hg_parameter_resolve(buffer);
解析出接受到的消息帧buffer中的messageBodyID,根据messageBodyID的不同作出不同的判断,如:录像的打开关闭,实时视频的开始结束,拍照模式的设置,,曝光,白平衡以及adb msc模式的切换的命令等等。完成后再将相对应的命令的字符串copy到buffer中。
cmd_resolve(nfp, buffer);
将上面的函数hg_parameter_resolve(buffer);解析出来的命令字符串
cmd_resolve(nfp, buffer);
具体代码如下所示,主要是根据参数cmdstr命令字符串和命令执行函数的对照表cmd_tab作出对比,并调用相应的命令函数执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22static int cmd_resolve(int fd, char *cmdstr) { size_t i = 0; for (i = 0; i < sizeof(cmd_tab) / sizeof(cmd_tab[1]); i++) { char *result = strstr(cmdstr, CMD_PREFIX); if (result != NULL) { size_t cmdlen = strlen(cmd_tab[i].cmd); if (strncmp(result, cmd_tab[i].cmd, cmdlen) == 0) { if (cmd_tab[i].func != NULL) cmd_tab[i].func(fd, result); cmdstr = result + cmdlen; if (*cmdstr == '' || strstr(cmdstr, CMD_PREFIX) == NULL) return 0; printf("handle continuous cmd: %sn", cmdstr); i = 0; } } } return -1; }
当地面端手机app wifi链接上飞机后,app就会向飞机发送消息,会执行tcp_func_start_rtsp_live回调函数,执行rtsp实时视频的传输。
hg_cgi_request_thread hg_cgi_response_thread
以上两个线程通过管道文件/tmp/media_response_fifo相互交换数据。涉及到一些http的使用
daemon_thread
这个线程中主要是一直轮讯是否有8888端口的udp链接存在,也就是 udp_server_thread 创建的socket udp的链接是否断开,如果断开则删除udp_server_thread线程,并继续从新创建udp_server_thread线程函数。具体代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19static void *daemon_thread(void *arg) { pthread_detach(pthread_self()); while(true){ if (false == is_video_port_used()) { printf("%s %s %d bebugn", __FILE__, __FUNCTION__, __LINE__); pthread_cancel(udp_server_tid); //delete the thread udp_server_thread pthread_join(udp_server_tid,NULL);//wait thread udp_server_thread exit if (pthread_create(&udp_server_tid, NULL, udp_server_thread, NULL) != 0)//从新创建线程udp_server_thread printf("Createthread error!n"); sleep(2); } } return NULL; }
其中判断相应的udp是否处于链接状态的代码如下:通过执行netstat命令,可以查看当前的网络链接状态信息然后,将输出的信息重定位到一个文件中,然后调用strstr函数,查看是否有相应的端口号,就知道是否还处于链接状态。
1
2
3
4system("busybox rm /tmp/netstat8888.txt"); system("busybox netstat -an |grep -i 8888 > /tmp/netstat8888.txt");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20busybox netstat -an Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:554 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:5037 0.0.0.0:* LISTEN tcp 0 0 0.0.0.0:12346 0.0.0.0:* LISTEN udp 0 0 0.0.0.0:9000 0.0.0.0:* udp 0 0 0.0.0.0:67 0.0.0.0:* udp 0 0 0.0.0.0:8888 0.0.0.0:* Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node Path unix 2 [ ACC ] STREAM LISTENING 3518 @jdwp-control unix 2 [ ] DGRAM 3578 /var/run/hostapd/wlan0 unix 3 [ ] STREAM CONNECTED 3519 unix 3 [ ] STREAM CONNECTED 3523 unix 2 [ ] DGRAM 3456 unix 3 [ ] STREAM CONNECTED 3516 unix 3 [ ] STREAM CONNECTED 3520 unix 3 [ ] STREAM CONNECTED 3515 unix 3 [ ] STREAM CONNECTED 3524
最后
以上就是迷你眼神最近收集整理的关于rv1108 sdk app层上电初始化流程的全部内容,更多相关rv1108内容请搜索靠谱客的其他文章。
发表评论 取消回复