STM32F429 ile Çalışmalarım

İki Main Tek İşlemci!


Merhabalar, picproje forumunda bir arkadaşın sorusu üzerine açıklama yapmıştım. İki farklı yazılımı tek bir işlemci üzerinde çalıştırmak ve aralarında nasıl geçiş yapacağımıza dair. Buradan da paylaşmak istedim.

Şu şekilde bir gidişat yapacağız, 2 farklı projeyi demo bir karta yükleyerek birbiri arasında bir geçiş yapacağız.

Kullandığım kart :NUCLEO-F401RE

Öncelikle kullandığınız işlemcinin “Reference Manual” dosyasını internet üzerinden bulalım. Bu dosyayı bulduktan sonra, “Embedded Flash memory in STM32F401xB/C and STM32F401xD/E” başlığına gidiyoruz.

Burada flash hafızamızın layoutunu görebiliriz ve uygulamaları koyacağımız sektör adreslerini görmekteyiz.

Uygulamada Sector 0’da bir uygulama, Sector 1’de ise diğer uygulamayı barındıracağım ve aralarında geçiş yapacağım.

Öncelikle gelin Sector 0’a yapacağımız uygulamayı hazırlayalım. Öncelikle Sector 1’e atlamak için bir fonksiyon yazalım.

static void JumpFunctionSectorOne(void)
{
	typedef void (*Jump)(void);
	Jump JumpFunc;
	uint32_t JumpAddr = *(uint32_t *)(0x08004000 + 4);
	JumpFunc = (Jump)JumpAddr;
	__set_MSP(*(__IO uint32_t*)0x08004000);
	JumpFunc();
}

Burada

*(uint32_t *)(0x08004000 + 4)

4 ofset vermemizin sebebi zıplayacağımız yerde bulunan vector tablosunda (startup_stm32f4xx dosyasında bulabilirsiniz.). Reset Handler ikinci sırada bulunan bir fonksiyon göstericisi ve word cinsinden adreslendiği için + 4 eklemekteyiz.

Aynı şekilde main stack pointer’i set etmeyi unutmayın, daha sonrasında tanımsız davranışlar yaşamamak için.

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler

Kodu derleyip yüklerken eğer defaultta bulunan sector adresinden başka bir yere yükleme yaparsanız, hem kodun barınacağı adresi hem de vector tablosunun yer alacağı adresi değiştirmeniz gerekmekte. Aksi takdirde jump ettğiniz yerde çakılır uygulamanız, bu oldukça kritik. Biz bu uygulamayı sector 0 yani default alanda barındaracağımız için herhangi bir değişiklik yapmayacağız şu anda. Fakat sector 1 içerisinde çalışacak uygulama için bu değişiklikleri az sonra yapacağız.

Main içerisinde önce uygulamanın başladığını ve bir süre sonra jump edeceğini söylüyoruz.

printf("Cihaz ayakta, Cihaz 0.sektorden basladi");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
	printf("\r\n Uygulama Jump Edecek \r\n");
	HAL_Delay(3000);
	JumpFunctionSectorOne();
	printf("\r\n Kod buraya ulasmadi \r\n");
		
    /* USER CODE BEGIN 3 */
  }

Şimdi ise, yazacağımı kodu Sector 1’e koyalım ve Sector 0’a jump yapmasını sağlayalım. Yani bir önce bahsettiğimiz uygulamanın tam tersi. Öncelikle rom adresini değiştirmemiz gerekmekte.
Eğer keil kullanıyorsanız, Option For Target kısmında bulunan IROM1 kısmından bu adresi değişterebilirsiniz. Uygulamayı Sector 1 içerisinde barındaracağım için, reference manual üzerinden oranın adresini aldım ve 0x8004000 şeklinde IROM1 kutucuğunu düzenledim. Tabi bu kadarı yeterli mi? Hayır. Şimdi ise vector tablomuzu düzenlememiz gerekmekte. Bunun için, system_stm32f4xx.c içerisine gidelim.

#define VECT_TAB_OFFSET  0x8004000 /*!< Vector Table base offset field. 
                                   This value must be a multiple of 0x200. */

Yukarda görmüş olduğunu kısım ilk uygulamamız da 0x00 olarak tanımlıydı fakat şimdi farklı bir sector de barındırdığımız kodu çalıştıracağımız için buraya offset veriyoruz.

