OpenIPC开源FPV之Adaptive-Link天空端代码解析
1. 源由
在《OpenIPC开源FPV之Adaptive-Link工程解析》中,已经有了整个工程的大体概念,接下来再对代码进行逐步分析。
首先,对天空端的代码进行分析:ALink42n.c
2. 框架代码
ALink42n.c
相对来说,代码量最少,也是最为基本的一份代码。
目前,尚不太清楚具体n/p/q之间的差异,逻辑上看应该是关于切换配置profile
的条件计算方式不太一样,对于稳定性、可靠性方面应该有所差异。
注:感兴趣的朋友,可以跟下帖子,不过随着代码的深入了解,以及性能测试数据,也能慢慢明晰之间的差异。
2.1 消息机制
- 加载配置 - “/etc/alink.conf”
- 加载Profile - “/etc/txprofiles.conf”
- majestic:80
- wfb-cli:8000
- Terminal:bash
- 绑定默认IP - 10.5.0.10:9999
- 接受两种UDP报文:special报文和普通报文
main
├──> load_config(CONFIG_FILE); // "/etc/alink.conf"
├──> load_profiles(PROFILE_FILE); // "/etc/txprofiles.conf"
├──> bind DEFAULT_IP(10.5.0.10) DEFAULT_PORT(9999)
├──>loop recvfrom
│ ├──> <special:> special_command_message(message);
│ └──> process_message(message);
└──> close(sockfd);
2.2 超时机制
当长时间未收到报文,则进行最大功率设置。
count_messages (void *arg)
│
├──> while (1) // Infinite loop
│ ├──> usleep(fallback_ms * 1000); // Sleep for 'fallback_ms' milliseconds
│ │
│ ├──> pthread_mutex_lock(&count_mutex); // Lock the count_mutex to safely access shared data
│ │ ├── local_count = message_count; // Store current message count into local_count
│ │ ├── message_count = 0; // Reset the message count to 0
│ │ └── pthread_mutex_unlock(&count_mutex); // Unlock the count_mutex after accessing shared data
│ │
│ ├──> pthread_mutex_lock(&pause_mutex); // Lock the pause_mutex to safely check and change 'paused'
│ │ ├──> if (local_count == 0 && !paused) { // If no messages received and not paused:
│ │ │ ├──> printf("No messages received in %dms, sending 999\n", fallback_ms);
│ │ │ └──> start_selection(999, 1000); // Call start_selection with parameters 999 and 1000
│ │ ├──> else { // If messages are received or paused:
│ │ │ ├──> if (verbose_mode) { // If verbose mode is enabled:
│ │ │ │ └──> printf("Messages per %dms: %d\n", fallback_ms, local_count);
│ │ │ └──> } // End of verbose_mode check
│ │ └──> } // End of else block
│ └──> pthread_mutex_unlock(&pause_mutex); // Unlock the pause_mutex after checking 'paused' status
│
└──> return NULL; // Return NULL from the function (indicates thread termination)
3. 报文处理
+--------------+---------------+-------------+
| | special? (8B) | Msg content |
| Msg len (4B) |---------------+-------------|
| | RF Signal Estimated Values |
+--------------+---------------+-------------+
3.1 special报文
- 报文格式:
+--------------+---------------+-------------+
| Msg len (4B) | special? (8B) | Msg content |
+--------------+---------------+-------------+
- 代码流程:
处理pause_adaptive
/resume_adaptive
/request_keyframe
命令
special_command_message
├──> "pause_adaptive"
│ └──> paused = true
├──> "resume_adaptive"
│ └──> paused = false
├──> "drop_gop"
│ └──> // 已经注释掉,代码暂时保留
├──> "request_keyframe"
│ └──> < > request_keyframe_interval_ms> `idrCommand`
└──> "Unknown"
3.2 普通报文
- 报文格式:
+--------------+------------------+-----------------+----------------+-----------+------+-------+-------+---------------+
| Msg len (4B) | transmitted_time | link_value_rssi | link_value_snr | recovered | lost | rssi1 | rssi2 | rssi3 | rssi4 |
+--------------+------------