Paparazzi UAS  v5.15_devel-113-g1b57ff1
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
rtos_mon_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Gautier Hattenberger <gautier.hattenberger@enac.fr>
3  *
4  * This file is part of paparazzi
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
28 #include <ch.h>
29 
30 #if !CH_DBG_THREADS_PROFILING
31 #error CH_DBG_THREADS_PROFILING should be defined to TRUE to use this monitoring tool
32 #endif
33 
36 
37 static uint16_t get_stack_free(const thread_t *tp);
38 
40 {
41  idle_counter = 0;
43 }
44 
45 // Fill data structure
47 {
48  int i;
49  size_t total_fragments, total_fragmented_free_space, largest_free_block;
50  total_fragments = chHeapStatus(NULL, &total_fragmented_free_space, &largest_free_block);
51 
52  rtos_mon.core_free_memory = chCoreGetStatusX();
53  rtos_mon.heap_fragments = total_fragments;
54  rtos_mon.heap_largest = largest_free_block;
55  rtos_mon.heap_free_memory = total_fragmented_free_space;
57 
58  // loop threads to find idle thread
59  // store info on other threads
60  thread_t *tp;
61  float sum = 0.f;
63  tp = chRegFirstThread();
64  do {
65  // add beginning of thread name to buffer
66  for (i = 0; i < RTOS_MON_NAME_LEN-1 && tp->name[i] != '\0'; i++) {
68  }
70 
71  // store free stack for this thread
73 
74  // store time spend in thread
76  sum += (float)(tp->time);
77 
78  // if current thread is 'idle' thread, store its value separately
79  if (tp == chSysGetIdleThreadX()) {
80  idle_counter = (uint32_t)tp->time;
81  }
82  // get next thread
83  tp = chRegNextThread(tp);
84  // increment thread counter
86  } while (tp != NULL && rtos_mon.thread_counter < RTOS_MON_MAX_THREADS);
87 
88  // store individual thread load (as centi-percent integer)
89  for (i = 0; i < rtos_mon.thread_counter; i ++) {
90  rtos_mon.thread_load[i] = (uint16_t)(10000.f * (float)thread_p_time[i] / sum);
91  }
92 
93  // assume we call the counter once a second
94  // so the difference in seconds is always one
95  // NOTE: not perfectly precise, +-5% on average so take it into consideration
98 }
99 
100 static uint16_t get_stack_free(const thread_t *tp)
101 {
102 #if defined STM32F4
103  int32_t index = 0;
104  // FIXME this is for STM32F4 only
105  const uint8_t *max_ram_addr = (uint8_t*) (0x20000000 + (128*1024));
106  const int32_t internal_struct_size = (CH_KERNEL_MAJOR == 2) ? 80 : 120;
107  unsigned long long *stk_addr = (unsigned long long *) ((uint8_t *)tp + internal_struct_size);
108 
109  while ((stk_addr[index] == 0x5555555555555555) && (((uint8_t *) &(stk_addr[index])) < max_ram_addr))
110  index++;
111 
112  const int32_t free_bytes = (index * (int32_t)sizeof(long long)) - internal_struct_size;
113  uint16_t ret;
114  if (free_bytes < 0) {
115  // stack overflow ?
116  ret = 0;
117  } else if (free_bytes > 0xFFFF) {
118  // return value in Kbytes
119  ret = (uint16_t) (free_bytes / 1024);
120  } else {
121  // return value in bytes
122  ret = (uint16_t) free_bytes;
123  }
124  return ret;
125 #else
126  (void)tp;
127  return 0;
128 #endif
129 }
130 
unsigned short uint16_t
Definition: types.h:16
static uint16_t get_stack_free(const thread_t *tp)
#define RTOS_MON_NAME_LEN
Definition: sys_mon_rtos.h:40
uint16_t thread_load[RTOS_MON_MAX_THREADS]
individual thread load in centi-percent (10*%)
Definition: sys_mon_rtos.h:53
void rtos_mon_init_arch(void)
Definition: rtos_mon_arch.c:39
static uint32_t last_idle_counter
Definition: rtos_mon_arch.c:35
void rtos_mon_periodic_arch(void)
Definition: rtos_mon_arch.c:46
struct rtos_monitoring rtos_mon
Definition: rtos_mon.c:30
#define RTOS_MON_MAX_THREADS
Definition: sys_mon_rtos.h:36
char thread_names[RTOS_MON_THREAD_NAMES+1]
string of thread names / identifiers
Definition: sys_mon_rtos.h:55
uint8_t thread_name_idx
length of the string in thread_names buffer
Definition: sys_mon_rtos.h:56
static uint32_t idle_counter
Definition: rtos_mon_arch.c:35
uint8_t cpu_load
global CPU/MCU load in %
Definition: sys_mon_rtos.h:51
unsigned long uint32_t
Definition: types.h:18
uint16_t thread_free_stack[RTOS_MON_MAX_THREADS]
individual thread free stack in bytes
Definition: sys_mon_rtos.h:54
uint8_t thread_counter
number of threads
Definition: sys_mon_rtos.h:52
uint32_t core_free_memory
core free memory in bytes
Definition: sys_mon_rtos.h:47
uint32_t heap_largest
Largest free block in the heap.
Definition: sys_mon_rtos.h:50
signed long int32_t
Definition: types.h:19
static uint32_t thread_p_time[RTOS_MON_MAX_THREADS]
Definition: rtos_mon_arch.c:34
unsigned char uint8_t
Definition: types.h:14
uint32_t heap_free_memory
Total fragmented free memory in the heap.
Definition: sys_mon_rtos.h:48
uint32_t heap_fragments
Number of fragments in the heap.
Definition: sys_mon_rtos.h:49
#define CH_CFG_ST_FREQUENCY
System tick frequency.
Definition: chconf.h:52
System monitoring for RTOS targets return cpu load, average exec time, ...