Forum: Mikrocontroller und Digitale Elektronik Aufstieg STM32F4 zu F7. Probleme mit der Geschwindigkeit.


von Matthias F. (frank91)


Lesenswert?

Hallo alle zusammen.

Ich habe eine Platine welche mit einem STM32F429BIT bestückt ist.
Diese Platine steuert ein Display mittels emWin an.
Außerdem habe ich weitere Peripherien wie eine LAN Schnittstelle (lwip).
Bei der Lan Schnittstelle habe ich momentan nur das TCP ECHO Client 
Beispiel aus den Cube Beispielen übernommen.
Alles funktionierte tadellos.
Allerdings musste ich aus mehreren Gründen die Platine überarbeiten und 
auf den Pingleichen STM32F767BIT wechseln.

Dies ist mein erstes Projekt mit einem F7.

Um etwaige Fehler bei der überarbeiteten Platine besser eingrenzen zu 
können habe ich 2 Stück meiner Prototypen mit meinem ursprünglichem 
STM32F429 bestückt.
Ansonsten ist die Hardware die selbe.

Wenn ich die Software mit dem STM32F429 überspiele funktioniert alles.
Anschließend habe ich ein neues Cube Projekt für den F7 erstellt. Die 
Software ist im Prinzip die selbe. Auch der Clock Tree wurde gleich 
konfiguriert.

Allerdings habe ich jetzt mit Problemen zu kämpfen.
Mein Ethernet ist sehr langsam. Bei meinem Terminal Programm dauert es 
manchmal ganze 2 Sekunden bis ich eine Antwort zurück bekomme.
Mir ist aufgefallen, dass dieses Problem nicht auftritt wenn ich STemWin 
nicht einbinde.
Wissen muss man hierbei dass die Verwaltung der Ethernet Libary (lwip) 
in der Main über ein Unterprogramm geschieht welches hier durchgehen 
aufgerufen wird.

Nun bin ich davon ausgegangen dass hier etwas falsch initialisiert 
wurde.
Allerdings finde ich keinen Initialisierungsfehler.

Um zu testen ob emWin mich ausbremst habe ich eine Variable erstellt 
welche bei jedem Durchgang der main schleife erhöht wird.
Dabei kam ich zu folgendem Ergebniss:

F4 komplette Software: ~110.000 Durchgänge pro Sekunde

F7 komplette Software : ~nur 37.000 Durchgänge pro Sekunde
F7 ohne GUI_Exec in der Main: ~110.000 Durchgänge pro Sekunde. 
Allerdings ist das Ethernet seltsamerweiße immer noch so langsam.
F7 komplett ohne STemWin: ~470.000 Durchgänge pro Sekunde. Lan läuft 
flüssig.

Fällt hierbei jemanden ein an was das liegen könnte?
Ich denke dass möglicherweiße irgendwas bei der Initialisierung des F7 
falsch gemacht. Etwas das es vielleicht beim F4 noch nicht gab. 
Zumindest könnte ich es mir nur so erklären.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Sind die Caches richtig initialisiert und eingeschaltet? Liegen DMA 
Speicherbereiche im richtigen Memory? Stimmen Taktfrequenz und 
Waitstates?

von Matthias F. (frank91)


Lesenswert?

Also es gibt ja jetzt seit dem F7 einen D- und einen I-Cache.
So wirklich hab ich den Sinn dahinter noch nicht verstanden.
Wenn ich beide allerdings initialisiere finde ich die Platine allerdings 
gar nicht mehr im Netzwerk.
Außerdem fällt dann gelegentlich das Bild für circa eine halbe Sekunde 
aus.
In den Beispielen sind allerdings beide Caches stehts initialisiert.
Gibt es hier etwas einzustellen?
Laut Cube nicht.

Am DMA und den Speicherbereichen habe ich nichts verändert.
Wenn ich die Cube Beispiele von F4 und F7 vergleiche sind hier auch 
keine Unterschiede zu finden.

Takfrequenzen sind wie gesagt bei beiden Controllern gleich gewählt 
worden.

Waitstates?

von Martin C. (Gast)


Lesenswert?

Hallo,

ich habe nur mit dem SAME70 von Atmel/Microchip Erfahrungen,
welcher auch ein M7 ist.

