26 Şubat 2018 Pazartesi

tcgetattr metodu

Giriş
Seri port parametrelerin okumak için kullanılır. Burada ilginç bir soru var.

Örnek
Şöyle yaparız.
struct termios options {};
tcgetattr(fd,&termAttr);
Örnek
Şöyle yaparız.
struct termios2 tio;
ioctl(fd, TCGETS2, &tio);


23 Şubat 2018 Cuma

MIL-STD-498 -SRS

Giriş
System Software Specification (SSS) ve Software Requirements Specification (SRS), Hardware Requirements Specification (HRS) bir çok projede karşımıza çıkan iki belge. Aşağıda bu belgeler ile ilgili aldığım notlar var. SSS, SRS ve HRS gibi belgelerin sadece yazıya dayalı olması iyi değil. Çünkü aşağıdaki cümlede ifade edildiği gibi yazıyı zihnimizde canlandırmak kolay değil.
Most people are bad at mentally mapping documentation to actions.
Dolayısıyla bu belgelerin şekiller ile desteklenmesi gerekiyor. SSS ve SRS genellikle CDRL listesine dahil edilirler.

Açık Kaynak/Open Source Projeler
Bu projelerin çoğunda SRS bulunmaz.

Requirements Analysis
SRS kullanılan yaşam döngüsü modeline göre Requirements Analysis (Gereksinim Analizi) safhasının veya yinelemelerinin sonucunda ortaya çıkar. Açıklaması şöyle.
Requirement Analysis is that it is a process and the document created during this process is SRS (Software Requirement Specification).

CDRL (Contract Data Requirements List) Nedir?
CDRL sözleşmenin bir lahikası olarak belirtirlir. Müsteriye teslim edilecek dokümanları listeler. Türkçesi SVIL'dir (Sozleşme Veri İsteri Listesi).

SRS
Bir CSCI'ın geliştirilmesi için kullanılan gereksinimleri içeren doküman. Projede her CSCI bileşeninin kendi SRS dokümanının olması gerekir. Bazı projelerde User Requirements diye bir belge de üretiliyor ama tam ne işe yarar bilmiyorum.

Türkçe Karşılığı
Yazılım Gereksinim Özellikleri (YGÖ) kelimesi kullanılıyor. Bence makul bir karşılık.

Dili
SRS belgesini bir çok firma İngilizce olarak hazırlamaya çalışıyor. Hazırlayanların ana dili İngilizce olmadığı için ifade bozuklukları, anlaması güç cümleler ile dolu olabiliyor. Türkçe hazırlanırsa da karşılıkları olmadığı için mecburen İngilizce kavramlar/kelimeler kullanılıyor. Her iki durum da hoş değil.

İngilizce yazılan gereksinimlerde niçin "shall" kelimesinin kullanıldığı burada açıklanmış. Türkçesi "yapacaktır" gibi düşünülürse, daha bir kesinlik manası sağladığı için "will" yerine "shall" kullanılıyor.

IEEE SRS
IEEE SRS dokümanında şu konulara değinilmesini istiyor
1.Interfaces
2.Functional Capabilities
3.Performance Levels
4.Data Structures/Elements
5.Safety
6.Reliability
7.Security/Privacy
8.Quality
9.Constraints and Limitations
Başlıklar olarak şöyle yapılabilir.
1.Introduction 1.1 Purpose 1.2 Document conventions 1.3 Intended audience 1.4 Additional information 1.5 Contact information/SRS team members 1.6 References

2.Overall Description 2.1 Product perspective 2.2 Product functions 2.3 User classes and characteristics 2.4 Operating environment 2.5 User environment 2.6 Design/implementation constraints 2.7 Assumptions and dependencies

3.External Interface Requirements 3.1 User interfaces 3.2 Hardware interfaces 3.3 Software interfaces 3.4 Communication protocols and interfaces

4.System Features 4.1 System feature A 4.1.1 Description and priority 4.1.2 Action/result 4.1.3 Functional requirements 4.2 System feature B

