Selamlar,
MCU için C++ kullanan arkadaş var mı? Yorumlarını bekliyorum.
ARM AVR vs birçok MCU derleyicileri C++'ı destekliyor ama şuana kadar nette çok az örneğini gördüm.
Profesyonel piyasada kullanılmıyor mu? Yada az buçuk işletim sistemi vs çalıştıran gömülü sistemlerde?
MCU için amacım C++'ın alengirli özelliklerini kullanmak değilde class'lar vs ile programlamaya renk katmak.
QP Framework'e bir bakin. Isletim sistemi ile yada isletim sistemsiz kullanilabilir.
Practical UML Statecharts in C/C++, Second Edition: Event-Driven Programming for Embedded Systems kitabinda detayli bahsediliyor.
benim bildigim kadari ile cortex m3lerde uyarlandi.
Bu günlerde ben de bu konu üzerindeyim.
Bir projede kullanmadım ama renesas R8C ve M16 için bazı denemelerim oldu. Bu denemeler sonucunda gayet memnun kaldım. Bu yüzden Cortex-M4 ile başlayacağım projeleri C++ ile yazmayı düşünüyorum.
https://www.picproje.org/index.php/topic,37194.msg269763/topicseen.html#msg269763
Bu başlıkta konuyu biraz kaşımayı düşünüyorum.
Teşekkürler,
C++'a ve bahsedilen kaynaklara biraz göz attım, vakit olunca deneme yapacağım.
Fakat şuan ileriye dönük olarak fayda/zarar durumunu kestiremiyorum.
İleride ilgileneceğim alan gömülü sistemler olacak bu doğrultuda düzenli ilerlemek istiyorum.
İlerisi olduğuna emin olsam C++'a daha çok yöneleceğim.
Bilgisayar tarafında da C# uğraşıyorum onada daha fazla yönelmek istiyorum ama karasızım biraz.
Ufak uygulama ile buyuk uygulama arasindaki siniri nasil tarif edersiniz?
C ve C++ ile ayni uygulama icin kod gelistirilmeye calisilsa kod ve ram alani kullanimi icin ne soylenebilir?
Araclarda kullandigimiz navigasyon cihazlari c++ ile mi yazilmistir?
Ben de bunlari merak ediyorum.
Alıntı yapılan: bunalmis - 08 Ocak 2012, 20:59:36
Ufak uygulama ile buyuk uygulama arasindaki siniri nasil tarif edersiniz?
C ve C++ ile ayni uygulama icin kod gelistirilmeye calisilsa kod ve ram alani kullanimi icin ne soylenebilir?
Araclarda kullandigimiz navigasyon cihazlari c++ ile mi yazilmistir?
Ben de bunlari merak ediyorum.
buyuk uygulamalarda ne kadar kod ve ram kullandigimizla ilgilenmeyiz. buyuk uygulamayi gelistirebilmek ve calistirmak yeteri kadar zor ve zahmetlidir, ne kadar kod yada ram harcandiginin onemi cok dusuktur.
Alıntı YapNeyse şimdi forumdaki kimse burada bunları hesaplamaz sanırım.
sayın @gerbay, when you ASSUME something you make an ASS of U and ME.
bu forumda kimse kullanmaz derken, en azindan @mufitsozen sizi tenzih ederim gibi bir ifade kullanabilirdin. ;)
Alıntı yapılan: bunalmis - 08 Ocak 2012, 20:59:36
Ufak uygulama ile buyuk uygulama arasindaki siniri nasil tarif edersiniz?
C ve C++ ile ayni uygulama icin kod gelistirilmeye calisilsa kod ve ram alani kullanimi icin ne soylenebilir?
Araclarda kullandigimiz navigasyon cihazlari c++ ile mi yazilmistir?
Ben de bunlari merak ediyorum.
hocam bi arkadasim bi savunma sanayiinde calisiyi. Ucaklarin navigasyon cihazlari icin uygulama yaziyo. Kullandigi dil C imis
KHocam sizin kastettiginiz driver yazma falansa yani donanima hukmeden yazilimlarsa o arkadasin yaptigi sey o değil ben ona sormustum driver falan mi yaziyon diye yok demisti.Ben de fazla israr etmedim ne olduguna dair.Yani gomulu isletim sistemi vardir cihazlarda direkt donanim icin değil de isletim sistemi uzerinde calisacak programlar yaziyodur. Tam emin değilim yani. Ama durumboyle bile olsa nesne yonelimli bi dil kullanmak daha.mantikli geliyo bana
EKLEME: Hocam yukaridaki yazinizi tam okumamistim simdi okudum siz de zaten isletim sistemine kod yazmaktan bahsediyomussunuz
Bi ara C++'a merak salıp uğraşıp bırakmıştım. Şuan tekrar göz atıyorumda classlar nesneler overloding vs. ayrı bir hava katıyor programlamaya.
Denemeye değer :)
Alıntı yapılan: gerbay - 08 Ocak 2012, 22:33:18
hocam o dediğin işi şu an yapan iki firma var, birisinde VxWorks kullanıyorlar o işlerde. Diğerinde de GreenHills Integrity kullanıyorlar..
benim kastettiğim driver yazma falan değil zaten..
bir de şu var, savunma sanayiinde çalışan biri öyle yazıyor diye o iyi birşeydir değildir tartışması yapılmadan insanlarda bir "demekki bu iş o şekilde yapılır" düşüncesi oluyor..
ben size yabancı savunma sanayyinde bir çok farklı firma sayarım benzer işleri C++ kullanarak yapan..
nerede çalışırsa çalışsın, başkalarının doğrularını sorgusuz sualsiz, ölçüp tartmadan kendi doğrunuz haline getirmeyin..
Hocam beni yanlış anladınız. Ben o öyle yapıyo diye doğru demedim. Sadece bunalmış hocanın sorduğuna örnek vermek istedim.Zaten bana C kullanıyoruz dediğinde şaşırmıştım.Yani C kullanılması gerektiğini savunmuyorum.
Bana sanki malloc yazamayınca işin tüm tadı kaçıyor gibi geliyor. Gerçi bu işletim sistemi olmayışından kaynaklanıyor, yani C'de de böyle.
C++ bildiğim söylenemez ama onda da new ifadesi var sanırım. Çalışma anında dinamik olarak nesne oluşturamayacaksam C++'ın ne zevki kalır ki? Veya C'den ne farkı kalır?
Ne zaman ki işin içine bir işletim sistemi girer (tercihen Linux), o zaman C++ anlam kazanır bence.
Merhaba,
Alıntı yapılan: mufitsozen - 07 Ocak 2012, 16:28:45
QP Framework'e bir bakin. Isletim sistemi ile yada isletim sistemsiz kullanilabilir.
Practical UML Statecharts in C/C++, Second Edition: Event-Driven Programming for Embedded Systems kitabinda detayli bahsediliyor.
benim bildigim kadari ile cortex m3lerde uyarlandi.
Herşeyden önce bu kitabı herkes övmüş (amazonda kitap yorumlarına baktım). Peki okuyan, konuyu bilen arkadaşlar kitap ve kitabın konusu ne için bu kadar önemli?
Kitabın 2. bölüme kadar olan kısmını pdf formatta vermişler. Açtım göz attım. Second edition de kitapda, birçok gömülü sistem geliştiricisi donanım üzerine yetişmiş EE (Electrical Enginneer?) olduğu için C++ ile göz korkutmaya gerek yok bu yüzden ilk baskıdaki C++ programları yerine C programlama dilini kullandım gibi bazı şeyler yazmış. Şimdi C++ kullanacak kişi sizce first edition mı second edition mı okumalı?
Alıntı yapılan: Tagli - 08 Ocak 2012, 23:28:50
Bana sanki malloc yazamayınca işin tüm tadı kaçıyor gibi geliyor. Gerçi bu işletim sistemi olmayışından kaynaklanıyor, yani C'de de böyle.
C++ bildiğim söylenemez ama onda da new ifadesi var sanırım. Çalışma anında dinamik olarak nesne oluşturamayacaksam C++'ın ne zevki kalır ki? Veya C'den ne farkı kalır?
Ne zaman ki işin içine bir işletim sistemi girer (tercihen Linux), o zaman C++ anlam kazanır bence.
Çalışma anında dinamik nesne oluşturmakdan kasıt ne oluyor? new ile istendiği zaman dinamik olarak nesne oluşturma talebinde bulunabilinir. Sanırım aynı şeylerden bahsetmiyoruz?
Doğru ama işletim sistemi yoksa new komutu nasıl çalışabilir ki? Yeni bir nesne oluşturabilmek için öncelikle sistemden bir alan istenmesi gerekir. İşletim sistemi yoksa yeni alan da alınamaz. Tüm alanlar derleme sırasında statik olarak tanımlanmalıdır.
Gömülü sistemlerde C++ kullanmak meselesini sadece ihtiyaç meselesine de indirgememek gerek. Belki C++ kullanmaya hiç ihtiyacımız olmayabilir. Ama onun getirdiği yenilikler, programlaya katacağı hoşluklar program yazmayı belki daha eğlenceli hale getirecek.
İnternet explorer kullanırken bir bağlantıyı yeni sekmede açmak için farenin orta tuşunu kullanıyorum. Sağ tuşa basıp yeni sekmede aç da diyebilirim. Orta tuşa ihtiyacım var mı? Yok! Ama böyle kullanmayı seviyorum.
C++ daki fonksiyon aşırı yükleme bile C++ kullanmayı isteğimiartırıyor. Şart mı değil. C ile, farklı şekillerde halledebilirim. Ama bu özelliği kullanmak bana keyif veriyor.
Embedded programcılar için gerçek hayatta her zaman karşılaşmasak da karşılaşabileceğimiz bir örnek:
Bir I2C aygıtımız var. I2C kontrolünü software ile yapmak zorundayız. Bir sorun yok hemen bir program yazar hallederiz.
Peki bu aygıttan 2 tane lazım olursa ve biz bu aygıtı başka porta bağlamak zorunda kalırsak?
Sorun yok oturur 2. I2C rutinleri yazarız. Ya da rutinimizi parametrik hale getirir 2. I2C kontrolünü de yaparız.
Peki 3. 4. 5. 6. I2C ihtiyacı duyduğumuzda ne yapacağız?
Aynı şeyi C++ ile yapsaydık.
Bir tane I2C sınıfı tanımlardık. O kadar.
Sonra bu sınıftan bir nesne oluşturup port ayarlarımızı yapardık iş bitti.
2. lazım olduğunda? bir nesne daha tanımla port ayarlarını yap kullan.
3. 4. 5. 6. 7. kaynakların yettiği sürece devam.
Bu işi C ile yapabiliyoruz. O zaman C++ gerekli mi? Değil. Ama kullanmak ister miyim? Evet.
:) yok hocam muhakkak fantezi için değil. Öğrendikçe bir sürü şey keşfediyorum ve her geçen gün daha da seviyorum.
Mesajımın hedefindeki kişiler, C++ kullanmak için gerçekten hiç gerekçesi olmayanlar.
Alıntı yapılan: Klein - 09 Ocak 2012, 17:14:45
Gömülü sistemlerde C++ kullanmak meselesini sadece ihtiyaç meselesine de indirgememek gerek. Belki C++ kullanmaya hiç ihtiyacımız olmayabilir. Ama onun getirdiği yenilikler, programlaya katacağı hoşluklar program yazmayı belki daha eğlenceli hale getirecek.
İnternet explorer kullanırken bir bağlantıyı yeni sekmede açmak için farenin orta tuşunu kullanıyorum. Sağ tuşa basıp yeni sekmede aç da diyebilirim. Orta tuşa ihtiyacım var mı? Yok! Ama böyle kullanmayı seviyorum.
C++ daki fonksiyon aşırı yükleme bile C++ kullanmayı isteğimiartırıyor. Şart mı değil. C ile, farklı şekillerde halledebilirim. Ama bu özelliği kullanmak bana keyif veriyor.
Embedded programcılar için gerçek hayatta her zaman karşılaşmasak da karşılaşabileceğimiz bir örnek:
Bir I2C aygıtımız var. I2C kontrolünü software ile yapmak zorundayız. Bir sorun yok hemen bir program yazar hallederiz.
Peki bu aygıttan 2 tane lazım olursa ve biz bu aygıtı başka porta bağlamak zorunda kalırsak?
Sorun yok oturur 2. I2C rutinleri yazarız. Ya da rutinimizi parametrik hale getirir 2. I2C kontrolünü de yaparız.
Peki 3. 4. 5. 6. I2C ihtiyacı duyduğumuzda ne yapacağız?
Aynı şeyi C++ ile yapsaydık.
Bir tane I2C sınıfı tanımlardık. O kadar.
Sonra bu sınıftan bir nesne oluşturup port ayarlarımızı yapardık iş bitti.
2. lazım olduğunda? bir nesne daha tanımla port ayarlarını yap kullan.
3. 4. 5. 6. 7. kaynakların yettiği sürece devam.
Bu işi C ile yapabiliyoruz. O zaman C++ gerekli mi? Değil. Ama kullanmak ister miyim? Evet.
Hocam burada anlattığınız şeyleri c'de de kütühane oluşturup yapabiliyoruz ama. Yanlış mıyım?
Evet bazılarını C ile'de yapabilirsiniz. Ama C++'da olduğu kadar şık ve esnek olmaz. İhtiyaç meselesine indirgememek gerektiğini söylemem de bu yüzden.
Aşağıdaki kod yukarıda bahserriğim "i2c" sınıfı ve bu sınıftan nesne atamaya örnek kod.
Bu kodla işlemcimizin istediğimiz prtuna istediğimiz kadar i2c aygıt bağlayabiliyoruz. Bu işi c ile yapabiliriz. ben C++ kodlarını koyuyorum. Bu işin C ile yapılmış halini de birisi koyarsa, C++ programcılık hayatımıza nasıl renkler katabilir daha iyi görebiliriz. Belki de C++ ile kod yazmaya hiç sıcak bakmayanlaın kafasında acaba? sorusunu uyandırabiliriz. Amacım bununla yapılır , şununla yapılmaz gibi bir kıyaslama değil. C++ ile kod yazmanın benim hayatıma getirdiği kolaylıkları sizinle paylaşarak, biraz ilgi duymanızı sağlamak.
i2c sınıfının tanımı.
class i2c {
void delay(unsigned int usec);
void clk(void);
void start(void);
void stop(void);
void ack(void);
void init(void);
void write(unsigned char devdata);
unsigned char read(unsigned char ackchar);
unsigned char volatile __data13 *SCL;
unsigned char volatile __data13 *SDA;
unsigned char volatile __data13 *sda_dir;
unsigned char volatile __data13 *scl_dir;
unsigned char scl_mask;
unsigned char sda_mask;
public:
unsigned char read_byte(unsigned char i2caddr,unsigned char memadr);
void write_byte(unsigned char i2caddr,unsigned char memadr, unsigned char memdata);
void set_hardware( unsigned char volatile __data13 *sclport, unsigned char scl_pin,
unsigned char volatile __data13 *sdaport, unsigned char sda_pin,
unsigned char volatile __data13 *scl_direction_register,
unsigned char volatile __data13 *sda_direction_register);
};
i2c sınıfının üye fonksiyonları
#include "i2c.h"
#define ACK 0
#define NACK 1
const unsigned char port_mask[]={
0x01,0x02,0x04,0x08,
0x10,0x20,0x40,0x80,
};
void i2c::set_hardware( unsigned char volatile __data13 *sclport, unsigned char scl_pin,
unsigned char volatile __data13 *sdaport, unsigned char sda_pin,
unsigned char volatile __data13 *scl_direction_reg,
unsigned char volatile __data13 *sda_direction_reg )
{
SCL = sclport;
SDA = sdaport;
sda_dir = sda_direction_reg;
scl_dir = scl_direction_reg;
scl_mask = port_mask[scl_pin];
sda_mask = port_mask[sda_pin];
init();
}
void i2c::init(void){
*sda_dir |= sda_mask; // output
*scl_dir |= scl_mask; // output
stop();
}
void i2c::clk(void){
*SCL |= scl_mask ;
*SCL &= ~scl_mask;
}
void i2c::start(void){
*SCL |= scl_mask;
*SDA &= ~sda_mask;
*SCL &=~scl_mask;
}
void i2c::stop(void){
*SDA &= ~sda_mask;
*sda_dir |=sda_mask; // output
*SCL |=scl_mask;
*SDA |=sda_mask;
}
void i2c::ack(void){
*sda_dir &=~sda_mask; //input
clk();
*SDA |=sda_mask;
*sda_dir |=sda_mask; // output
}
void i2c::write(unsigned char devdata){
unsigned char I;
unsigned char sdata;
*sda_dir |= sda_mask; // output
sdata=devdata;
for(I=0; I < 8; I++)
{
if(sdata & 0x80) *SDA |= sda_mask; else *SDA &= ~sda_mask;
clk();
sdata <<=1;
}
ack();
};
unsigned char i2c::read(unsigned char ackchar){
unsigned char I;
unsigned char sdata=0;
*sda_dir &=~sda_mask; //input
*SDA |= sda_mask;
for(I=0; I < 8; I++)
{
*SCL |= scl_mask;
sdata <<=1;
if(*SDA & sda_mask ) sdata |=1;
*SCL &= ~scl_mask;
}
*sda_dir |= sda_mask; // output
clk();
return(sdata);
}
void i2c::write_byte(unsigned char i2caddr,unsigned char memadr, unsigned char memdata){
start();
write(i2caddr);
write(memadr);
write(memdata);
stop();
}
unsigned char i2c::read_byte(unsigned char i2caddr,unsigned char memadr){
unsigned char eedata=0;
start();
write(i2caddr);
write(memadr);
start();
write(i2caddr+1);
eedata=read(ACK);
stop();
return(eedata);
}
kullanımı
#include <ior8c24_25.h>
#include "i2c.h"
i2c i2c_eeprom;
i2c i2c_pot;
i2c i2c_device1;
i2c i2c_device2;
unsigned char x,y,z;
int main(){
i2c_eeprom.set_hardware(&p3,1,&p2,2,&pd3,&pd2);
i2c_pot.set_hardware(&p1,7,&p2,6,&pd1,&pd2);
i2c_device1.set_hardware(&p3,4,&p2,5,&pd3,&pd2);
i2c_device2.set_hardware(&p1,6,&p1,2,&pd1,&pd1);
i2c_eeprom.write_byte(0xA0, 12, 122);
x= i2c_eeprom.read_byte(0xA0, 12);
y= i2c_device2.read_byte(0xE0,x);
i2c_device1.write_byte(0xD0,y,x);
z=i2c_pot.read_byte(0xB0,156);
return 0;
}
Bu arada, yanlış anlaşılma olmasın: Nesne tabanlı programlamayı çok seven biriyim. C'den önce Java öğrendim. C#'la da uğraşmışlığım var. Hayatta karşıma çıkan hemen her sorunu (özellikle de programlama sorunlarını) nesne mantığı ile düşünür ve çözüm ararım.
Ancak işletim sistemi olmadan nasıl malloc veya new yazabileceğimizi anlamış değilim. Benim bildiğim kadarıyla (ki burada aksinin söylendiğini görene kadar da bildiğimden oldukça emindim) boş alan isteyebilmek için, bu alanı isteyebileceğiniz bir otorite olması gerekir. Yani malloc bir alan istemidir ve arkada bu isteme cevap verebilecek bir işletim sistemi gerekir. Zaten malloc nadir de olsa null döndürebilir. Bunun anlamı, işletim sisteminin size istediğiniz alanı veremediğidir. Bu durumda ona göre işlem yapmak gerekir.
gerbay hocam, bunun nasıl mümkün olabileceğini anlatıp konuya açıklık getirebilirsen sevinirim.
-IAR C Library Functions dokumani soyle diyor:
malloc void *malloc(size_t size)
Description
Allocates a memory block for an object of the specified size.
The availability of memory depends on the size of the heap. For more information
about changing the heap size, see the IAR C Compiler Reference Guide.
-EWARM Compiler Reference dokumani da soyle diyor:
Dynamic memory on the heap
Memory for objects allocated on the heap will live until the objects are explicitly
released. This type of memory storage is very useful for applications where the amount
of data is not known until runtime.
In C, memory is allocated using the standard library function malloc, or one of the
related functions calloc and realloc. The memory is released again using free.
In C++, there is a special keyword, new, designed to allocate memory and run
constructors. Memory allocated with new must be released using the keyword delete.
MCU uzerinde calisinca otorite biz oluyoruz. Yani birileri bizden malloc talebinde bulunabilir. Ancak soyle dusunelim. Bir fonksiyon icerisinde degisken tanimladik. int turunden olsun. o fonksiyon cagrilana kadar o degisken RAM'de degil. Cagrildiginda bir adres belirleniyor. Fonksiyon bitince de RAM'den siliniyor. Bu da aslinda dinamik bir adres atamasidir. Yani hepsini static girmeliyiz demissiniz, pek mumkun degil gibi gorunuyor.
Yani isletim sistemi dinamik yer saglayabiliyorsa, ve MCU uzerinde biz calisirken, aslinda MCU'nun isletim sistemi oluyorsak (yanlisim varsa duzeltin), bu dinamik yer saglama islemini kendimize yapabiliriz diye dusunuyorum.
Dinamik nesne oluşturma için yazdığım kod ve IAR'ın derleme sonunda ürettiği kod aşağıda. Kodu denemediğim için çalışıp çalışmadığını bilmiyorum.
int main(){
i2c *i2c_ptr;
i2c_ptr= new i2c;
i2c_ptr->set_hardware(&p3,1,&p2,2,&pd3,&pd2);
i2c_ptr->write_byte(0x80,x,15);
i2c_eeprom.set_hardware(&p2,6,&p3,1,&pd2,&pd3);
i2c_eeprom.write_byte(0xA0, 12, 122);
12 int main(){
\ main:
\ 000000 7DBF ADD.B #-0x1, SP
13 i2c *i2c_ptr;
14 i2c_ptr= new i2c;
\ 000002 75C00A00 MOV.W #0xa, R0
\ 000006 FD...... JSR.A `??operator new`
\ 00000A 7305 MOV.W R0, A1
15
16 i2c_ptr->set_hardware(&p3,1,&p2,2,&pd3,&pd2);
\ 00000C 7DE2E600 PUSH.W #0xe6
\ 000010 7DE2E700 PUSH.W #0xe7
\ 000014 7DE2E400 PUSH.W #0xe4
\ 000018 C302 MOV.B #0x2, R0H
\ 00001A C401 MOV.B #0x1, R0L
\ 00001C 75C2E500 MOV.W #0xe5, R2
\ 000020 7354 MOV.W A1, A0
\ 000022 FD...... JSR.A ??set_hardware
\ 000026 7DB6 ADD.B #0x6, SP
17 i2c_ptr->write_byte(0x80,x,15);
\ 000028 7CE200 PUSH.B #0x0
\ 00002B 7CE20F PUSH.B #0xf
\ 00002E 0F.... MOV.B x, R0H
\ 000031 74C080 MOV.B #0x80, R0L
\ 000034 7354 MOV.W A1, A0
\ 000036 FD...... JSR.A ??write_byte
\ 00003A 7DB2 ADD.B #0x2, SP
18
19 i2c_eeprom.set_hardware(&p2,6,&p3,1,&pd2,&pd3);
\ 00003C 7DE2E700 PUSH.W #0xe7
\ 000040 7DE2E600 PUSH.W #0xe6
\ 000044 7DE2E500 PUSH.W #0xe5
\ 000048 C301 MOV.B #0x1, R0H
\ 00004A C406 MOV.B #0x6, R0L
\ 00004C 75C2E400 MOV.W #0xe4, R2
\ 000050 75C4.... MOV.W #i2c_eeprom, A0
\ 000054 FD...... JSR.A ??set_hardware
\ 000058 7DB6 ADD.B #0x6, SP
20 i2c_eeprom.write_byte(0xA0, 12, 122);
\ 00005A 7CE200 PUSH.B #0x0
\ 00005D 7CE27A PUSH.B #0x7a
\ 000060 74C10C MOV.B #0xc, R0H
\ 000063 74C0A0 MOV.B #0xa0, R0L
\ 000066 75C4.... MOV.W #i2c_eeprom, A0
\ 00006A FD...... JSR.A ??write_byte
\ 00006E 7DB2 ADD.B #0x2, SP
hocam bilgiler icin tesekkurler, cok aciklayici olmus gercekten. elinize saglik.
yani arka planda mutlaka benzer algoritmalar kullaniyordur ancak C++'da bu yapi dile entegre sekilde değil mi?
Bilgilendirmeler için teşekkürler arkadaşlar. Bir yanlışımı düzeltmiş oldunuz.
Konuyla ilgili Microchip'in bir uygulama notunu buldum: AN914 (http://www.google.com.tr/url?sa=t&rct=j&q=microchip%20application%20note%20dynamic%20memory%20allocation&source=web&cd=2&ved=0CC0QFjAB&url=http%3A%2F%2Fww1.microchip.com%2Fdownloads%2Fen%2Fappnotes%2F00914a.pdf&ei=N4wNT5iBBcegOsO3jJMH&usg=AFQjCNGztdkAqyJGEgrQ86g0vi-PlFvi7w&sig2=PuDWrewAt-_smmyCuy0shw)