Wenn der D(aten)-Cache und DMA zusammen in Betrieb sind, bekommt der 
Cache die über DMA gelesenen Daten nicht mit.
Damit die CPU die eingelesenen Daten sehen kann, muss der Cache 
invalidiert werden, er füllt sich dann aus dem RAM erneut auf. Ich habe 
es mir einfacher gemacht und die vom Netzwerk-Stack benutzten Bereiche 
als nicht cachebar eingestellt (in der Cortex M7 MPU).

Wie sieht es denn mit der Taktfrequenz aus ?
Zuerst läuft die CPU nur mit der Grundfrequenz (12 MHz ?), bis die PLL 
zur Taktvervielfachung initialisiert wurde.

Gruß,
Martin C.

von Matthias F. (frank91)


Angehängte Dateien:

Lesenswert?

Vielen dank schon einmal für deine Hilfe!!

Ich denke so langsam komme ich der Sache näher.
Ich habe mir die Beispiele von STM noch einmal genauer angesehen.
Hier wird vor dem Enablen von D- und I-Cache einige MPU Funktionen 
aufgerufen.
Anfangs dachte ich das dieses MPU nur dient um in irgendeiner weiße den 
Speicher zu schützen.

Ich habe nun die entsprechenden Applikation Notea für caches und MPU 
überflogen.
Hier gibt es tatsächlich einen Eintrag über Probleme mit dem DMA in 
Kombination mit dem Datencache.
Ab Seite 8:
http://www.st.com/content/ccc/resource/technical/document/application_note/group0/08/dd/25/9c/4d/83/43/12/DM00272913/files/DM00272913.pdf/jcr:content/translations/en.DM00272913.pdf

Hier werden außerdem einige Lösungen genannt. Unter anderem den Bereich 
nicht Cachebar zu machen, so wie du sagtest.

Die MPU Beispiele von STM sehen wie folgt aus:
(STM32F756BI)
1
/**
2
  * @brief  Configure the MPU attributes as Write Through for SRAM1/2.
3
  * @note   The Base Address is 0x20010000 since this memory interface is the AXI.
4
  *         The Region Size is 256KB, it is related to SRAM1 and SRAM2  memory size.
5
  * @param  None
6
  * @retval None
7
  */
8
9
10
static void MPU_Config(void)
11
{
12
  MPU_Region_InitTypeDef MPU_InitStruct;
13
  
14
  /* Disable the MPU */
15
  HAL_MPU_Disable();
16
17
  /* Configure the MPU attributes as WT for SRAM */
18
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
19
  MPU_InitStruct.BaseAddress = 0x20010000;
20
  MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
21
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
22
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
23
  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
24
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
25
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
26
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
27
  MPU_InitStruct.SubRegionDisable = 0x00;
28
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
29
30
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
31
32
  /* Enable the MPU */
33
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
34
}

da sich der SRAM bei mir an einer anderen Stelle (siehe Anhang) befindet 
habe ich das Unterprogramm angepasst:
(STM32F767BI)
1
{
2
  MPU_Region_InitTypeDef MPU_InitStruct;
3
4
  /* Disable the MPU */
5
  HAL_MPU_Disable();
6
7
  /* Configure the MPU attributes as WT for SRAM */
8
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
9
  MPU_InitStruct.BaseAddress = 0x20020000; //0x20010000;
10
  MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;//MPU_REGION_SIZE_256KB;
11
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
12
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
13
  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
14
  MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
15
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
16
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
17
  MPU_InitStruct.SubRegionDisable = 0x00;
18
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
19
20
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
21
22
  /* Enable the MPU */
23
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
24
}

Seit dem ich diesen Teil im Code übernommen habe kann ich gleichzeitig 
das Lan und StemWin verwenden.
Das Lan ist jetzt trotz eingebunden D- und i-Cache erreichbar.

Allerdings habe ich jetzt wieder die kurzen Bildaussetzer, welche ich 
bereits in meinem vorherigen Post erwähnt habe.
Außerdem kommt es gelegentlich vor, dass einzelne Nachrichten vom Lan 
wieder einen kurzen Augenblick dauern.
Insgesamt ist es jetzt zwar viel schneller aber durch die gelegentlichen 
Aussetzer für meine spätere Applikation nicht hinnehmbar.

