Keil'de Debug Yapma

Başlatan Mucit23, 06 Ağustos 2014, 12:21:05

Mucit23

Daha önce pek debug'la işim olmamıştı. Keide Debug Nasıl yapıldığını, Yani bir register izleme, MCU'nun donanımsal registerlerini izleme gibi olayların nasıl yapıldığını hiç bilmiyorum.

Şuanda örneğin STM32F103 üzerinde GPIO Donanımının ODR veya IDR gibi Registerleri incelemek istiyorum. Keilde debug butonuna basıyorum debug moduna giriyor.

System Viewer menüsünden GPIOB'yi seçiyorum. GPIOB nin bütün registerleri geliyor fakat hepsi sıfır. İşlemciyle bir türlü bağlantı kuramadım.
J link Klonu var. Klon PC'ye bağlı olmayınca bile aynı şekilde debug moduna giriyor keil.

Bu tür ayarları nasıl yapmam gerekiyor? Yardım ederseniz sevinirim.

X-Fi

Hocam options->debug penceresinde simulatörü değilde debugger ı seçin daha sonra setting kısmından gerekli bağlantı ayarları ve çip seçimini yapın gerçek zamanlı işlemci üzerinde debug yapabileceksiniz.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

Mucit23

Hocam teşekkürler.

Şimdi işlemciyi Debug moduna alabiliyorum. Hatta GPIO_ODR veya IDR gibi registerleri görebiliyorum.

STM32 ile 2x16 LCD çalıştırmak istiyorum. Bir türlü yapamadım.
Şuradaki başlıkta bir kütüphane verdim
https://www.picproje.org/index.php/topic,38262.msg418307.html#msg418307
O kütüphaneyi kullanıyorum ama sorun var.

Bu kütüphanede bazı noktalara breakpoint koyup programın oraya kadar gelip durmasını istiyorum. BreakPoint den sonra kendim adım adım çalıştırayım.
Bunu nasıl yaparım.

STM32 ile 2x16 LCD kullanmak için kullandığınız bir kütüphane varmı?

Mucit23

Konu Güncel, STM32 için 2x16LCD kütüphanesi arıyorum.

yamak

Hocam breakpoint  olayıında anlamadığınız tam olarak nedir?

Mucit23

Hocam break poit koyuyorum istediğim satıra. Normalde bildiğim kadarıyla debug moduna geçtiğim zaman break point koyduğum noktaya kadar programın çalışıp orda durması gerekiyor. Böyle olmuyor. Debug moduna girdiğim zaman program startup'tan başlıyor.

yamak

Hocam işlemci reset alınca direk reset vectorüne dallanır.O sebepten ilk başta program counter reset handler'ın ilk satırından başlar.Siz run derseniz (RST butonunun yanındaki buton) breakpoint'in olduğu yerde durması gerekir.Ama keil'da simülasyon debug'ta bazen sorun olabiliyor.PC breakpoint'in olduğu yere gitmeyebiliyor.

yldzelektronik

Alıntı yapılan: Mucit23 - 08 Ağustos 2014, 17:31:12
Hocam break poit koyuyorum istediğim satıra. Normalde bildiğim kadarıyla debug moduna geçtiğim zaman break point koyduğum noktaya kadar programın çalışıp orda durması gerekiyor. Böyle olmuyor. Debug moduna girdiğim zaman program startup'tan başlıyor.

Debug ayarlarında run to main check boxı var onu check et.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

Mucit23

#8
Hocam o checkbox aktif değildi aktif yaptım. Diğer bir yandan debug işini hala çözemedim. Run tuşuna basınca program normal olarak çalışıyor. Yani main döngüsüne giriyor kodları çalıştırıyor vs.

BreakPoint'de durmuyor.

Bu işi çözerim elbet fakat bana çok vakit kaybettirecek. Benim kodlar niye çalışmıyor anlamıyorum. RW pinide kullanılıyor. LCD nin meşgul olup olmadığına bakılıyor. Delaylarda sorun olsa diyecem ama şcd nin meşgul olup olmadığına yine lcd den bakılıyor.