Sıra geldi Sector 0’a zıplamak için yapmamız gerekenlere, bunun için şöyle bir fonksiyon yazalım, ilk uygulamaya benzer şekilde.

static void JumpFunctionSectorZero(void)
{
	typedef void (*Jump)(void);
	Jump JumpFunc;
	uint32_t JumpAddr = *(uint32_t *)(0x08000000 + 4);
	JumpFunc = (Jump)JumpAddr;
	__set_MSP(*(__IO uint32_t*)0x08000000);
	JumpFunc();
}

Şimdi ise main içerisinde uygulamanın sector 1den başladığını ve jump edeceğini belirtelim.

printf("Cihaz ayakta, Cihaz 1.sektorden basladi");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		printf("\r\n Uygulama Jump Edecek \r\n");
		HAL_Delay(3000);
		JumpFunctionSectorZero();
		printf("\r\n Kod buraya ulasmadi \r\n");
		
    /* USER CODE BEGIN 3 */
  }

Şimdi bu kodu da kartımıza yükleyelim, yalnız karta yüklerken flashı temizlemeyin, çünkü sector 0’a yüklemiş olduğumuz bir yazılım var. Eğer temizlerseniz uygulama çalıştıktan bir sonra sector 0’a zıplayacak ve FF olduğu için hardfault’a düşeceksiniz.

İşte bu kadar, iki farklı uygulamayı bu şekilde tek bir kart işlemcide çalıştırabilir ve arasında geçiş yapabilirsiniz.

Eğer üretim kodunuzda böyle yapı barındaracaksınız bazı korumaları almanızda fayda var, başka bir sektöre geçiş yapmadan önce o sektörde bir yazılım olup olmadığını kontrol etmek gibi.

#bootloader, #gomulusistemler, #stm32-iki-main-fonksiyonu

League Of Legends SS Lane-Oto Zhonya Keyboard


Yazıya geçmeden önce bir çekiliş düzenliyorum , Üç boyutlu yazıcı elektroniğinden , robot kolunu kadar.Ayrıntılar için şurada ki videoya göz atmayı unutmayın.Bol şanslar.

 

Uzun bir süredir LoL oyuncusuyum , hemen hemen her heronun özelliklerini bilirim de , oynadığım hero sayısı 3tür 5tir kızlar hoştur.Anaç ruhumdan dolayı support herolar ile oynarım , bazen de middle geçerim karşımda ki ezerim harbi harbi ezerim ama.Oyunda kasılan itemlerde aktif olarak kullanılabilecekleri hep kullanmayı unuturum.Bir de uzun yıllardır oynarım oyunu da hala unuturum ama.Bir de ss olayları var , yani rakip sizin laneden çekildiği zaman başka lane gidebilir orada ki arkadaşınızı sıkıştırabilirler diye ss atarsınız.Anlamı kabaca adam burada yok muhtelemen sana geliyor bak diye.Bunu oyunda mouse olarak yapabilirsiniz bazı öküzler(bkz: ben) haritayı takip etmez.O yüzden ss verdiğinizi göremez bunun için yazı diliyle anlatmanız gerek. Bot ss , Mid ss , Top ss gibi.Bunu klavyeden yazmak yerine bir usb hid yapayım butona bağlayım da kendisi yapsın abi dedim , donanım kartı olarak stm32f103 kullandım 1dolarlık bir ürün kendisi ama boyuna bakılmayıp işlevi önemsencek türden bir kart.

İkinci olay ise , zhonya itemi bu item tam siz ölecekken basarsanız 3-4 artık ne kadarsa tam hatırlamıyorum saniye size vurulmasını engeller hayat kurtaran itemdir , hatta oyun bile kazandırabilir size bu item.Tabi ben itemi çoğu oyun kasarım hele de anivia oynarken hem kendi pasifinden hem de zhonyadan aldığım güçle rakibi deli ederim.

Bu zhonya içinde şöyle bir uygulama hazırladım amaç can olduğuna göre , ekranda ki can değerini arka planda çalışan bir uygulama ile aldım iteme atadağım klavye tuşuna bastırdım.Tresh değerim 100 gibi bir şeydi ama bazen nasıl oluyorsa adamın canını aldığı oldu , canım fulle yakın iken adamın canına göre zhonya basıp takımın bana sövmesine sebep oldu , genel oyun arenasında girdiğim için normal , bayram bayram veletler doluştu oyuna.