Ich werde mich wohl in die Caches, ihre Bedeutung und den MPU noch 
genauer einlesen müssen. Vielleicht habe ich hier noch etwas übersehen.

Oder erkennt jemand eine Abweichung / Fehler in meinem Code?

von 32zuterrtzkutehte (Gast)


Lesenswert?

wichtiges thema ist auch aligning
ich habe den LAN buffer in den extra 16K SRAM gelegt
dazu auch passend die MPU setzen ...

im Linkerfile habe ich alles auf ALIGN(8) gesetzt

hae festgestellt das größere Projekte irgendwann  diese bremseffekte 
zeigen
wenn man jedoch aligning beachtet gehts ...
ich habe immer auf O2 optimiert
dann läuft auch der LWIP gut

LwIP hat einen eigenen Heap und nutzt für die TCBs die eignenen malloc 
funtionen .. nicht die blockvariante



ich schaue morgen mal nach und zeig mal meine config..( lwip, ethernet , 
mpu PLL )

von 32zuterrtzkutehte (Gast)


Lesenswert?

achso

schau mal in den ethernet treiber

da gabs die variante mit der semaphore ... diese hatte bei mir nie 
sauber funtioniert.

von 32zuterrtzkutehte (Gast)


Lesenswert?

nutzt du das original Linker file?
das war ei mir damals auch prolematisch weil er a 0x200000 
durchaddressiert.
obwohl da 3 bereiche liegen

problem ist dann  der DMA der nicht überall sauber abeitet

von 32zuterrtzkutehte (Gast)


Lesenswert?

in der stm32f7xx_hal_conf.h :
1
#define ETH_RXBUFNB                    ((uint32_t)5U)       /* 5 Rx buffers of size ETH_RX_BUF_SIZE  */
2
#define ETH_TXBUFNB                    ((uint32_t)5U)       /* 5 Tx buffers of size ETH_TX_BUF_SIZE  */