LCD deki durum ise şöyle. İlk enerjilendiğinde init edilmeden önce zaten ekranın üst satırında kareler çıkıyor. Sonra init edildiği zaman ekran silikleşiyor. Buda ekranın açıldığı anlamına geliyor. Fakat devamı gelmiyor. Çözemedim durumu

Bana acilen çalışan bir 2x16LCD kütüphanesi lazım bildiğiniz kullandığınız bir kütüphane varsa verirseniz sevinirim.



mesaj birleştirme:: 08 Ağustos 2014, 19:45:22

Tamam çalıştırdım RW pin okumayı iptal ettim. Delayları bolca yerleştirdim şimdi çalıştı ama çok yavaş. Delayların sınır değerini bulmaya çalışayım. Yada yapabilirsem RW ile LCD Busy okumasını yapmaya çalışacağım.

Neyse

Debug Konusu benim için hala çözülebilmiş değil.

Tekrarlayayım. Keilde Debug yaparken BreakPoint kulanımı nasıldır?

X-Fi

#9
Ferhat hocam merhaba ben debug olayını kod içinde aktif rol alma olarak görüyorum sizinde böyle düşünmenizi isterim çünkü yeri geldiğinde işleri çok kolaylaştırıyor. Ben çok basit tüm arkadaşların anlayabileceği dilde anlatayım.

Öncelikle en baştan başlayalım bir kod yazdınız veya kodun bir kısmını değiştirdiniz ve kodun nasıl çalışacağını bilmiyorsunuz burada kodu durdurup sonuç elde etmek gerekiyorsa breakpoint kullanılır gömülü sistemler için yazılımsal ve donanımsal breakpointler ikiye ayrılır. Donanımsal olanlar debug esnasında karar verip eklediğiniz breakpointler yazılımsal olanlar ise kod derlenmeden önce ekleyip sonra derlediğiniz breakpointlerdir. Kullanım şartları kullandığınız debugger ve mcu debug birimi ile değişiklik gösterir. Donanımsal pointleri örnek veriyorum max 6 tane koyabiliriz. Yazılımsal olanı ise benim gördüğüm en fazla 65536 adet eklenebiliyor.

Bilinmesi gereken önemli nokta şudur debug işlemi mcu yu durdurma ve register izleme değiştirme işlemidir, durdurma işlemini breakpoint ya da reset yapar. SWO, EHT gibi yeni standartlar eklendikçe debug sistemleri gelişiyor. Yazılımsal yardımcılara örnek performans analizörü verilebilir. İşlemci hangi fonksiyonda ne kadar zaman harcamış performans analizörüyle izlenir. En son duyduğum debug sırasında donanımsal olarak mcu akımını ölçen ve fonksiyonlardaki akım grafiğini çıkaran trace cihazı çıkmış daha bilmediğimiz neleri vardır.

Peki ya yazılımı debug yaparken breakpoint nasıl, ne zaman çalışır? Mcu sadece run modda iken breakpoint kontrolü yapar ve varsa o adreste kalır bekler. Run mod işlemcinin clock hızının release moda birebir olduğu zamandır. Release mod ile Debug Run arasındaki tek fark mod içerisinde periodik window update seçeneği ile istediğiniz registerları watch penceresinden izlemeye devam edebilirsiniz. Breakpointde bekleyen mcu için uygulanacak komuylar şunlardır; Adım adım ilerle, fonksiyonlara girmeden ilerle, bir üst fonksiyona çıkana kadar ilerle gibi. Bu komutları kullanarak yazılımınızı test edersiniz. Sonrasında debug run komutuyla MCU nun varsa bir başka breakpoint adresine kadar gitmesini sağlayabilirsiniz.

Peki ya şöyle olsaydı napacağız diyelim ki rtc nin 29 şubat hesaplayan yazılımını test edeceğiz bu satıra gelinmesi için 29 şubatı beklemeye gerek yok. Debug moda işlemciyi test etmek istediğimiz satıra Set program counter ile taşıyabilirsiniz. (tabiki stack kopması olacağını ve etkilenen donanım ve registerların düzenini gözeterek) Debug sırasında bu işlemi daha akıllıca yazılımdan koşulu sağlayacak registerları ayarlayarak da işlemciyi götürmek mümkün.