5.Other Nonfunctional Requirements 5.1 Performance requirements 5.2 Safety requirements 5.3 Security requirements 5.4 Software quality attributes 5.5 Project documentation 5.6 User documentation

6.Other Requirements Appendix A: Terminology/Glossary/Definitions list Appendix B: To be determined
Interfaces Nedir
1. User Interfaces
2. Hardware interfaces
3. Software interfaces
4. Communication Interface

User Interfaces başığı altına (the buttons, sliders, text boxs etc..) gibi şeyler yazılabilir deniyor. ancak ben hiç yazıldığını görmedim.

SRS Mimari ve Tasarım
SRS problem uzayı, tasarım ve mimari ise çözüm uzayında gibi düşünülüyor. Ancak bence tam olarak birbirlerinden bu kadar bağımsız şeyler değiller.

Örnek
Şöyle bir soru olsun.
A software Requirements Specification (SRS) document should avoid discussing which one of the following ?
(A) User interface issues
(B) Non-functional requirements
(C) Design specifications
(D) Interfaces with third party software
Cevabı (C) Design Specifications.

Örnek
"A Comparison of Requirements Specification Methods from a Software Architecture Perspective" makalesi SRS maddelerinin, yazılımın mimarisini ne kadar etkilediği konusunu işliyor. Makaleden bir kaç cümle şöyle.
"If functionality is the only concern in designing an architecture, any structure will do. This conclusion stems from the work of Parnas more than 30 years ago."
Devam ediyor.
"Connecting requirements to architecture can be viewed as a special case of connecting a system's problem space and its solution space".
SRS Geliştirme Eforu
Geliştirme eforunun yaklaşık yüzde 40'ı gereksinim ve tasarım aşamasına ayrılırsa iyi olur.

SRS Belgesinde Kullanılan Bazı Sütünlar

Derived Requirement
Aşağıda açıkladım
Verification Method
Doğrulama yöntemi. Test, Analysis, Inspection (Code Review, Design Review), Demonstration olabilir. Verification (doğrulama) yöntemi olmayan madde olmamalı.
Notes
Gereken notlar

Derived Gereksinimler Nedir
Bazı projelerde gereksinimler "Derived" olarak işaretlenirler. Derived Requirement sistem tasarımından kaynaklanmayan, sistem izlenebilirliği olmayan ister anlamına geliyor. Örneğin sistem tasarımı, yazılımın kaç bölümlenmeden (partition) oluşacağını söylemeyebilir. Ancak SRS'te bu ister bulunabilir. Bu durumda SRS'teki ister "Derived Requirement" olarak işaretlenir. Aşağıdaki cümle de önemli.
"These are requirements that are generated by the development team, based on a number of sources such as regulatory agencies, corporate guidelines, and past experiences on similar projects."
DO-178B kullanan projelerde bir gereksinimin derived olarak işaretlenebilmesi için "Safety Assesment" süreci tarafından onaylanmış olması gerekir.

Non-Functional Gereksinimler Nedir?
Non-Functional Gereksinimler yazısına taşıdım.

SRS ve Tasarım Arasında İzlenebilirlik Tablosu
Her SRS dokümanında, isterlerin hangi CSC'de ele alındığını gösteren bir izlenebilirlik tablosu bulunur. Aslında bu tablo genellikle işe yaramaz, çünkü SRS ve gerçek tasarım/kod arasında çoğunlukla büyük boşluklar bulunur. Mühendisler izlenebilirlik tablosunu kabaca kestirimlerine dayanarak doldururlar. SRS'i eline alıp okuyarak geliştirmeye başlayan bir mühendis, tek bir maddenin kaç bileşene dokunacağını, maliyetinin ne olacağını kestiremeyebilir.

DO-178B gibi süreçlerde ise bu boşluğu doldurmak üzere, High Level (bahse konu SRS belgesi) ve Low Level Requirements isimli iki belge üretilir. Low Level Requirements belgesi SRS ve kod/arasındaki boşluğu kapatır.