ethernetif.c:
1
__ALIGN_BEGIN ETH_DMADescTypeDef    __attribute__((__section__(".eth"),used))  DMARxDscrTab[ETH_RXBUFNB]   __attribute__((aligned(8)));/* Ethernet Rx MA Descriptor */
2
__ALIGN_BEGIN ETH_DMADescTypeDef     __attribute__((__section__(".eth"),used))  DMATxDscrTab[ETH_TXBUFNB]   __attribute__((aligned(8)));/* Ethernet Tx DMA Descriptor */
3
__ALIGN_BEGIN uint8_t          __attribute__((__section__(".eth"),used))  Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]   __attribute__((aligned(8))); /* Ethernet Receive Buffer */
4
__ALIGN_BEGIN uint8_t         __attribute__((__section__(".eth"),used))  Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]   __attribute__((aligned(8))); /* Ethernet Transmit Buffer */
5
6
static err_t low_level_output(struct netif *netif, struct pbuf *p)
7
{  
8
  /* copy frame from pbufs to driver buffers */
9
  for(q = p; q != NULL; q = q->next)
10
  {
11
      ......
12
            ...
13
  }
14
15
  /* Prepare transmit descriptors to give to DMA */
16
  HAL_ETH_TransmitFrame(&heth, framelength);
17
18
  SCB_CleanDCache();
19
20
  errval = ERR_OK;
21
  
22
error:
23
  if ((heth.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET)
24
  {
25
          ....
26
          ...
27
  }
28
  return errval;
29
}
30
31
static struct pbuf * low_level_input(struct netif *netif)
32
{
33
  struct pbuf *p = NULL;
34
  struct pbuf *q;
35
  uint16_t len = 0;
36
  uint8_t *buffer;
37
  __IO ETH_DMADescTypeDef *dmarxdesc;
38
  uint32_t bufferoffset = 0;
39
  uint32_t payloadoffset = 0;
40
  uint32_t byteslefttocopy = 0;
41
  uint32_t i=0;
42
  
43
  SCB_CleanInvalidateDCache();
44
45
  /* get received frame */
46
  if (HAL_ETH_GetReceivedFrame_IT(&heth) != HAL_OK)
47
    return NULL;
48
49
....
50
...
51
...
52
}

lwipopts.h
1
#define MEMP_MEM_MALLOC         1
2
#define MEM_ALIGNMENT     4
3
#define WITH_RTOS     1
4
#define CHECKSUM_BY_HARDWARE    1
5
6
#define MEM_SIZE                 (42*1024)

linkerfile:
1
MEMORY
2
{ 
3
  RAM4   (xr)    : ORIGIN = 0x00000000, LENGTH = 16K   /* ITCM */
4
  ROM   (xr)    : ORIGIN = 0x08000000, LENGTH = 1024K 
5
  RAM   (xrw)    : ORIGIN = 0x20010000, LENGTH = 240K  /* SRAM1 */  
6
  RAM2  (xrw)    : ORIGIN = 0x2004C000, LENGTH = 16K   /* SRAM2 */
7
  RAM3   (xrw)    : ORIGIN = 0x20000000, LENGTH = 63K   /* DTCM */
8
}
9
...
10
...
11
...
12
13
14
15
  _siitcm = LOADADDR(.itcm);  
16
    /* ITCM RAM for critical functions */
17
  .itcm :
18
  {
19
    . = ALIGN(8);    
20
    _sitcm = .;        /* create a global symbol at itcm start */
21
    *(.itcm)
22
    *(.itcm*)    
23
    . = ALIGN(8);
24
    _eitcm = .;        /* define a global symbol at itcm end */
25
  } >RAM4 AT> ROM
26
27
  /* User_heap section*/      
28
  .dtcm (NOLOAD):
29
  {
30
    __dtcmstart = . ;
31
    . = ALIGN(8);
32
    *(.dtcm)
33
    *(.dtcm*)
34
    __dtcmend = . ;
35
    . = ALIGN(8);
36
    
37
    . = ALIGN(8);
38
    __stackend = . ;
39
    . = . + _Min_Stack_Size;
40
    __stackstart = . ;
41
    . = ALIGN(8);
42
  } >RAM3
43
    
44
  /* Ethernet memory*/          
45
  .eth (NOLOAD):
46
  {
47
    . = ALIGN(8);
48
    *(.eth)
49
    *(.eth*)
50
    . = ALIGN(8);
51
  } >RAM2 
52
53
...
54
...
55
...

ich nutze auch den ITCM RAM
für schnelle funktionen.
dafür müssen diese in den ITCM geladen werden:
1
void SystemInit(void)
2
{
3
  // copy to ITCM RAM !!!
4
  unsigned long *pulSrc, *pulDest;
5
  pulSrc = &_siitcm;
6
  for(pulDest = &_sitcm; pulDest < &_eitcm; )
7
  {
8
          *(pulDest++) = *(pulSrc++);
9
  }
10
...
11
...
12
...


RTOS nutze ich heap_5 mit 2 sections

MPU :
1
void MPU_Config(void)
2
{
3
  MPU_Region_InitTypeDef MPU_InitStruct;
4
5
  /* Disables the MPU */
6
  HAL_MPU_Disable();
7
    /**Initializes and configures the Region and the memory to be protected
8
    */
9
  MPU_InitStruct.Enable       = MPU_REGION_ENABLE;
10
  MPU_InitStruct.SubRegionDisable   = 0x0;
11
  MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
12
  MPU_InitStruct.AccessPermission   = MPU_REGION_FULL_ACCESS;
13
14
  MPU_InitStruct.DisableExec     = MPU_INSTRUCTION_ACCESS_DISABLE;
15
  MPU_InitStruct.IsShareable     = MPU_ACCESS_SHAREABLE;
16
  MPU_InitStruct.IsCacheable     = MPU_ACCESS_CACHEABLE;
17
  MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
18
  MPU_InitStruct.Size         = MPU_REGION_SIZE_64KB;
19
20
  MPU_InitStruct.Number       = MPU_REGION_NUMBER0;
21
  MPU_InitStruct.BaseAddress     = 0x20000000;
22
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
23
24
  MPU_InitStruct.Number       = MPU_REGION_NUMBER1;
25
  MPU_InitStruct.BaseAddress     = 0x20010000;
26
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
27
28
  MPU_InitStruct.Number       = MPU_REGION_NUMBER2;
29
  MPU_InitStruct.BaseAddress     = 0x20020000;
30
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
31
32
  MPU_InitStruct.Number       = MPU_REGION_NUMBER3;
33
  MPU_InitStruct.BaseAddress     = 0x20030000;
34
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
35
36
  MPU_InitStruct.Number       = MPU_REGION_NUMBER4;
37
  MPU_InitStruct.BaseAddress     = 0x20040000;
38
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
39
40
41
  /* Enables the MPU */
42
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
43
}

von Matthias F. (frank91)


Lesenswert?

Könntest du mir noch sagen, wie du im Cube die Cortex_M7_Configuration 
gewählt hast?
Auf was steht
-Flash Interface?
-Art Accelerator?
-Instruction Prefetch?
-CPU ICache?
-CPU DCache?

Sobald ich dies weiß werde ich deine Änderungen einfach mal in mein 
Projekt übernehmmen und ausprobieren.

von Matthias F. (frank91)


Lesenswert?

Gerade eben habe ich folgende Einstellungen ausprobiert festgestellt:
1
I&DCache | MPU(wie mein Post weiter oben) | Resultat
2
-------------------------------------------------------------------
3
nein     | nein                           | lan sehr langsam
4
--------------------------------------------------------------------
5
ja       | nein                           | lan nicht erreichbar 
6
         |                                | LTDC hat Aussetzer.
7
---------------------------------------------------------------------
8
ja       | nein                           | lan schneller, noch nicht 
9
         |                                | ausreichend.
10
         |                                | LTDC hat Aussetzer.
11
---------------------------------------------------------------------
12
nein     | ja                             | lan schneller, noch nicht 
13
         |                                | ausreichend.
14
---------------------------------------------------------------------

von 32zuterrtzkutehte (Gast)


Lesenswert?

was reicht nicht aus vom LAN her?

ich habe
SIP,
RTP,
MJPEG stream empfangen,
TLS websocket verbindung
Sylog spam

und das alles parallel

inkl software audio verarbeitung ( echo usw ) und JPEG softwaredecoder

von 32zuterrtzkutehte (Gast)


Lesenswert?

achso ..

caches sind alle AN
prefetch an
MPU auch an

von Harrypotter (Gast)


Lesenswert?

AN4839 gelesen?

von Matthias F. (frank91)


Lesenswert?

Harrypotter schrieb:
> AN4839 gelesen?

ja.
Auch die 
http://www.st.com/content/ccc/resource/technical/document/application_note/group0/25/ca/f9/b4/ae/fc/4e/1e/DM00287603/files/DM00287603.pdf/jcr:content/translations/en.DM00287603.pdf
Seite 49 und Seite 81.

Hier gibt es auch ein Beispiel für MPU.
Verwende ich dieses erhalte ich die selben Resultate wie in meinem Post
vom 15.09.2017 09:33.

von Matthias F. (frank91)


Lesenswert?

32zuterrtzkutehte schrieb:
> achso ..
>
> caches sind alle AN
> prefetch an
> MPU auch an

Ich habe dein Beispiel jetzt übernommen und getestet.
Das mit dem System_Init und dem Linker File hab ich weggelassen, weil 
mir das zu heikel war dort etwas zu verstellen.

Resultat:
Die Main Schleife wird jetzt noch langsamer durchlaufen....
Nur noch 20.000 Durchgänge pro Sekunde.
Aber: Das Lan funktioniert jetzt!!!

Ich verstehe den Zusammenhang nicht :-/
Könntest du es mir möglicherweise ein wenig erklären, was die geänderten 
Zeilen bewirken?

Aufgrund der langsamen Main bin ich mir trotz allem noch nicht sicher ob 
ich es so lassen kann :-/

von Matthias F. (frank91)


Lesenswert?

Wenn ich von deinem Code nur das hier übernehme:
1
ethernetif.c:
2
__ALIGN_BEGIN ETH_DMADescTypeDef    __attribute__((__section__(".eth"),used))  DMARxDscrTab[ETH_RXBUFNB]   __attribute__((aligned(8)));/* Ethernet Rx MA Descriptor */
3
__ALIGN_BEGIN ETH_DMADescTypeDef     __attribute__((__section__(".eth"),used))  DMATxDscrTab[ETH_TXBUFNB]   __attribute__((aligned(8)));/* Ethernet Tx DMA Descriptor */
4
__ALIGN_BEGIN uint8_t          __attribute__((__section__(".eth"),used))  Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]   __attribute__((aligned(8))); /* Ethernet Receive Buffer */
5
__ALIGN_BEGIN uint8_t         __attribute__((__section__(".eth"),used))  Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]   __attribute__((aligned(8))); /* Ethernet Transmit Buffer */