Diyelim ki mcu da lcd driver modulu var ve sizin segment haritası çıkartmanız lazım. Apayrı bir yazılım yapıp tuşla segmentleri tek tek yaktırıp not mu alacaksanız? Hayır. Debug modunda mcular üzerindeki standart donanımların, işlemcişye özel registerların hatta yazılımsal sistemlerin kendilerine özel eklentileri vardır. Bu eklentiler sayesinde segment haritanızı çıkarırken lcd donanımındaki registerları anlık olarak değiştirebilir ve sonucunu donanımsal olarak izler ve kaydedersiniz.

Görüldüğü gibi tekrar tekrar kod derleme yükleme işlemi olmadan en temel uğraştırıcı işler debug sayesinde halledilebiliyor. 

Yazılımınız ne kadar büyürse o kadar çok debug yapmanız gerekecek demektir. Bu durumda lazım olacak diğer araç gereçleride anlatayım;

Fonksiyon analizinde kullanılan goto definition ve goto referance kısayolları bunlardan bir tanesi. Fonksion referanslarını genelde header dosyaları sağladığı için bir fonksiyonda goto referance tıklarsanız o fonksiyonun projeye dağıldığı referansı ekrana getirir. Goto definition  ise bence en önemlisidir ve fonksiyonun kaynağını ekrana getirir.

İşiniz bittiğinde eski ekranınıza geri dönmek istiyorsanız onuda navigate forwards/backwards kısayolunu kullanabilirsiniz.

Etkili bir gezinme rehberi olarak bookmarks kullanılır insert bookmark ile kod içerisinde farklı fonksiyonları işaretleyip çalıştığınız noktalara geri dönmenizi kolaylaştırır yerini unutmamanızı sağlar. (bol tuşlu mouse lar bu özellik için uygun)

Çoğu basit gibi görünen araçlar aslında kullanıldıkça kıymet kazanıyor bu yüzden anlattım.

İyi çalışmalar dilerim.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

mozkan87

STM32F103 ile denemedim ama STM32F407 ile ufak değişiklikler ile kullandım. MCBSTM32 board için oluşturulmuş örneklerin içinde mevcut.

lcd_4bit.c
/*----------------------------------------------------------------------------
 * Name:    LCD_4bit.c
 * Purpose: low level LDC functions
 * Note(s): 2 line 16 character Text LCD (4-bit interface)
 *          connected on MCBSTM32 Evaluation Board
 *----------------------------------------------------------------------------
 * This file is part of the uVision/ARM development tools.
 * This software may only be used under the terms of a valid, current,
 * end user licence from KEIL for a compatible version of KEIL software
 * development tools. Nothing else gives you the right to use this software.
 *
 * This software is supplied "AS IS" without warranties of any kind.
 *
 * Copyright (c) 20009-2011 Keil - An ARM Company. All rights reserved.
 *----------------------------------------------------------------------------*/

#include "STM32F10x.h"

/*********************** Hardware specific configuration **********************/

/*------------------------- Speed dependant settings -------------------------*/

/* If processor works on high frequency delay has to be increased, it can be 
   increased by factor 2^N by this constant                                   */
#define DELAY_2N     0

/*------------------------- Text LCD size definitions ------------------------*/

#define LineLen     16                  /* Width (in characters)              */
#define NumLines     2                  /* Hight (in lines)                   */

/*-------------------- LCD interface hardware definitions --------------------*/

/* PINS: 
   - DB4 = PC3
   - DB5 = PC2
   - DB6 = PC1
   - DB7 = PC0
   - E   = PC10
   - RW  = PC11
   - RS  = PC12                                                               */

#define PIN_E                 (   1 << 10)
#define PIN_RW                (   1 << 11)
#define PIN_RS                (   1 << 12)
#define PINS_CTRL             (0x07 << 10)
#define PINS_DATA             (0x0F <<  0)
#define PINS_ALL              (PINS_CTRL | PINS_DATA)

const unsigned int SWAP_DATA[16] = { 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 
                                     0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF};

