Forum: Mikrocontroller und Digitale Elektronik Typisieren von Variablen - Problem mit IAR MISRA C rule 45


von Heinrich (Gast)


Lesenswert?

Gibt es eine Möglichkeit die Zuweisung bei der ADC12 Konfiguration des 
MSP430F161x anders als

DMA1DA = (unsigned short)&tabelle[0];

zu gestalten? Der ADC12 ist als CONSEQ_2 (A single channel is converted 
repeatedly.) konfiguriert.
Durch obige Zeile wird immer MISRA C rule 45 von IAR 3.42A verletzt.
Warning[Pm038]: type casting from any type to or from pointers shall not 
be used (MISRA C rule 45)

Die gleiche Regel wird auch in der zweiten Zeile von folgendem Beispiel 
verletzt:

const signed short Werte[] = { .... }
signed short* p_Werte_Tabelle = (signed short*)&Werte[0];

Das Problem besteht hier in der Umdeklaration von const zu einem pointer 
vom Typ signed short. Wäre der Pointer auch const signed short, könnte 
ich ihn aber nicht mehr ändern.

Ich möchte die Meldungen gern umgehen, ohne die Regel abzuschalten oder 
die Fehler als Warnungen zu definieren.

von Hegy (Gast)


Lesenswert?

Wie ist denn 'tabelle' definiert?

int tabelle[x]; ??

Läst sich tabelle[x] auch als
unsigned char tabelle[x]
definieren?

von pumpkin (Gast)


Lesenswert?

1
DMA1DA = (unsigned short)&tabelle[0];

Die Adresse des arrays zu casten macht ja auch keinen Sinn. Ohne darüber 
nachzudenken ob es das macht was du willst:
1
DMA1DA = (unsigned short) tabelle[0];

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

pumpkin wrote:

> Die Adresse des arrays zu casten macht ja auch keinen Sinn.

Warum soll das keinen Sinn haben?

Ich kenne den MSP430 nicht, aber der Name des Registers sah mir sehr
nach einem DMA-Register aus, und da kann eine Adresse sehr wohl
Sinn haben.

Wie man MISRA davon überzeugen kann, dass das Sinn hat, habe ich aber
auch keine Idee.  Sinnvollerweise müsste die entsprechende IO-Header-
Datei des Compilers/der Bibliothek dieses Register bereits als void *
deklarieren, da es ja in der Tat einen Zeiger aufnimmt.

von Karl Arsch von der Rennbahn (Gast)


Lesenswert?

Wenns für die DMA ist dann sollte man die Adresse nehmen wie sie ist. 
Denn eine 'vorzeichenbehaftete' Adresse in eine 'vorzeichenlose' zu 
wandeln kann wenig Sinn machen.

pumpkin

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl Arsch von der Rennbahn wrote:

> Wenns für die DMA ist dann sollte man die Adresse nehmen wie sie ist.
> Denn eine 'vorzeichenbehaftete' Adresse in eine 'vorzeichenlose' zu
> wandeln kann wenig Sinn machen.

Du hast noch nichtmal ansatzweise das Problem verstanden...

von Heinrich (Gast)


Lesenswert?

Die Tabelle ist als
unsigned short tabelle[x];
definiert, da der MSP ja auch nur Digitalwerte von 0 bis 4095 erzeugt.

Der MSP möchte die Speicheradresse haben, wo er die ADC12-Messwerte 
ablegt. Diese Adresse ist aber im RAM und bei jedem compilieren wieder 
wo anders.

Lasse ich das (unsigned short) am Anfang weg, dann mekert der Compiler 
folgendermaßen:

Error[Pe513]: a value of type "unsigned short *" cannot be assigned to 
an entity of type "unsigned short"

In DMA1DA muss die Startadresse des RAM stehen, wo die Messwerte der 
Reihe nach landen sollen. Die verwendete Variante macht also Sinn.
unsigned char tabelle[x] macht keinen Sinn, da der ADC12 immer 16Bit 
Werte ermittelt und immer 2 Byte füllt, das Problem wäre aber das 
gleiche.

Heinrich

von tom (Gast)


Lesenswert?

Hi,

na ja, die MISRA-Regel ist ja auch eine Warning! Zweifellos hat die 
Regel einen Sinn und weiter ohne Zweifel ist der Code ebendso richtig. 
Wenn das DMA-Register eine Adresse braucht, dann muß es auch die Adresse 
sein.