geht das Lan wie es soll. Allerdings wird die Main nur 40.000 in der 
Sekunde durchlaufen.

von 32zuterrtzkutehte (Gast)


Lesenswert?

hast du dein linker file auch angepasst was die section "eth" 
beinhaltet?

Problem sind die Speicherbereiche die zwar zusammenhängend ab adresse 
0x2000000 sind ...
aber!!!

DTCM hat 64bit anbindung glaube und ist daher schneller
SRAM1 240kb hat nur 32bit anbindung und damit langsamer
SRAM2 16kb auch nur 32bit aber über anderen Bus angebunden und damit für 
ETH/USB besser
das ganze teil ist eine wissenschaft für sich.


ich habe jetzt im linker alles auf 8byte aligned und verschenke damit 
ein paar byte ...
aber ich brauch nicht mehr so super genau aufpassen wo  welches byte 
landet.

da ich ein RTOS nutze was  mit heap_5 betrieben wird und den rest vom 
DTCM , SRAM1 als dynamischen heap nutzt...

probleme hat der M7 immer dann wenn er nicht richtig aligned ist...
dann wird ein teil der SW zum bremsklotz

witzig ist dann zB auch wenn 1-2 Tasks ( von 10 ) langsamer laufen ..
der rest aber weiterhin schnell agiert