/* Enable Clock for peripheral driving LCD pins                               */
#define LCD_CLOCK_EN         (RCC->APB2ENR |= (1 << 4)); // enable clock for GPIOC

/* pin E  setting to 0 or 1                                                   */
#define LCD_E(x)              GPIOC->ODR = (GPIOC->ODR & ~PIN_E)  | (x ? PIN_E : 0);

/* pin RW setting to 0 or 1                                                   */
#define LCD_RW(x)             GPIOC->ODR = (GPIOC->ODR & ~PIN_RW) | (x ? PIN_RW : 0);

/* pin RS setting to 0 or 1                                                   */
#define LCD_RS(x)             GPIOC->ODR = (GPIOC->ODR & ~PIN_RS) | (x ? PIN_RS : 0);

/* Reading DATA pins                                                          */
#define LCD_DATA_IN           SWAP_DATA[(((GPIOC->IDR & PINS_DATA) >> 0) & 0x0F)]

/* Writing value to DATA pins                                                 */
#define LCD_DATA_OUT(x)       GPIOC->ODR = (GPIOC->ODR & ~PINS_DATA) | ((SWAP_DATA[x]) << 0);

/* Setting all pins to output mode                                            */
#define LCD_ALL_DIR_OUT       GPIOC->CRL = (GPIOC->CRL & 0xFFFF0000) | 0x00003333; \
                              GPIOC->CRH = (GPIOC->CRH & 0xFFF000FF) | 0x00033300;
 
/* Setting DATA pins to input mode                                            */
#define LCD_DATA_DIR_IN       GPIOC->CRL = (GPIOC->CRL & 0xFFFF0000) | 0x00004444;

/* Setting DATA pins to output mode                                           */
#define LCD_DATA_DIR_OUT      GPIOC->CRL = (GPIOC->CRL & 0xFFFF0000) | 0x00003333;

/******************************************************************************/