Şu ss olayı problemsiz çalışıyor zhonya da problem var onları da halledip yayınlayacağım muhtelemen.Çalıştığım için çok vaktim olmuyor ama amaçsız projelere devam elbet 😀

Hırs yaptım komple yapay zeka yazıp Elon Musk’ın yapay zekasını yenip bayrakları astırmaya.

Donanım kısmı oldukça basit aslında iki buton , bir tane kart , bir de elektrik kablo kutusu aldım(çok önemli ya)

WhatsApp Image 2017-09-02 at 22.07.16 (1)WhatsApp Image 2017-09-02 at 22.07.20WhatsApp Image 2017-09-02 at 22.07.23WhatsApp Image 2017-09-02 at 22.07.44

 

 

İlk denemeleri yaparken yanlış zhonya lar yanlış ss ler den sonra takım

Untitled.png

FreeRTOS+LwIP+CubeMx+STM32F7xx+WebServer{GPIO KONTROL}


Herkese SELAMLAR , umarım bu kaynağı başlıktaki konular içerisinde saç baş yolmadan bulmuşsunuzdur zira ben biraz yoldum.Bugün CubeMX kullanarak ETH üzerine Lwip kuracağız ardından da bunları FreeRTOS da çalıştıracağız , FreeRTOS konusunu için şuraya bakabilirsiniz.

Öncelikle LwIP nedir sorusuna cevap vererek başlasak iyi olur.Açılımı LightWeight Ip olan bu uygulama temelinde TCP/IP protokolünü bulunduran  bağımsız bir uygulama diyebiliriz.

Ana özellikleri şunlardır:
– Protokoller: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE
– DHCP istemcisi, DNS istemcisi (mDNS ana makine resolver dahil), AutoIP / APIPA (Zeroconf), SNMP (V1, v2c, v3, özel MIB desteği ve MIB derleyicisi)
– API’ler: gelişmiş performans, isteğe bağlı Berkeley benzeri soket API’si için özel API’ler
– Genişletilmiş özellikler: Birden fazla ağ arabirimi üzerinden IP iletimi, TCP tıkanıklığı kontrolü, RTT tahmini ve hızlı kurtarma / Hızlı retransmit
– Addon uygulamaları: HTTP (S) sunucu, SNTP istemcisi, SMTP (S) istemcisi, ping, NetBIOS ad sunucusu, mDNS yanıtlayıcı, MQTT istemcisi, TFTP sunucusu.

Şurada içinde kaybolacağınız bir döküman var.CubeMx ile birlikte gelen örnekler içerisinde bir LwIP örneği mevcut(FreeRTOS içeriyor , C:\Users\xxxxx\STM32Cube\Repository\STM32Cube_FW_F7_V1.4.0\Projects\STM32746G-Discovery\Applications. Dosya yolunda örneği bulabilirsiniz. )  ancak çok fazla .c ve .h dosyası mevcut gerek ekran ayarlamaları için gerekse farklı kullanımlar için çok açık bir proje değil.Özellikle üzerine bir şey eklemek istediğiniz zaman tanımlama çakışması ,  pin kontrolü gibi bir çok sorunlara karşılaşabiliyorsunuz.Hal böyle olunca sade bir uygulama yapmak istedim nitekim ciddi bir kaynak eksikliği var hem Türkçe hemde diğer dillerde.(İngilizce olarak değil  , cidden diğer dillerde).Derleyici olarak Keil kullanacağız , AC6 da kodu generate ettiğim  zaman bir kaç hata aldım çözülmesi zor şeyler değil ama eclipse tabanlı şeyleri hiç sevemedim nedense o yüzden Keil ile devam ediyorum.

Öncelikle CubeMx açıyoruz , kullandığım kart STM32F746G DISCOVERY , bunun için açılışta NEW PROJECT–>KARTIMI SEÇİYORUM.

Önemli bir diğer nokta , kartı seçerken sol üst tarafta bulunan “Initialize all IP with their defaul Mode” kutucuğunu işaretleyin.Bunun anlamı şudur  , Kart üzerinde bulunan çevre birim aygıtları için hem pin düzenini hem de varsayılan modları otomatik olarak ayarlar , tüm çevre birim aygıtları için C başlatma kodunu ürettiriyoruz.Genel bir uygulama için tercih edilmelidir.

Capture.PNG

Şimdi ekranda kotrolcümüzün pin yapısı var görüldüğü gibi hemen hemen her pin bir göreve atanmış , sol taraftada kullanıp kullanmayacağımız belli olmayan bir sürü çevre birim aktif halde.Sadeleştirmek ve atamayı kendimiz yapmak için Sol üst köşede bulunan Pinout>Clear Pinouts yapıyoruz.