SRS ve Test Arasında İzlenebilirlik Tablosu
SRS ve Test (STD) arasında da izlenebilirlik kurmak gerekir. Hatta Test ve Test Sonuçları arasında da bağlantı kurulur.

Yazılım Kalite Etkenleri ile İlgili Gereksinimler

SRS belgelerinde bazen aşağıdakine benzer yazılım kalite etkenleri (software quality factors) görüyorum. Bunları not etmek istedim.

Functionality Requirements
Örnek yaz

Reliability Requirements
Örnek
X shall be able to process following data during N hours.
Maintainability Requirements
Örnek yaz

Availability Requirements
Örnek yaz

Flexibility Requirements
Örnek yaz

Portability Requirements
X shall be developed independent from OS specific system calls.

Reusability Requirements
Örnek yaz

Testability Requirements
Bu iyi bir örnekmi bilmiyorum ancak aşağıdakine benzer cümleler gördüm.
X shall provide health status. X shall perform BIT upon request.

Efficiency Requirements
Örnek yaz

Usability Requirements
Örnek yaz

Kalite Etkenleri Nasıl Test Edilir
Sistem veya Yazılım Kalite Etkenleri netice itibariyle birer gereksinim olduklarına göre, test edilmeleri de gerekir. Bu iş için "Fonksiyonel Olmayan Testler" başlığı altında toplanabilecek bazı faaliyetler gerçekleştirilir.
Performans Testleri :
Yükleme (Load) Testleri : Sistemin belli bir yük altında testi
Stres Testleri: Sistemin aşırı yük altında testi
Uyumluluk (Compatibility) Testleri :
Güvenlik Testleri :
Kullanılabilirlik Testleri :
Yerelleştirme (Localization) Testleri : Çeviriler, tarih, saat formatı vs.

SRS Hataları
SRS'e donanım özelliklerini yazmak gördüğüm hatalardan birisi. Örneğin software shall run on 1 GB memory, 1GHz processor gibi. Bu tür bir gereksinim bence sistem seviyesinde olmalı.

Yazılımın kapasitesini belirten ancak throughput, gecikme, bir işin ne kadar birim zamanda yapılacağını belirtmeyen gereksinim maddeleri bence doğru değiller. Örneğin bir yazılım 5000 nesneyi bellekte tutacaktır denirse ancak bu 5000 nesneyi veya 1 tanesini ne kadar zamanda işleyeceği belirtilmezse, yazılımı test etmek için referans zamanı verilmemiş olur.


SRS Hangi Ölçütlere Göre Gözden Geçirilebilir
SRS Kontrol Listesi yazısına taşıdım.

Müşterinin SRS'e Yorum Vermesi
Sözleşmede genellikle SRS teslim edildikten X gün sonrasına kadar müşteri yorum verebilir şeklinde bir madde bulunur.

Benzer şekilde SRS'i hazırlayan taraf ta yine Y gün içerisinde yorumlara cevap vermekle mükelleftir, şeklinde bir madde ile taraflar SRS'i ciddiye aldıklarını belirtirler.

SRS Örnekleri
SRS Örnekleri yazısına taşıdım.

Baseline
İngilizce açıklaması şöyle
A specification or software product that has been formally reviewed or agreed upon, that thereafter serves as the basis for further development, and that can be changed only through a formal change control process.
Türkçe açıklaması şöyle
Resmi olarak gözden geçirilmiş veya üzerinde anlaşılmış ileriki geliştirmeler için temel teşkil edecek ve sadece resmi değişiklik kontrol süreci ile değiştirilebilen özellik veya yazılım ürünü.

SRS Değişiklikleri
SRS değiştiğinde eski ana hat (baseline) ile yeni anahatın farkını çıkarıp ekibe dağıtmak gerekir. Doors'ta Baseline Comparison Report alınabilir.


22 Şubat 2018 Perşembe

Yazılım Mimarisindeki Genel Kabiliyetler

Giriş
Aşağıda bazı projelerde gördüğüm genel kabiliyetlerle ilgili notlarım var. Bu kabiliyetler teknolojiden bağımsız.

