Перейти к содержанию
    

Вычисление загрузки ЦПУ на stm32h7

38 minutes ago, jcxz said:

Сомневаюсь, что в режиме ожидания, он DRAM в self-refresh переводит. Хотя, всё возможно конечно....

Современные мобильники набиты таким количеством свистоперделок, что без агрессивного управления питанием никак. Переводит, а если возможно, то и PASR задействует, чтобы еще пуще осётра урезать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 hours ago, jcxz said:

Зачем? Вы его купите и дизассемблируете? :biggrin: Так не получится - прошивка закрыта.


Я поверю вам на слово если вы принимали участие в его разработке.

23 hours ago, aaarrr said:

 

Для случая ARMv7, например, в конечном счете будет вызвана:

https://elixir.bootlin.com/linux/v5.6.13/source/arch/arm/mm/proc-v7.S#L75

Вполне себе сон.

Но если нужно неделю прожить на аккумуляторе, то без полноценного отключения CPU и перевода RAM в self-refresh не обойтись.

LG Crystal  и Viewity на полную мощность процессора на сотнях мегагерц (10 лет назад было дело точно не помню) жрал немеряно, но на 6 мегагерцах какие-то слезы. От той батарейки на 6 мегагерцах он пару недель бы работал.

 

 

Для случая ARMv7, например, в конечном счете будет вызвана cpu_v7_do_idle или  cpu_pj4b_do_idle

Но я что-то не нашел где она вызывается. Несколько еще имен определены для нее, но ни одно не используется.

Или я просмотрел что-то?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 hours ago, Tarbal said:

Или я просмотрел что-то?

Напрямую не находится, потому что подставляется макросом, формирующим имя из названия архитектуры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 hours ago, aaarrr said:

Напрямую не находится, потому что подставляется макросом, формирующим имя из названия архитектуры.

А этот макрос не в исходниках что ли?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

15 minutes ago, aaarrr said:

Разумеется, в исходниках.

Вроде здесь все упоминания этой функции:
https://elixir.bootlin.com/linux/v5.6.13/C/ident/cpu_v7_do_idle

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, aaarrr said:

Ну вот первый пример навскидку
 

/*
 * cpu_arm7tdmi_proc_init()
 * cpu_arm7tdmi_do_idle()
 * cpu_arm7tdmi_dcache_clean_area()
 * cpu_arm7tdmi_switch_mm()
 *
 * These are not required.
 */
ENTRY(cpu_arm7tdmi_proc_init)
ENTRY(cpu_arm7tdmi_do_idle)
ENTRY(cpu_arm7tdmi_dcache_clean_area)
ENTRY(cpu_arm7tdmi_switch_mm)
		ret	lr

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 minutes ago, Tarbal said:

Ну вот первый пример навскидку

И что же этот пример должен показать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я вставил в "while(1)" код:

Скрытый текст

		for(uint32_t i = 0; i < 0xfffffff; i++){
			asm("nop");
		}


		static uint32_t wtim = 0, // work  time
		                stim = 0, // sleep time
		                ltim = 0; // last  time

		int16_t cpuProcent = 0;

		__disable_irq();
		uint32_t prev = DWT->CYCCNT;
		__WFI();
		uint32_t next = DWT->CYCCNT;
		__enable_irq();

		wtim += prev - ltim;
		stim += next - prev;
		ltim  = next;

		cpuProcent = (float)wtim/(float)(stim + wtim) * 100;

 

У меня всегда процент загрузки 99 или 100 %. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скрытый текст
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
*    Keil project for very basic and primitive CPU load monitor
*
*    Before you start, select your target, on the right of the "Load" button
*
*    @author        Tilen Majerle
*    @email        [email protected]
*    @website    http://stm32f4-discovery.net
*    @ide        Keil uVision 5
*    @conf        PLL parameters are set in "Options for Target" -> "C/C++" -> "Defines"
*    @packs        STM32F4xx Keil packs version 2.4.0 or greater required
*    @stdperiph    STM32F4xx Standard peripheral drivers version 1.5.0 or greater required
*/
/* Include core modules */
#include "stm32f4xx.h"
/* Include my libraries here */
#include "defines.h"
#include "tm_stm32f4_delay.h"
#include "tm_stm32f4_disco.h"
#include "tm_stm32f4_general.h"
#include "tm_stm32f4_usart.h"
 
#include "stdio.h"
 
/* Go to sleep mode */
void GoToSleepMode(void);
 
int main(void) {
    __IO uint32_t i;
    
    /* Initialize system */
    SystemInit();
    
    /* Init DWT timer to count processor cycles */
    TM_GENERAL_DWTCounterEnable();
    
    /* Reset counter */
    TM_GENERAL_DWTCounterSetValue(0);
    
    /* Initialize delay */
    TM_DELAY_Init();
    
    /* Initialize leds on board */
    TM_DISCO_LedInit();
    
    /* Initialize button */
    TM_DISCO_ButtonInit();
    
    /* Init USART2, TX: PA2, RX: PA3, 921600 baud */
    TM_USART_Init(USART2, TM_USART_PinsPack_1, 921600);
    
    while (1) {
        /* If button is pressed, do some useless dummy counting */
        /* Otherwise, go sleep directly */
        if (TM_DISCO_ButtonPressed()) {
            /* Do some while looping */
            i = 0;
            while (i++ < 0x2FFF);
        }
        
        /* Toggle leds */
        TM_DISCO_LedToggle(LED_ALL);
        
        /* Go to sleep mode */
        GoToSleepMode();
    }
}
 
void GoToSleepMode(void) {
    uint32_t t;
    static uint32_t l = 0;
    static uint32_t WorkingTime = 0;
    static uint32_t SleepingTime = 0;
    static uint32_t LastTime = 0;
 
    /* Disable interrupts */
    __disable_irq();
    
    /* Add to working time */
    WorkingTime += DWT->CYCCNT - l;
    
    /* Save count cycle time */
    t = DWT->CYCCNT;
    
    /* Go to sleep mode */
    /* Wait for wake up interrupt, systick can do it too */
    __WFI();
    
    /* Increase number of sleeping time in CPU cycles */
    SleepingTime += DWT->CYCCNT - t;
    
    /* Save current time to get number of working CPU cycles */
    l = DWT->CYCCNT;
    
    /* Enable interrupts, process/execute an interrupt routine which wake up CPU */
    __enable_irq();
    
    /* Every 1000ms print CPU load via USART */
    if ((TM_DELAY_Time() - LastTime) >= 1000) {
        /* Save new time */
        LastTime = TM_DELAY_Time();
        
        /* Print to user */
        printf("W: %u; S: %u; L: %5.2f %%\n", WorkingTime, SleepingTime, ((float)WorkingTime / (float)(SleepingTime + WorkingTime) * 100));
        
        /* Reset time */
        SleepingTime = 0;
        WorkingTime = 0;
    }
}
 
/* Handle printf functionality */
int fputc(int ch, FILE* fil) {
    /* Send character over USART */
    TM_USART_Putc(USART2, ch);
    
    /* Return character */
    return ch;
}

управление потребляемой мощностью в сложных устройствах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...