Paparazzi UAS  v5.10_stable-5-g83a0da5-dirty
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 
50  rtos_mon.core_free_memory = chCoreGetStatusX();
53 
54  // loop threads to find idle thread
55  // store info on other threads
56  thread_t *tp;
57  float sum = 0.f;
59  tp = chRegFirstThread();
60  do {
61  // add beginning of thread name to buffer
62  for (i = 0; i < RTOS_MON_NAME_LEN-1 && tp->p_name[i] != '\0'; i++) {
63  rtos_mon.thread_names[rtos_mon.thread_name_idx++] = tp->p_name[i];
64  }
66 
67  // store free stack for this thread
69 
70  // store time spend in thread
72  sum += (float)(tp->p_time);
73 
74  // if current thread is 'idle' thread, store its value separately
75  if (tp == chSysGetIdleThreadX()) {
76  idle_counter = (uint32_t)tp->p_time;
77  }
78  // get next thread
79  tp = chRegNextThread(tp);
80  // increment thread counter
82  } while (tp != NULL && rtos_mon.thread_counter < RTOS_MON_MAX_THREADS);
83 
84  // store individual thread load (as centi-percent integer)
85  for (i = 0; i < rtos_mon.thread_counter; i ++) {
86  rtos_mon.thread_load[i] = (uint16_t)(10000.f * (float)thread_p_time[i] / sum);
87  }
88 
89  // assume we call the counter once a second
90  // so the difference in seconds is always one
91  // NOTE: not perfectly precise, +-5% on average so take it into consideration
94 }
95 
96 static uint16_t get_stack_free(const thread_t *tp)
97 {
98 #if defined STM32F4
99  int32_t index = 0;
100  // FIXME this is for STM32F4 only
101  const uint8_t *max_ram_addr = (uint8_t*) (0x20000000 + (128*1024));
102  const int32_t internal_struct_size = (CH_KERNEL_MAJOR == 2) ? 80 : 120;
103  unsigned long long *stk_addr = (unsigned long long *) ((uint8_t *)tp + internal_struct_size);
104 
105  while ((stk_addr[index] == 0x5555555555555555) && (((uint8_t *) &(stk_addr[index])) < max_ram_addr))
106  index++;
107 
108  const int32_t free_bytes = (index * (int32_t)sizeof(long long)) - internal_struct_size;
109  uint16_t ret;
110  if (free_bytes < 0) {
111  // stack overflow ?
112  ret = 0;
113  } else if (free_bytes > 0xFFFF) {
114  // return value in Kbytes
115  ret = (uint16_t) (free_bytes / 1024);
116  } else {
117  // return value in bytes
118  ret = (uint16_t) free_bytes;
119  }
120  return ret;
121 #else
122  (void)tp;
123  return 0;
124 #endif
125 }
126 
unsigned short uint16_t
Definition: types.h:16
static uint16_t get_stack_free(const thread_t *tp)
Definition: rtos_mon_arch.c:96
#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:51
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:53
uint8_t thread_name_idx
length of the string in thread_names buffer
Definition: sys_mon_rtos.h:54
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:49
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:52
uint8_t thread_counter
number of threads
Definition: sys_mon_rtos.h:50
uint32_t core_free_memory
core free memory in bytes
Definition: sys_mon_rtos.h:47
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
heap free memory in bytes
Definition: sys_mon_rtos.h:48
#define CH_CFG_ST_FREQUENCY
System tick frequency.
Definition: chconf.h:49
System monitoring for RTOS targets return cpu load, average exec time, ...