/* 8 user defined characters to be loaded into CGRAM (used for bargraph)      */
const char UserFont[8][8] = {
  { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
  { 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 },
  { 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18 },
  { 0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C },
  { 0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E },
  { 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F },
  { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
  { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
};


/************************ Global function definitions *************************/


/*******************************************************************************
* Delay in while loop cycles                                                   *
*   Parameter:    cnt:    number of while cycles to delay                      *
*   Return:                                                                    *
*******************************************************************************/

static void delay (int cnt)
{
  cnt <<= DELAY_2N;

  while (cnt--);
}


/*******************************************************************************
* Read status of LCD controller                                                *
*   Parameter:    none                                                         *
*   Return:       Status byte contains busy flag and address pointer           *
*******************************************************************************/

static unsigned char lcd_read_status (void)
{
  unsigned char status;

  LCD_DATA_DIR_IN
  LCD_RS(0)
  LCD_RW(1)
  delay(10);
  LCD_E(1)
  delay(10);
  status  = LCD_DATA_IN << 4;
  LCD_E(0)
  delay(10);
  LCD_E(1)
  delay(10);
  status |= LCD_DATA_IN;
  LCD_E(0)
  LCD_DATA_DIR_OUT
  return (status);
}


/*******************************************************************************
* Wait until LCD controller busy flag is 0                                     *
*   Parameter:                                                                 *
*   Return:       Status byte of LCD controller (busy + address)               *
*******************************************************************************/

static unsigned char wait_while_busy (void)
{
  unsigned char status;

  do  {
    status = lcd_read_status();
  }  while (status & 0x80);             /* Wait for busy flag                 */

  return (status);
}


/*******************************************************************************
* Write 4-bits to LCD controller                                               *
*   Parameter:    c:      command to be written                                *
*   Return:                                                                    *
*******************************************************************************/

void lcd_write_4bit (unsigned char c)
{
  LCD_RW(0)
  LCD_E(1)
  LCD_DATA_OUT(c&0x0F)
  delay(10);
  LCD_E(0)
  delay(10);
}


/*******************************************************************************
* Write command to LCD controller                                              *
*   Parameter:    c:      command to be written                                *
*   Return:                                                                    *
*******************************************************************************/

void lcd_write_cmd (unsigned char c)
{
  wait_while_busy();

  LCD_RS(0)
  lcd_write_4bit (c>>4);
  lcd_write_4bit (c);
}


/*******************************************************************************
* Write data to LCD controller                                                 *
*   Parameter:    c:      data to be written                                   *
*   Return:                                                                    *
*******************************************************************************/

static void lcd_write_data (unsigned char c)
{
  wait_while_busy();

  LCD_RS(1)
  lcd_write_4bit (c>>4);
  lcd_write_4bit (c);
}


/*******************************************************************************
* Print Character to current cursor position                                   *
*   Parameter:    c:      character to be printed                              *
*   Return:                                                                    *
*******************************************************************************/

void lcd_putchar (char c)
{ 
  lcd_write_data (c);
}


/*******************************************************************************
* Initialize the LCD controller                                                *
*   Parameter:                                                                 *
*   Return:                                                                    *
*******************************************************************************/

void lcd_init (void)
{ 
  int i;
  char const *p;

  LCD_CLOCK_EN                          /* Enable clock for peripheral        */

  /* Set all pins for LCD as outputs                                          */
  LCD_ALL_DIR_OUT

  delay (15000);
  LCD_RS(0)
  lcd_write_4bit (0x3);                 /* Select 4-bit interface             */
  delay (4100);
  lcd_write_4bit (0x3);
  delay (100);
  lcd_write_4bit (0x3);
  lcd_write_4bit (0x2);

  lcd_write_cmd (0x28);                 /* 2 lines, 5x8 character matrix      */
  lcd_write_cmd (0x0C);                 /* Display ctrl:Disp=ON,Curs/Blnk=OFF */
  lcd_write_cmd (0x06);                 /* Entry mode: Move right, no shift   */

  /* Load user-specific characters into CGRAM                                 */
  lcd_write_cmd(0x40);                  /* Set CGRAM address counter to 0     */
  p = &UserFont[0][0];
  for (i = 0; i < sizeof(UserFont); i++, p++)
    lcd_putchar (*p);

  lcd_write_cmd(0x80);                  /* Set DDRAM address counter to 0     */
}



/*******************************************************************************
* Set cursor position on LCD display                                           *
*   Parameter:    column: column position                                      *
*                 line:   line position                                        *
*   Return:                                                                    *
*******************************************************************************/

void set_cursor (int column, int line)
{
  unsigned char address;

  address = (line * 40) + column;
  address = 0x80 + (address & 0x7F);
  lcd_write_cmd(address);               /* Set DDRAM address counter to 0     */
}

/*******************************************************************************
* Clear the LCD display                                                        *
*   Parameter:                                                                 *
*   Return:                                                                    *
*******************************************************************************/

void lcd_clear (void)
{
  lcd_write_cmd(0x01);                  /* Display clear                      */
  set_cursor (0, 0);
}


/*******************************************************************************
* Print sting to LCD display                                                   *
*   Parameter:    string: pointer to output string                             *
*   Return:                                                                    *
*******************************************************************************/

void lcd_print (char *string)
{
  while (*string)  {
    lcd_putchar (*string++);
  }
}


/*******************************************************************************
* Print a bargraph to LCD display                                              *
*   Parameter:     val:  value 0..100 %                                        *
*                  size: size of bargraph 1..16                                *
*   Return:                                                                    *
*******************************************************************************/
void lcd_bargraph (int value, int size) {
   int i;

   value = value * size / 20;            /* Display matrix 5 x 8 pixels       */
   for (i = 0; i < size; i++) {
      if (value > 5) {
         lcd_putchar (0x05);
         value -= 5;
      }
      else {
         lcd_putchar (value);
         break;
      }
   }
}


/*******************************************************************************
* Display bargraph on LCD display                                              *
*   Parameter:     pos_x: horizontal position of bargraph start                *
*                  pos_y: vertical position of bargraph                        *
*                  value: size of bargraph active field (in pixels)            *
*   Return:                                                                    *
*******************************************************************************/

void lcd_bargraphXY (int pos_x, int pos_y, int value) {
  int i;

  set_cursor (pos_x, pos_y);
  for (i = 0; i < 16; i++)  {
    if (value > 5) {
      lcd_putchar (0x05);
      value -= 5;
    } else {
      lcd_putchar (value);
      while (i++ < 16) lcd_putchar (0);
    }
  }
}

/******************************************************************************/


lcd.h
/*----------------------------------------------------------------------------
 * Name:    LCD.h
 * Purpose: LCD function prototypes
 * Note(s): 
 *----------------------------------------------------------------------------
 * This file is part of the uVision/ARM development tools.
 * This software may only be used under the terms of a valid, current,
 * end user licence from KEIL for a compatible version of KEIL software
 * development tools. Nothing else gives you the right to use this software.
 *
 * This software is supplied "AS IS" without warranties of any kind.
 *
 * Copyright (c) 20009-2011 Keil - An ARM Company. All rights reserved.
 *----------------------------------------------------------------------------*/

extern void lcd_init       (void);
extern void lcd_clear      (void);
extern void lcd_putchar    (char c);
extern void set_cursor     (int column, int line);
extern void lcd_print      (char *string);
extern void lcd_bargraph   (int value, int size);
extern void lcd_bargraphXY (int pos_x, int pos_y, int value);

/******************************************************************************/


Karamel

Alıntı yapılan: X-Fi - 08 Ağustos 2014, 23:51:38
Ferhat hocam merhaba ben debug olayını kod içinde aktif rol alma olarak görüyorum sizinde böyle düşünmenizi isterim çünkü yeri geldiğinde işleri çok kolaylaştırıyor. Ben çok basit tüm arkadaşların anlayabileceği dilde anlatayım.

Öncelikle en baştan başlayalım bir kod yazdınız veya kodun bir kısmını değiştirdiniz ve kodun nasıl çalışacağını bilmiyorsunuz burada kodu durdurup sonuç elde etmek gerekiyorsa breakpoint kullanılır gömülü sistemler için yazılımsal ve donanımsal breakpointler ikiye ayrılır. Donanımsal olanlar debug esnasında karar verip eklediğiniz breakpointler yazılımsal olanlar ise kod derlenmeden önce ekleyip sonra derlediğiniz breakpointlerdir. Kullanım şartları kullandığınız debugger ve mcu debug birimi ile değişiklik gösterir. Donanımsal pointleri örnek veriyorum max 6 tane koyabiliriz. Yazılımsal olanı ise benim gördüğüm en fazla 65536 adet eklenebiliyor.

Bilinmesi gereken önemli nokta şudur debug işlemi mcu yu durdurma ve register izleme değiştirme işlemidir, durdurma işlemini breakpoint ya da reset yapar. SWO, EHT gibi yeni standartlar eklendikçe debug sistemleri gelişiyor. Yazılımsal yardımcılara örnek performans analizörü verilebilir. İşlemci hangi fonksiyonda ne kadar zaman harcamış performans analizörüyle izlenir. En son duyduğum debug sırasında donanımsal olarak mcu akımını ölçen ve fonksiyonlardaki akım grafiğini çıkaran trace cihazı çıkmış daha bilmediğimiz neleri vardır.

Peki ya yazılımı debug yaparken breakpoint nasıl, ne zaman çalışır? Mcu sadece run modda iken breakpoint kontrolü yapar ve varsa o adreste kalır bekler. Run mod işlemcinin clock hızının release moda birebir olduğu zamandır. Release mod ile Debug Run arasındaki tek fark mod içerisinde periodik window update seçeneği ile istediğiniz registerları watch penceresinden izlemeye devam edebilirsiniz. Breakpointde bekleyen mcu için uygulanacak komuylar şunlardır; Adım adım ilerle, fonksiyonlara girmeden ilerle, bir üst fonksiyona çıkana kadar ilerle gibi. Bu komutları kullanarak yazılımınızı test edersiniz. Sonrasında debug run komutuyla MCU nun varsa bir başka breakpoint adresine kadar gitmesini sağlayabilirsiniz.

Peki ya şöyle olsaydı napacağız diyelim ki rtc nin 29 şubat hesaplayan yazılımını test edeceğiz bu satıra gelinmesi için 29 şubatı beklemeye gerek yok. Debug moda işlemciyi test etmek istediğimiz satıra Set program counter ile taşıyabilirsiniz. (tabiki stack kopması olacağını ve etkilenen donanım ve registerların düzenini gözeterek) Debug sırasında bu işlemi daha akıllıca yazılımdan koşulu sağlayacak registerları ayarlayarak da işlemciyi götürmek mümkün.

Diyelim ki mcu da lcd driver modulu var ve sizin segment haritası çıkartmanız lazım. Apayrı bir yazılım yapıp tuşla segmentleri tek tek yaktırıp not mu alacaksanız? Hayır. Debug modunda mcular üzerindeki standart donanımların, işlemcişye özel registerların hatta yazılımsal sistemlerin kendilerine özel eklentileri vardır. Bu eklentiler sayesinde segment haritanızı çıkarırken lcd donanımındaki registerları anlık olarak değiştirebilir ve sonucunu donanımsal olarak izler ve kaydedersiniz.

Görüldüğü gibi tekrar tekrar kod derleme yükleme işlemi olmadan en temel uğraştırıcı işler debug sayesinde halledilebiliyor. 

Yazılımınız ne kadar büyürse o kadar çok debug yapmanız gerekecek demektir. Bu durumda lazım olacak diğer araç gereçleride anlatayım;

Fonksiyon analizinde kullanılan goto definition ve goto referance kısayolları bunlardan bir tanesi. Fonksion referanslarını genelde header dosyaları sağladığı için bir fonksiyonda goto referance tıklarsanız o fonksiyonun projeye dağıldığı referansı ekrana getirir. Goto definition  ise bence en önemlisidir ve fonksiyonun kaynağını ekrana getirir.

İşiniz bittiğinde eski ekranınıza geri dönmek istiyorsanız onuda navigate forwards/backwards kısayolunu kullanabilirsiniz.

Etkili bir gezinme rehberi olarak bookmarks kullanılır insert bookmark ile kod içerisinde farklı fonksiyonları işaretleyip çalıştığınız noktalara geri dönmenizi kolaylaştırır yerini unutmamanızı sağlar. (bol tuşlu mouse lar bu özellik için uygun)

Çoğu basit gibi görünen araçlar aslında kullanıldıkça kıymet kazanıyor bu yüzden anlattım.

İyi çalışmalar dilerim.


hocam bu konu hakkinda kisa bir video hazirlayip burada yada sitenizde paylasma sansiniz varmidir? anlattiklarinizi anladim ama yap deseniz yapamam. ama uygulamali oalrak gorsek hepimiz bir kerede kavrariz olayi.

Mucit23

Coşkun Hocam Açıklama için Teşekkürler.

Debug konusunda çok az bilgim vardı. Bu konuya birazdaha ağırlık vereceğim.

Hocam vaktiniz olduğu zamanlarda bu konuyu birazdaha ayrıntılı anlatırsanız büyük bir boşluğu doldurmuş olursunuz. Özellikle Register ve Değişken izleme Müdahale etme ve performans analizatörü gibi keil debuggerinin bilinmesi gereken özellikleri üzerinde dursanız çok iyi olur.

X-Fi

Hocam video denemelerim hep başarısız oluyor pek beceremiyorum vakit bulursam bir pdf hazırlamaya çalışırım böylece benimde işime yarar. Ayrıca çalışırken pdf den bilgi almak daha hızlı oluyor.

iyi çalışmalar.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

minicihazlar

Breakpoint'ta durmuyorsa o zaman optimizasyonlar açıktır ve derleyici breakpoint koyduğunuz noktayı optimize ettiği için duracak yer işlemciye yüklenen kod içerisine bulunmuyor demektir. Proje optisonları penceresindeki "C/C++" sekmesindeki "Optimization" kısmındaki drop-down menüdeki değeri "Level 0 (-O0)" olarak değiştirip tekrar derleyip denerseniz artık istediğiniz breakpoint'a geldiğinde duracaktır.