man sucht sich dann blöd

von 32zuterrtzkutehte (Gast)


Lesenswert?

Matthias F. schrieb:
> enn ich von deinem Code nur das hier übernehme:
> ethernetif.c:
> __ALIGN_BEGIN ETH_DMADescTypeDef
> __attribute__((__section__(".eth"),used))  DMARxDscrTab[ETH_RXBUFNB]
> __attribute__((aligned(8)));/* Ethernet Rx MA Descriptor */
> __ALIGN_BEGIN ETH_DMADescTypeDef
> __attribute__((__section__(".eth"),used))  DMATxDscrTab[ETH_TXBUFNB]
> __attribute__((aligned(8)));/* Ethernet Tx DMA Descriptor */
> __ALIGN_BEGIN uint8_t          __attribute__((__section__(".eth"),used))
> Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE]   __attribute__((aligned(8))); /*
> Ethernet Receive Buffer */
> __ALIGN_BEGIN uint8_t         __attribute__((__section__(".eth"),used))
> Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE]   __attribute__((aligned(8))); /*
> Ethernet Transmit Buffer */
>
> geht das Lan wie es soll. Allerdings wird die Main nur 40.000 in der
> Sekunde durchlaufen.

hier werden die buffer für die LAN schnittstelle
also descriptoren und TX/RX Buffer
auf 8byte aligned in die extra 16kb SRAM 2 gelegt


0x20000000...........0x20010000..............................0x2004C000. 
...
_____DTCM RAM_______|______240kb SRAM_______________________|__16kb SRAM 
..


der DTCM ist aber an einem anderen BUS angebunden
Daher auch probleme mit DMA und daten die im DTCM RAM liegen.

ich würde von anfang an aufpassen wo welche daten liegen.
es ist dem µC nicht egal welcher RAM bereich das ist .


zB musst du mal schauen wo der STACK in deinem Linkerfile liegt.
wenn du nur eine RAM region hast udn der STACK liegt am ende ...

ist er momentan in den letzten 16kb

STACK sollte im indealfall im DTCM liegen
also den ersten 64kb
bei mir am ende des DTCM RAM

wenn man den ganzen quatsch mal umgebogen hat , gehts

von 32zuterrtzkutehte (Gast)


Lesenswert?

wenn dir das zu langsam ist ..
lege die funktion in den ITCM RAM
hier ist quasi auch 0Waitstates für befehle und damit voller MCU takt
der JPEG decoder von elm chan läuft dann auf ca 260% gegenüber normalen 
funktionen aus dem Flash