Das Problem ist eigentlich das folgende: gerade in der 
Systemprogrammierung entstehen Konstrukte, die potentiell gefährlich 
sind, ohne die es aber gar nicht geht. Egal was Du machst, es wird immer 
solche Fälle geben. Der Ausweg: (falls das möglich ist) PARTIELL 
abschalten! (wenigstens für das - möglichst kleine - Quelltextmodul)

MISRA (und auch andere solche Regelsätze) sind nicht dazu da, sie 
sklavisch zu befolgen. Sie sind Werkzeuge, die auf MÖGLICHE Probleme 
hinweisen und den Programmierer zum Nachdenken und prüfen veranlassen 
sollen! Und - MIT BEGRÜNDUNG - auch das Abschalten ermöglichen sollten! 
Forderungen wie "es müssen alle Regeln absolut und unbedingt eingehalten 
werden" sind schwachsinnig! (wiewohl recht oft Vorgesetzte und 
"Profi-Programmierer", die Erfahrung zeigt's, solcherlei verlangen)

Recht gern ist man der Meinung, sich mit MISRA Sicherheit vor Fehlern im 
Sinne einer Garantie zu erkaufen. Das ist ein kompletter Trugschluß (und 
im schlimmsten Fall ein Plazebo, das von der fehlerhaften Realität 
ablenkt!) Ein falsch eingesetztes Werkzeug wird ganz sicher nicht zu 
einem guten Produkt führen!

von Heinrich (Gast)


Lesenswert?

Hi tom,

ist schon richtig, dass nicht immer alle MISRA-Regeln unbedingt 
eingehalten werden müssen. Aber beim Abschalten von Regeln "entschlüpft" 
ab und zu doch mal eine Fehlermeldung die auf einen richtigen Fehler 
hinweist. Ich gebe mir daher alle (derzeit von mir nicht behebbaren 
Fehlermeldugen) als Warnungen aus und merke mir ab und zu die Anzahl der 
Warnungen. Sind es "mal wieder" mehr geworden, gehe ich die Liste mit 
den Warnungen durch und suche die Neue. Das kostet zwar erst mal etwas 
Zeit, erspart aber später "komische Programmeffekte".

Wenn's keine Lösung für mein Ärgernis gibt, dann bleibt die Codezeile 
eben wie sie ist.

zur Bemerkung von Jörg Wunsch:
Ich habe mal bei IAR angefragt, was die in Ihrer Bibliothek machen 
können. Das wäre dann eine saubere Lösung!

Gruß
Heinrich

von Heinrich (Gast)


Lesenswert?

Der Support von IAR hat mir u.a. zu folgender Lösung geraten:

include-file anpassen!

Ich habe das im msp430x16x.h - File folgendermaßen getan.

...
#define DEFC(..
#define DEFW(..
Zusäzliches Makro:
#define DEFP(name, address) __no_init volatile unsigned short *name @ 
address;

6x ersetzen von DEFW() durch DEFP()
...
#define DMA0SA_             (0x01e2)    /* DMA Channel 0 Source Address 
*/
DEFP(   DMA0SA            , DMA0SA_)
#define DMA0DA_             (0x01e4)    /* DMA Channel 0 Destination 
Address */
DEFP(   DMA0DA            , DMA0DA_)
#define DMA0SZ_             (0x01e6)    /* DMA Channel 0 Transfer Size 
*/
DEFW(   DMA0SZ            , DMA0SZ_)
#define DMA1SA_             (0x01ea)    /* DMA Channel 1 Source Address 
*/
DEFP(   DMA1SA            , DMA1SA_)
#define DMA1DA_             (0x01ec)    /* DMA Channel 1 Destination 
Address */
DEFP(   DMA1DA            , DMA1DA_)
#define DMA1SZ_             (0x01ee)    /* DMA Channel 1 Transfer Size 
*/
DEFW(   DMA1SZ            , DMA1SZ_)
#define DMA2SA_             (0x01f2)    /* DMA Channel 2 Source Address 
*/
DEFP(   DMA2SA            , DMA2SA_)
#define DMA2DA_             (0x01f4)    /* DMA Channel 2 Destination 
Address */
DEFP(   DMA2DA            , DMA2DA_)
#define DMA2SZ_             (0x01f6)    /* DMA Channel 2 Transfer Size 
*/
DEFW(   DMA2SZ            , DMA2SZ_)
...

Vielleicht findet das auch in den anderen MSP430-Typen Anwendung und 
wird von TI mal in ihre Dateien übernommen.

Grüße
Heinrich

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.