2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
4 * @brief The OpenPilot Modules do the majority of the control in OpenPilot. The
5 * @ref OPLinkModule The OPLink Module is the equivalanet of the System
6 * Module for the OPLink modem. it starts all the other modules.
7 # This is done through the @ref PIOS "PIOS Hardware abstraction layer",
8 # which then contains hardware specific implementations
9 * (currently only STM32 supported)
12 * @addtogroup OPLinkModule OPLink Module
13 * @brief Initializes PIOS and other modules runs monitoring
14 * After initializing all the modules runs basic monitoring and
19 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
20 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
21 * @brief System module
23 * @see The GNU Public License (GPL) Version 3
25 *****************************************************************************/
27 * This program is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published by
29 * the Free Software Foundation; either version 3 of the License, or
30 * (at your option) any later version.
32 * This program is distributed in the hope that it will be useful, but
33 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37 * You should have received a copy of the GNU General Public License along
38 * with this program; if not, write to the Free Software Foundation, Inc.,
39 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
44 #include <uavobjectmanager.h>
45 #include <openpilot.h>
47 #include <oplinkstatus.h>
50 #include <pios_rfm22b.h>
51 #include <pios_board_info.h>
54 #define SYSTEM_UPDATE_PERIOD_MS 1000
56 #if defined(PIOS_SYSTEM_STACK_SIZE)
57 #define STACK_SIZE_BYTES PIOS_SYSTEM_STACK_SIZE
59 #define STACK_SIZE_BYTES 924
62 #define TASK_PRIORITY (tskIDLE_PRIORITY + 2)
67 static xTaskHandle systemTaskHandle
;
68 static bool stackOverflow
;
69 static bool mallocFailed
;
70 volatile int initTaskDone
= 0;
71 static uint8_t previousRFXtalCap
;
74 static void systemTask(void *parameters
);
75 static void oplinkSettingsUpdatedCb(UAVObjEvent
*ev
);
78 * Create the module task.
79 * \returns 0 on success or -1 if initialization failed
81 int32_t OPLinkModStart(void)
84 stackOverflow
= false;
86 // Create oplink system task
87 xTaskCreate(systemTask
, "OPLink", STACK_SIZE_BYTES
/ 4, NULL
, TASK_PRIORITY
, &systemTaskHandle
);
89 PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM
, systemTaskHandle
);
95 * Initialize the module, called on startup.
96 * \returns 0 on success or -1 if initialization failed
98 int32_t OPLinkModInitialize(void)
100 // Must registers objects here for system thread because ObjectManager started in OpenPilotInit
102 // Call the module start function.
108 MODULE_INITCALL(OPLinkModInitialize
, 0);
111 * System task, periodically executes every SYSTEM_UPDATE_PERIOD_MS
113 static void systemTask(__attribute__((unused
)) void *parameters
)
115 portTickType lastSysTime
;
116 uint16_t prev_tx_count
= 0;
117 uint16_t prev_rx_count
= 0;
118 uint16_t prev_tx_seq
= 0;
119 uint16_t prev_rx_seq
= 0;
120 bool first_time
= true;
122 while (!initTaskDone
) {
125 /* create all modules thread */
126 MODULE_TASKCREATE_ALL
;
128 /* start the delayed callback scheduler */
129 PIOS_CALLBACKSCHEDULER_Start();
132 /* We failed to malloc during task creation,
133 * system behaviour is undefined. Reset and let
134 * the BootFault code recover for us.
139 // Initialize previousRFXtalCap used by callback
140 OPLinkSettingsRFXtalCapGet(&previousRFXtalCap
);
141 OPLinkSettingsConnectCallback(oplinkSettingsUpdatedCb
);
144 lastSysTime
= xTaskGetTickCount();
148 // Update the OPLinkStatus UAVO
149 OPLinkStatusData oplinkStatus
;
150 OPLinkStatusGet(&oplinkStatus
);
152 // Get the other device stats.
153 PIOS_RFM22B_GetPairStats(pios_rfm22b_id
, oplinkStatus
.PairIDs
, oplinkStatus
.PairSignalStrengths
, OPLINKSTATUS_PAIRIDS_NUMELEM
);
155 // Get the stats from the radio device
156 struct rfm22b_stats radio_stats
;
157 PIOS_RFM22B_GetStats(pios_rfm22b_id
, &radio_stats
);
158 oplinkStatus
.HeapRemaining
= xPortGetFreeHeapSize();
160 if (pios_rfm22b_id
) {
162 oplinkStatus
.DeviceID
= PIOS_RFM22B_DeviceID(pios_rfm22b_id
);
163 oplinkStatus
.RxGood
= radio_stats
.rx_good
;
164 oplinkStatus
.RxCorrected
= radio_stats
.rx_corrected
;
165 oplinkStatus
.RxErrors
= radio_stats
.rx_error
;
166 oplinkStatus
.RxMissed
= radio_stats
.rx_missed
;
167 oplinkStatus
.RxFailure
= radio_stats
.rx_failure
;
168 oplinkStatus
.TxDropped
= radio_stats
.tx_dropped
;
169 oplinkStatus
.TxFailure
= radio_stats
.tx_failure
;
170 oplinkStatus
.Resets
= radio_stats
.resets
;
171 oplinkStatus
.Timeouts
= radio_stats
.timeouts
;
172 oplinkStatus
.RSSI
= radio_stats
.rssi
;
173 oplinkStatus
.LinkQuality
= radio_stats
.link_quality
;
174 oplinkStatus
.AFCCorrection
= radio_stats
.afc_correction
;
178 uint16_t tx_count
= radio_stats
.tx_byte_count
;
179 uint16_t rx_count
= radio_stats
.rx_byte_count
;
180 uint16_t tx_packets
= radio_stats
.tx_seq
- prev_tx_seq
;
181 uint16_t rx_packets
= radio_stats
.rx_seq
- prev_rx_seq
;
182 uint16_t tx_bytes
= (tx_count
< prev_tx_count
) ? (0xffff - prev_tx_count
+ tx_count
) : (tx_count
- prev_tx_count
);
183 uint16_t rx_bytes
= (rx_count
< prev_rx_count
) ? (0xffff - prev_rx_count
+ rx_count
) : (rx_count
- prev_rx_count
);
184 oplinkStatus
.TXRate
= (uint16_t)((float)(tx_bytes
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
185 oplinkStatus
.RXRate
= (uint16_t)((float)(rx_bytes
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
186 oplinkStatus
.TXPacketRate
= (uint16_t)((float)(tx_packets
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
187 oplinkStatus
.RXPacketRate
= (uint16_t)((float)(rx_packets
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
188 prev_tx_count
= tx_count
;
189 prev_rx_count
= rx_count
;
190 prev_tx_seq
= radio_stats
.tx_seq
;
191 prev_rx_seq
= radio_stats
.rx_seq
;
193 oplinkStatus
.TXSeq
= radio_stats
.tx_seq
;
194 oplinkStatus
.RXSeq
= radio_stats
.rx_seq
;
195 oplinkStatus
.LinkState
= radio_stats
.link_state
;
198 // Turn on the link/heartbeat ID if we're connected, otherwise flash it.
199 if (radio_stats
.link_state
== OPLINKSTATUS_LINKSTATE_CONNECTED
) {
206 OPLinkStatusSet(&oplinkStatus
);
208 // Wait until next period
209 vTaskDelayUntil(&lastSysTime
, SYSTEM_UPDATE_PERIOD_MS
/ portTICK_RATE_MS
);
214 * Called by the RTOS when the CPU is idle, used to measure the CPU idle time.
216 void vApplicationIdleHook(void)
220 * Called by the RTOS when a stack overflow is detected.
222 #define DEBUG_STACK_OVERFLOW 0
223 void vApplicationStackOverflowHook(__attribute__((unused
)) xTaskHandle
*pxTask
,
224 __attribute__((unused
)) signed portCHAR
*pcTaskName
)
226 stackOverflow
= true;
227 #if DEBUG_STACK_OVERFLOW
228 static volatile bool wait_here
= true;
237 * Called by the RTOS when a malloc call fails.
239 #define DEBUG_MALLOC_FAILURES 0
240 void vApplicationMallocFailedHook(void)
243 #if DEBUG_MALLOC_FAILURES
244 static volatile bool wait_here
= true;
253 * Called whenever OPLink settings changed
255 static void oplinkSettingsUpdatedCb(__attribute__((unused
)) UAVObjEvent
*ev
)
257 uint8_t currentRFXtalCap
;
259 OPLinkSettingsRFXtalCapGet(¤tRFXtalCap
);
261 // Check if RFXtalCap value changed
262 if (currentRFXtalCap
!= previousRFXtalCap
) {
263 PIOS_RFM22B_SetXtalCap(pios_rfm22b_id
, currentRFXtalCap
);
264 PIOS_RFM22B_Reinit(pios_rfm22b_id
);
265 previousRFXtalCap
= currentRFXtalCap
;