Capture.PNG

Clear pinout yaptıktan sonra ;

Capture.PNG

Şimdi asgari olarak kartımızın çalışması için gerekli ayarlamaları yapalım.

Sırasıyla RCC-SYS-ETH-LWIP-FREERTOS kullanacağımızı belirttik(sol taraf)

1234

Zaten ETH birimini aktif etmeden LwIP enable etmeniz mümkün değil.

Şimdi sol üst tarafta bulunan Pinout penceresinin yanındaki CLOCK CONFIGURATION kısmına geliyoruz.Ekranın ortasında HCLK(Mhz) olarak 168 görüyorsunuz , yazılarımı takip eden var STM32F429DISC  için max çalışma frekansıydı ancak bu kart için 216 ve oraya 216 yazarak Enter tuşuna bastığımız da gerekli ayarlamaları kendisi yapıyor.

5.PNG

Şimdi eklediğimiz Middleware katmanlarımızı ve Connectivity bölümümüzde gerekli ayarları yapacağız.Bunun için Clock Conf yanındaki Configuration bölümüne geçiyoruz.Karşınıza şöyle bir sayfa gelecek.

Capture.PNG

İlk olarak Connectivity kısmından başlayalım.ETH butonuna bir defa tıklamanız yeterli.Şimdi yapacağımız ayar çok kritik , CubeMx yazılımda bir bug var bu bug başkaları tarafından rapor edilmiş zaten sizin ki güncel bir sürüm değilse açılan pencerede kırmızı ok ile gösterdiğim yerin değeri 1 çıkacak.ONU 0 YAPMAMIZ GEREKLİ.Son ayar şöyle olacak.OK deyip ayarımızı kaydediyoruz.

Capture

FreeRTOS kısmında bir ayar yapmayacağız , default olarak bir adet TASK kendinden geliyor zaten eğer başka tasklar oluşturup onları da kontrol etmek isterseniz FreeRTOS kısmından yapabilirsiniz.

LwIP penceresine geçiyoruz.Burada  “General Settings” kısmında bazı ayarlar yapacağız ,bunlardan ilki LWIP_DHCP  disable etmek ve elimizde ip adresini girmek olacak.Disable etmeden ip adresi atamanız için gerekli satırlar aktif olmaz.Burada önemli olan bir diğer kodu elle girdiğiniz ip adresiniz bilgisayar ethernet kartı ile eşleşmesi.CMD konsolunda ipconfig yazdıktan sonra (bilgisayarınızda LAN kablosu bağlı olması gerekiyor) orada ki adresi görebilirsiniz , orada ki adres 255 gibi değerler ile başlıyor ise , bilgisayarınıza elle ip vermeniz gerekiyor.Aşağıda ki görsel 192.168.0.10 kit için atadığım ip adresi , bilgisayarımın ise 192.168.0.15(elle girildi).Yine OK diyerek ayarlarımızı kaydediyoruz.

Capture.PNG

Şimdi kodu generate edeceğiz ben daha öncede belirttiğim için Keil için kodumu generate edeceğim.Generate etmeden önce hazırlayacağımız yazılımda Web Server üzerinden bir led kontrol edeceğiz.Bu yüzden kit üzerinde bulunan I portuna bağlı 1.pini output olarak ayarlayalım.Bunun için CubeMx arayüzünde tekrar Sol üst taraftan pinout kısmına geliyoruz.Ortada bulunan pinlerden PI1 seçerek GPIO_OUTPUT seçeneğini aktif ediyoruz.

Capture.PNG

Artık kodumuzu generate edelim.Şimdi ise Keil arayüzüne geçiyoruz ve kodumuzu derleyip herhangi hata almadığımızdan emin oluyoruz.

Capture.PNG

Projemizin bulunduğu konuma gelerek Inc klasörü içine httpserver-netconn.h ve Src klasörüne gelerek httpserver-netconn.c dosyalarını ekliyoruz.Netconn dediğimiz bir api ve biz bu api kullanarak uygulamamızı hazırlayacağız.

httpserver-netconn.h

#ifndef __HTTPSERVER_NETCONN_H__
#define __HTTPSERVER_NETCONN_H__
#include "lwip/api.h"
void http_server_netconn_init(void);
#endif /* __HTTPSERVER_NETCONN_H__ */