Fault/Event Management
Bir sistemin ürettiği hataların kullanıcı tarafından görülebilmesi gerekebilir.

Örnek
Bir seferinde bu kabiliyeti karşılamak için Spring Event'leri kullanmıştık. Her bileşen hata ile karşılaşınca bir Spring Event'i fire ediyordu. Bu eventleri dinleyen Spring Bean, hataları veritabanına kaydediyordu. Bir başka uygulama bu verileri kullanıcıya listeliyordu.

Sistemin Mod ve Durumunun Yönetilmesi (Mode and State)
Sistemin Mod ve Durumunun Yönetilmesi (Mode and State) yazısına taşıdım.

Kaydetme Kabiliyeti (Record)
Kaydetme Kabiliyeti yazısına taşıdım.

Tekra Oynatma Kabiliyeti (Replay)

Tekrar oynatmada iki temel çözüm var
1. Sistemin en başa alınarak herşeyin tekrar oynatılması
2. Sistemin belli bir state'a alınarak kayıdın belli bir zamandan başlayarak oynatılması

Her iki durum için de genellikle oynatma hızı değiştirilebilmeli 1x, 2x, 4x gibi hızlar verilmelidir.

En Baştan Oynatma
En kolay çözüm bu. Tüm sistem temiz olarak açılır ve kayıt edilmiş mesajlar sistem gönderilir.

Belli Bir Zamandan Başlatarak Oynatma
Tekrar oynatmada genellikle kayıdın belli bir zaman noktasına gidilir. Bu yüzden kayıt başlatılırken zaman bilgisini tutmak gerekir. Zaman noktası seçilirken Duvar Saati veya Kayıt Başlangıç Saati kullanılabilir. Zaman noktası kaydırma işlemi defalarca yapılabilmelidir. Burada en önemli problem state'i geri alabilmek

Eğer elimizde sadece bir viewer varsa ve mesela 100 tane mesaj gösteriyorsa kayıdı ileri geri oynatırken sadece viewer'ı temizleyerek mesajları yeniden oynatmak kolay. Çünkü viewer neredeyse state tutmuyor denilebilir.

Ancak elimizde bir araba varsa ve kayıdın belli bir zamanına geri gitme istiyorsak mecburen state saklamak gerekiyor.

State'i belli bir zamandaki duruma çekmenin en kolay yolu herşeyi temizlemek ve state'i saklanan haliyle tekrar yüklemek. Eğer elimizde publish/subscrive mimarisi varsa, state'i temizlemek için bir topic gönderilir. Daha sonra state'i temsil eden topic'ler teker teker baştan gönderilir. Daha sonra kayıt edilen mesajlar tekrar oynatılır.






19 Şubat 2018 Pazartesi

Linux timerfd_create metodu

Giriş
Bu metod Linux'a mahsus bir çağrı. Bu metod ile select veya poll ile dinlenebilen bir timer yaratılabilir. Şöyle yaparız.
uint64_t expired = 0;
read (timerfd, &expired, sizeof(uint64_t));
timerfd_create metodu
Birinci parametre olarak CLOCK_MONOTONIC, CLOCK_REALTIME gibi seçenekle kullanılabilir. İkinci parametre olarak flag verilir. Eğer Linux sürümü destekliyorsa TFD_CLOEXE yani close-on-exec kullanılabilir.

