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 OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
20 * @brief System module
22 * @see The GNU Public License (GPL) Version 3
24 *****************************************************************************/
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License as published by
28 * the Free Software Foundation; either version 3 of the License, or
29 * (at your option) any later version.
31 * This program is distributed in the hope that it will be useful, but
32 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36 * You should have received a copy of the GNU General Public License along
37 * with this program; if not, write to the Free Software Foundation, Inc.,
38 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
43 #include <uavobjectmanager.h>
44 #include <openpilot.h>
46 #include <oplinkstatus.h>
49 #include <pios_rfm22b.h>
50 #include <pios_board_info.h>
53 #define SYSTEM_UPDATE_PERIOD_MS 1000
55 #if defined(PIOS_SYSTEM_STACK_SIZE)
56 #define STACK_SIZE_BYTES PIOS_SYSTEM_STACK_SIZE
58 #define STACK_SIZE_BYTES 924
61 #define TASK_PRIORITY (tskIDLE_PRIORITY + 2)
66 static xTaskHandle systemTaskHandle
;
67 static bool stackOverflow
;
68 static bool mallocFailed
;
69 volatile int initTaskDone
= 0;
72 static void systemTask(void *parameters
);
75 * Create the module task.
76 * \returns 0 on success or -1 if initialization failed
78 int32_t OPLinkModStart(void)
81 stackOverflow
= false;
83 // Create oplink system task
84 xTaskCreate(systemTask
, "OPLink", STACK_SIZE_BYTES
/ 4, NULL
, TASK_PRIORITY
, &systemTaskHandle
);
86 PIOS_TASK_MONITOR_RegisterTask(TASKINFO_RUNNING_SYSTEM
, systemTaskHandle
);
92 * Initialize the module, called on startup.
93 * \returns 0 on success or -1 if initialization failed
95 int32_t OPLinkModInitialize(void)
97 // Must registers objects here for system thread because ObjectManager started in OpenPilotInit
99 // Call the module start function.
105 MODULE_INITCALL(OPLinkModInitialize
, 0);
108 * System task, periodically executes every SYSTEM_UPDATE_PERIOD_MS
110 static void systemTask(__attribute__((unused
)) void *parameters
)
112 portTickType lastSysTime
;
113 uint16_t prev_tx_count
= 0;
114 uint16_t prev_rx_count
= 0;
115 uint16_t prev_tx_seq
= 0;
116 uint16_t prev_rx_seq
= 0;
117 bool first_time
= true;
119 while (!initTaskDone
) {
122 /* create all modules thread */
123 MODULE_TASKCREATE_ALL
;
125 /* start the delayed callback scheduler */
126 PIOS_CALLBACKSCHEDULER_Start();
129 /* We failed to malloc during task creation,
130 * system behaviour is undefined. Reset and let
131 * the BootFault code recover for us.
137 lastSysTime
= xTaskGetTickCount();
141 // Flash the heartbeat LED
142 #if defined(PIOS_LED_HEARTBEAT)
143 PIOS_LED_Toggle(PIOS_LED_HEARTBEAT
);
144 #endif /* PIOS_LED_HEARTBEAT */
146 // Update the OPLinkStatus UAVO
147 OPLinkStatusData oplinkStatus
;
148 OPLinkStatusGet(&oplinkStatus
);
150 // Get the other device stats.
151 PIOS_RFM22B_GetPairStats(pios_rfm22b_id
, oplinkStatus
.PairIDs
, oplinkStatus
.PairSignalStrengths
, OPLINKSTATUS_PAIRIDS_NUMELEM
);
153 // Get the stats from the radio device
154 struct rfm22b_stats radio_stats
;
155 PIOS_RFM22B_GetStats(pios_rfm22b_id
, &radio_stats
);
157 if (pios_rfm22b_id
) {
159 oplinkStatus
.HeapRemaining
= xPortGetFreeHeapSize();
160 oplinkStatus
.DeviceID
= PIOS_RFM22B_DeviceID(pios_rfm22b_id
);
161 oplinkStatus
.RxGood
= radio_stats
.rx_good
;
162 oplinkStatus
.RxCorrected
= radio_stats
.rx_corrected
;
163 oplinkStatus
.RxErrors
= radio_stats
.rx_error
;
164 oplinkStatus
.RxMissed
= radio_stats
.rx_missed
;
165 oplinkStatus
.RxFailure
= radio_stats
.rx_failure
;
166 oplinkStatus
.TxDropped
= radio_stats
.tx_dropped
;
167 oplinkStatus
.TxFailure
= radio_stats
.tx_failure
;
168 oplinkStatus
.Resets
= radio_stats
.resets
;
169 oplinkStatus
.Timeouts
= radio_stats
.timeouts
;
170 oplinkStatus
.RSSI
= radio_stats
.rssi
;
171 oplinkStatus
.LinkQuality
= radio_stats
.link_quality
;
175 uint16_t tx_count
= radio_stats
.tx_byte_count
;
176 uint16_t rx_count
= radio_stats
.rx_byte_count
;
177 uint16_t tx_packets
= radio_stats
.tx_seq
- prev_tx_seq
;
178 uint16_t rx_packets
= radio_stats
.rx_seq
- prev_rx_seq
;
179 uint16_t tx_bytes
= (tx_count
< prev_tx_count
) ? (0xffff - prev_tx_count
+ tx_count
) : (tx_count
- prev_tx_count
);
180 uint16_t rx_bytes
= (rx_count
< prev_rx_count
) ? (0xffff - prev_rx_count
+ rx_count
) : (rx_count
- prev_rx_count
);
181 oplinkStatus
.TXRate
= (uint16_t)((float)(tx_bytes
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
182 oplinkStatus
.RXRate
= (uint16_t)((float)(rx_bytes
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
183 oplinkStatus
.TXPacketRate
= (uint16_t)((float)(tx_packets
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
184 oplinkStatus
.RXPacketRate
= (uint16_t)((float)(rx_packets
* 1000) / SYSTEM_UPDATE_PERIOD_MS
);
185 prev_tx_count
= tx_count
;
186 prev_rx_count
= rx_count
;
187 prev_tx_seq
= radio_stats
.tx_seq
;
188 prev_rx_seq
= radio_stats
.rx_seq
;
190 oplinkStatus
.TXSeq
= radio_stats
.tx_seq
;
191 oplinkStatus
.RXSeq
= radio_stats
.rx_seq
;
192 oplinkStatus
.LinkState
= radio_stats
.link_state
;
194 oplinkStatus
.LinkState
= OPLINKSTATUS_LINKSTATE_DISABLED
;
197 if (radio_stats
.link_state
== OPLINKSTATUS_LINKSTATE_CONNECTED
) {
204 OPLinkStatusSet(&oplinkStatus
);
206 // Wait until next period
207 vTaskDelayUntil(&lastSysTime
, SYSTEM_UPDATE_PERIOD_MS
/ portTICK_RATE_MS
);
212 * Called by the RTOS when the CPU is idle, used to measure the CPU idle time.
214 void vApplicationIdleHook(void)
218 * Called by the RTOS when a stack overflow is detected.
220 #define DEBUG_STACK_OVERFLOW 0
221 void vApplicationStackOverflowHook(__attribute__((unused
)) xTaskHandle
*pxTask
,
222 __attribute__((unused
)) signed portCHAR
*pcTaskName
)
224 stackOverflow
= true;
225 #if DEBUG_STACK_OVERFLOW
226 static volatile bool wait_here
= true;
235 * Called by the RTOS when a malloc call fails.
237 #define DEBUG_MALLOC_FAILURES 0
238 void vApplicationMallocFailedHook(void)
241 #if DEBUG_MALLOC_FAILURES
242 static volatile bool wait_here
= true;