реклама на сайте
подробности

 
 
> Измерение Загрузки CPU, ARM7, lpc2367
whiteTigr
сообщение Aug 10 2011, 09:36
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 25-07-11
Пользователь №: 66 407



Захотел сделать измерение загрузки CPU.
Основная программа построена на прерываниях и работает с несколькими кнопками, сегментным индикатором и ком-портом.

Идея состоит в том, чтобы при начале любой (более-менее серъезной) процедуры стояло слово ImWorking, и заканчивалась процедура словом ImFinished.
Измеритель по этим словам выставляет тестовый диодик и считает сколько времени этот диодик простоял в высоком уровне (TimeInHighLevel).
Таймер в измерителе выдает прерывание раз в секунду, по которому значение TimeInHighLevel переписывается в буфер, доступный основной программе.

Вроде бы все получилось, но загрузка CPU, измеренная осцилографом, отличается от загрузки, измереной этим модулем.
Без оптимизации по осцилографу получается порядка 23% загрузки, модулем 24%. (вроде бы все нормально, списываем на погрешность)
С оптимизацией по времени выполнения получается: осцилограф - 13%, модуль 4%. (вот тут уже терзают сомнения)

И, так как я начинающий програмист, буду рад критике этого кода. sm.gif

Код
#include <LPC23xx.h>
#include "SystemMonitor.h"

// диодик
#define Work (1 << 1) // @ 1

#define PCTIM3  0x00800000; // 23

#define PCLK_TIMER3_OFFSET 14 // @ 1

#define INTTIM3 (1 << 27)

void Work_SET() { IOSET1 = Work; }
void Work_CLR() { IOCLR1 = Work; }

short WorkRefs = 0;

unsigned short CPUUsage = 0;

int TimeInHighLevel = 0;
int TimeSetHighLevel = 0;

__irq void Timer3Handler()
{
  if (WorkRefs > 0)  
    TimeInHighLevel += 10000 - TimeSetHighLevel;  

  CPUUsage = TimeInHighLevel;
  TimeInHighLevel = 0;
  TimeSetHighLevel = 0;

  T3IR = 0x01;
  VICVectAddr = 0;  
}

void InitSystemMonitor()
{
  TimeInHighLevel = 0;
  WorkRefs = 0;

  /* Initialize Timer 3 */  
  PCONP |= PCTIM3;

  PCLKSEL1 &= ~(3 << PCLK_TIMER3_OFFSET);
  PCLKSEL1 |=  (1 << PCLK_TIMER3_OFFSET);

  T3PR = 6399; // 100 mks  
  T3MR0 = 9999; // 1 s
  T3MCR = 3;

  VICIntEnClr = INTTIM3;
  VICVectAddr27 = (unsigned long)Timer3Handler;
  VICVectPriority27 = 15;  
  

  T3TCR = 0x01;

  VICIntEnable += INTTIM3;
}

void ImWorking()
{
  WorkRefs++;
  
  if (WorkRefs == 1)
  {
    Work_SET();
    TimeSetHighLevel = T3TC;
  }
}

void ImFinished()
{
  if (WorkRefs > 0)
    WorkRefs--;

  if (WorkRefs == 0)
  {
    TimeInHighLevel += T3TC - TimeSetHighLevel;
    Work_CLR();
  }
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
toweroff
сообщение Aug 11 2011, 09:52
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



после
Код
VICIntEnClr = INTTIM3;

прерывание от таймера НЕ произойдет, посему присвоение значения переменной выполнится атомарно
после этого прерывание снова разрешается, но мавр дело уже сделал sm.gif
Если флаг прерывания выставлен во время операции присвоения, то после разрешения прерывания автоматом попадаем в обработку прерывания
Go to the top of the page
 
+Quote Post
whiteTigr
сообщение Aug 11 2011, 12:20
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 55
Регистрация: 25-07-11
Пользователь №: 66 407



Цитата(toweroff @ Aug 11 2011, 13:52) *
Если флаг прерывания выставлен во время операции присвоения, то после разрешения прерывания автоматом попадаем в обработку прерывания


Спасибо. sm.gif
Кажется, я стал немножко больше понимать механизмы работы arm'а.
А то, 2 недели назад, все это было темным лесом и непонятно было с какой стороны к этому зверю подойти. sm.gif
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 04:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01398 секунд с 7
ELECTRONIX ©2004-2016