von Matthias F. (frank91)


Lesenswert?

Soory, ich war die letzen Tage geschäftlich unterwegs.


32zuterrtzkutehte schrieb:
> hast du dein linker file auch angepasst was die section "eth"
> beinhaltet?

Nein das Linker File war mir zu heikel um dort etwas zu verändern.
Aber so wie du es erklärst würde es womöglich schon Sinn machen dort 
etwas zu verändern.
Die Sektion .eth gibt es bei mir nicht. Hast du diesen neu angelegt?

> probleme hat der M7 immer dann wenn er nicht richtig aligned ist...
> dann wird ein teil der SW zum bremsklotz

Seltsam ist das dieses Problem beim M4 nicht hat. Zumindest ist es bei 
mir noch nicht aufgetaucht.


> hier werden die buffer für die LAN schnittstelle
> also descriptoren und TX/RX Buffer
> auf 8byte aligned in die extra 16kb SRAM 2 gelegt

So ganz verstehe ich das noch nicht :-/
Du legst also den buffer gezielt in einen anderen Speicherbereich.
Was genau sagt hierbei das aligned aus?

> der DTCM ist aber an einem anderen BUS angebunden
> Daher auch probleme mit DMA und daten die im DTCM RAM liegen.
>
> ich würde von anfang an aufpassen wo welche daten liegen.
> es ist dem µC nicht egal welcher RAM bereich das ist .

Momentan sieht mein Linker File noch so aus:
1
MEMORY
2
{
3
RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 512K
4
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 2048K
5
}

Der DTCM ist bei 0x2000 000 - 0x2001 FFFF.
Das heißt momentan wird erst der DTCM befüllt und anschließend der 
normale Ram. Ich bestimmte aber momentan noch nicht wo welche Daten 
liegen?

>
> STACK sollte im indealfall im DTCM liegen
> also den ersten 64kb
> bei mir am ende des DTCM RAM

Ok das könnte ich mal testen

von Matthias F. (frank91)


Lesenswert?

Nochmals vielen Dank für deine Hilfe.
Eine solche gute Antwort findet man eher seltener in diesem Forum.

Ich habe das Grundproblem jetzt dank deiner Hilfe verstanden.

Außerdem habe mir nochmals das Cube Beispiel vom Ethernet des F7 
angesehen.
Tatsächlich wird hier der Speicher des Ethernet auch im Linkerscript 
verschoben. Dies ist mir zu Beginn nicht aufgefallen.

Ich werde die Änderungen nun aus dem Cube Beispiel übernehmen.
Sollte ich in Zukunft weitere Geschwindigkeits-Probleme bekommen werde 
ich auch deine anderen Änderungen übernehmen.

von 32zuterrtzkutehte (Gast)


Lesenswert?

Matthias F. schrieb:
> Eine solche gute Antwort findet man eher seltener in diesem Forum.

ich kann sowas auch nicht gut erklären ^^

ob ich damit richtig liege weiß ich leider selbst nicht 100%ig.


Ich habe aber viele anfängliche Probleme durch viel testen beseitigt 
bekommen.

Ich hatte oft Probleme mit SW teilen die schon ewig funktioniert hatten 
, dann plötzlich aber langsam wurden auch wenn nur minimal was geändert 
wurde.
zB eine zusätzliche Variable in ein struct.
Ganze SW teile waren danach total langsam.
Durch das neue kompilieren inkl der neuordnung der Variablen war dann 
die eine oder andere Variable nicht richtig aligned.

die zugriffe werden dann x mal hin und hergeschoben und das bremmst dann 
massiv.
erst das 8byte aligning und die manuelle ordnung im RAM brachten das 
gewünschte ergebnis.

Ich würde dennoch von anfang an den RAM richtig aufteilen.
Im Cube Script war auch mal der Fehler den STACK am ende des DTCM zu 
legen.
OK , funktioniert.
Da das aber nur ein pointer ist und kein reservierter Bereich. kann man 
ein großes Array anlegen und schreibt vom DTCM über den STACK in den 
normalen RAM

witzig wirds erst dann wenn DMA dazukommt und seine Probleme mit dem 
DTCM RAM hat.
Denn der DMA kann leider nicht überall hin schreiben/lesen

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.