Örnek
Şöyle yaparız.
int timerfd = timerfd_create(CLOCK_MONOTONIC,0);
Örnek
Şöyle yaparız.
int timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
Örnek
Eğer hata varsa 0'dan küçük bir değer döner. Şöyle yaparız.
if( timerfd < 0 ) {
  printf("Timer fd failed\n");
}
Örnek
Şöyle yaparız.
int epoll_reactor::do_timerfd_create()
{
#if defined(BOOST_ASIO_HAS_TIMERFD)
# if defined(TFD_CLOEXEC)
  int fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
# else // defined(TFD_CLOEXEC)
  int fd = -1;
  errno = EINVAL;
# endif // defined(TFD_CLOEXEC)

  if (fd == -1 && errno == EINVAL)
  {
    fd = timerfd_create(CLOCK_MONOTONIC, 0);
    if (fd != -1)
      ::fcntl(fd, F_SETFD, FD_CLOEXEC);
}
timerfd_settime metodu
Interval atamak için şöyle yaparız.
int milliseconds = 50;// 50 ms for example
struct itimerspec timspec;
timspec.it_interval.tv_sec = 0;
timspec.it_interval.tv_nsec = milliseconds * 1000000;
Delay atamak için şöyle yaparız.
timspec.it_value.tv_sec = 1;
timspec.it_value.tv_nsec = 0;
Başlatmak için şöyle yaparız.
int res = timerfd_settime(timerfd, 0, &timspec, 0);

15 Şubat 2018 Perşembe

Tell, Don't Ask Kuralı

Giriş
Bu kural 3 varsayım ile geliyor. Bunlar şöyle.
1. You're using objects.
2. Your objects have state.
3. The state of your objects affects their behavior.
Tell, Don't Ask kuralı başka nesnenin iç durumuna erişme diyor. Açıklaması şöyle.
Allow your class to manage its own state. Don't ask it for its state, and then take action based on that state. Tell the class what you want, and let it decide what to do based on its own state.
Bir başka açıklama şöyle.
Tell-Don't-Ask is a principle that helps people remember that object-orientation is about bundling data with the functions that operate on that data. It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do. This encourages us to move behavior into an object to go with the data.
Örnek
Şu kod kuralı ihlal eder.
var color = trafficLight.Color;
var elapsed = trafficLight.Elapsed;
If (color == Color.Red && elapsed > 2.Minutes)
    trafficLight.ChangeColor(green);
Düzeltmek için şöyle yaparız.
var result = trafficLight.ChangeColor(Color.Green);


2 Şubat 2018 Cuma

Enterprise Architect Automation Interface

Enterprise Architect Notlarım
Giriş
Enterprise Architect Bir CASE (Computer Aided Software Engineering, Bilgisayar Destekli Yazılım Mühendisliği) aracıdır.

Bu tür araçların, CMMI sürecinin iyileştirilmesinde kullanılması konulu "akademik (!!)" bir çalışmada kullanılmasını görünce, insanın aklına Excel'in "not tutmak" için kullanılması geliyor.

CASE araçları kimileri tarafından modası geçmiş olarak görülse de, ben yazılım kod üretmek için olmasa bile, "Yazılım Ürün Hattı" konusu içinde bulunan Information Model'i betimlemek için faydalı olduklarını düşünüyorum.

Enterprise Architect Automation Interface İçin Ne Lazım ?
Enterprise Architect Automation Interface kullanabilmek içim eaapi.jar ve SSJavaCOM.dll doslayarı lazım. Her şey COM üzerinde inşa edildiği için EA.exe arka planda çalışmalı. Ayrcıa tüm veri yapıları başlangıç indeksi olarak Java'daki gibi 0 sayısı ile başlıyorlar.

Repository Sınıfı Nedir ?
Bu sınıf ile EA Automation arayüzüne erişim sağlanıyor. Aşağıdaki açıklamada entry point olduğu söyleniyor.

The Repository package contains the high level system objects and entry point into the model itself using the Models collection and the other system level collections.

Şekilden de tüm diğer sınıflara erişim için kullanılabileceği görülebilir.

Örnek:
import org.sparx.*;
Repository repository = new Repository ();
repository.open ("c:\\eatest.eap");
Eğer SQLServer'a bağlanmak istersek bu sefer bağlantı dizisini vermek lazım. Kullanılacak diziyi File/Open Project menüsünden görebiliriz. Örnek:
import org.sparx.*;
Repository repository = new Repository ();
String conn = "Model Ismi - DBType=1;Connect=Provider=SQLOLEDB.1;Password=mypass;Persist Security Info=true;User ID=myuser;Initial Catalog=MyModel;Data Source=MyServer\SQLEXPRESS";
repository.open (conn);
Package Sınıfı Nedir?
Bu sınıf ile paketlerin içindeki diagramlar bulunabilir.
Package1
  | -> Package2
           |->Diagram1
şeklinde bir ağaç yapısı varsa, Diagram1'e şöyle erişişir.

Collection<org.sparx.Package> packages = p.GetPackages();
Package package= packages.GetAt (0);
Collection<org.sparx.Diagram> diagrams= package.GetDiagrams();

Diagram Sınıfı Nedir?
Bu sınıf UML ile tasarlanan herhangi bir diagramı temsil ediyor.Yukarıdaki örnekten devam edersek. Diagram1 sınıfının içindeki nesnelere erişmek için aşağıdaki gibi yapılabilir.

Diagram diagram = diagrams.GetAt(0);
Collection<org.sparx.DiagramObject> diagramObjects = diagram.GetDiagramObjects();

Bir diagramı diske emf dosyası olarak kaydetmek için buradaki koda bakılabilir.

Element Sınıfı Nedir?
Bu sınıf ile diyagram içindeki sınıfın bilgisine erişmek mümkün. Aşağıdaki gibi GetElementByID metodu ile yapılabilir.

DiagramObject diagramObject = diagramObjects.GetAt (0);
int elementID = diagramObject.GetElementID (); //56110 verir
Element element = repository.GetElementByID (elementID);
String stereoType = element.GetStereoType ();//struct verir
String name = element.GetName (); //MyStruct verir
Collection<org.sparx.Attribute> attributes = element.GetAttributes();
Element'e direkt erişmek için GUID kullanılabilir. Örnek:
Element myClass = repository.GetElementbyGuid ("{7AC7AB80-DEE5-4CD1-...}");

Burada dikkat edilmesi gereken konu GetAttributes metodunun döndürdüğü Collection sınıfının java.util paketi içindeki Collection olmadığı. Bu sınıfı bir ArrayList'e çevirmek için aşağaki kod kullanılabilir
ArrayList<Attribute> list = new ArrayList <Attribute> ();
Iterator it = attributes.Iterator ();
while (it.hasNext ()){
  list.add (it.next());
}
C#'ta Attributes için şöyle yaparız.
foreach (EA.Attribute att in currentElement.Attributes)
{
}
C#'ta Methods için şöyle yaparız.
foreach (EA.Method att in currentElement.Methods)
{
}
Attribute Sınıfı Nedir?
Bu sınıf ile class veya struct içindeki alanların bilgisine erişmek mümkün.
Attribute attribute = attributes.GetAt (0);

String name = a.GetName();//m_MyAttributeString type = a.GetType ();//longint attributeID = a.GetElementID () //45789
Attribute'ları sıralama örneği
Collections.sort (list,new Comparator<Attribute> (){
  @Override  public int compare (Attribute left,Attribute right){
    if (left.GetPos () > right.GetPos ()){return 1;}
    if (left.GetPos () < right.GetPos ()){return -1;}
    return 0;
  }
});
Örnekler
EA kurulumunda C:\Program Files (x86)\Sparx Systems\EA\Code\Code Samples\ altında C# ve Java örnek projeleri var.

EA Plugin
EA için plug-in yazmayı gösteren güzel bir yazı burada.

EA'da Kod Üretme
C++
.h ve .cpp doslaları için farklı generator kodları kullanmak gerekir.

Header Kodu Üretmek 
Include path'lerinin ayarlanması gerekir.

Include Guard
Header dosyasının derleme hatası almaması için gerekir

Copyright Bilgisi
Kodun başına yazılır.

Getter Setter Metodları
Eğer attribute primitive ise örneğin int olsun aşağıdaki gibi olabilir.

const int GetAttr () const;
void SetAttr (const int& value)

Eğer attribute başka bir struct ise aşağıdaki gibi olabilir.
MyValue& GetMyValue ();
void SetMyValue (const MyValue& value);