httpserver-netconn.c dosyasını github hesabımda bulabilirsiniz .

https://github.com/volkanunal/LwipFreertosWebServer

Main.c içerisinde httpserver-netconn.h dosyasını çağırıyoruz , doğru eklediysek herhangi bir hata vermeyecektir.

Capture.PNG

Yine main.c içerisinde Task’ımızın bulunduğu fonksiyon içerisinde http serveri init etmemiz için gerekli fonksiyonu yazıyoruz.


void StartDefaultTask(void const * argument)
{
/* init code for LWIP */
MX_LWIP_Init();
<strong>http_server_netconn_init();</strong>
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)
{
osThreadTerminate(NULL);
}
/* USER CODE END 5 */
}

Artık programı kitimize yükleyebiliriz , programı attıktan sonra çalışması için resetlemeniz gerekmekte bunu yapmak istemiyorsanız keil arayüzünde option for target (sihirbaz çubugu gibi bir şey var ) oraya tıklarak debug->Settings(ST-LİNK DEBUGGER)->Flash Dowloand ve orada ki Reset and Run kutucuğunu işaretlemeniz gerekmekte.

Programı yükledikten sonra tarayıcımızı açıyoruz ve adres çubuguna 192.168.0.10 yazıyoru. Thats ALL baby !

Capture.PNG

ON-OFF butonları ile kit üzerinde ki ledi kontrol edebilirsiniz.Bu arada led arka tarafta Reset butonunun bitişiğinde bulunuyor.

Stm32f103xx USB MEDIA HID Uygulaması


Günaydınlar , Tünaydınlar ,İyi akşamlar , iyi geceler günün hangi saatinde buraya düştüyseniz artık 🙂 , bugün stm32f103 kartı ile media hid uygulaması yapacağız.Kartımızı kullanarak bilgisayarımızın sesini kısacağız , yapacağımız bu örnekten bir çok farklı proje için temel alabilirsiniz.Başlamadan önce , daha önce yaptığımız usb mouse hid uygulamasını izlemeniz faydalı olacaktır.Çünkü tekrardan CubeMx adımlarını göstermeyeceğim.

 

CubeMx üzerinden projemizin kemik yapısını oluşturduktan sonra ki adımları listeliyorum.

usbd_hid.c dosyası içerisine gir.

HID_MOUSE_ReportDesc–> yerini bul

__ALIGN_BEGIN static uint8_t HID_CUSTOM_ReportDesc[HID_CUSTOM_REPORT_DESC_SIZE] __ALIGN_END = {
// 78 bytes
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x19, 0xE0, // Usage Minimum (0xE0)
0x29, 0xE7, // Usage Maximum (0xE7)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x03, // Report Count (3)
0x75, 0x08, // Report Size (8)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x64, // Logical Maximum (100)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x29, 0x65, // Usage Maximum (0x65)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x02, // Report ID (2)
0x05, 0x0C, // Usage Page (Consumer)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x09, 0xB5, // Usage (Scan Next Track)
0x09, 0xB6, // Usage (Scan Previous Track)
0x09, 0xB7, // Usage (Stop)
0x09, 0xB8, // Usage (Eject)
0x09, 0xCD, // Usage (Play/Pause)
0x09, 0xE2, // Usage (Mute)
0x09, 0xE9, // Usage (Volume Increment)
0x09, 0xEA, // Usage (Volume Decrement)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
};


Aynı dosya içerisinde aşağıda ki işlemleri yap.

bInterfaceSubClass->0 a götür
nInterfaceProtocol->1 e götür
—————————————————————————————
usbd_hid.h dosyasına git
HID_EPIN_SIZE size 5 yap
ID_CUSTOM_REPORT_DESC_SIZE 78 yap
—————————————————————————————

Main.c içerisine gel ve int main() içerisine tanımları yap.

struct mediaHID_t {
uint8_t id;
uint8_t keys;
};
struct mediaHID_t mediaHID;
mediaHID.id = 2;
mediaHID.keys = 0;
eklemen gereken yer kod yapısı
—————————————————————————————

while(1) içerisinde neler yapmak istediğin.

mediaHID.keys = 0x80 //ses kısmak için desc
USBD_HID_SendReport(&hUsbDeviceFS, &mediaHID, sizeof(struct mediaHID_t));
HAL_Delay(30);
mediaHID.keys = 0;

 

Faydalı linkler: