„Zeig dich nicht, Maria Iwanowna, und hör dir dein Lieblingslied„ Valenki “an.
Trotz der Überschrift wird die Reihenfolge der Präsentation umgekehrt sein - zuerst über Texas Instruments (natürlich nicht über das Unternehmen selbst, ich bin immer noch Ingenieur, kein
Trainer, kein Geschäftsanalyst, daher über die vom Unternehmen hergestellten Produkte) und erst dann über die Division.
Der erste Teil des Marlezon-Balletts.
Das Thema der Diskussion wird die relativ neue SS13xx-Familie (SS1310 / SS1350 / SS1352) sein, aber es ist nur ein Ausgangspunkt für die Diskussion der Situation im Bereich der Programmierung eingebetteter Systeme. Dieser MK ist für die Entwicklung von Geräten mit drahtlosen Schnittstellen verschiedener Typen vorgesehen (ich mag das neue Wort IoT nicht wirklich, zumal es die Möglichkeit der Verwendung dieser Familie nicht ausschöpft).
MK basiert auf dem M3-Kern mit völlig akzeptablen, wenn auch nicht rekordverdächtigen Parametern für die Frequenz und Speichergröße von Programmen und Daten. Es verfügt über ausreichend Schnittstellen, diese Parameter sind jedoch keineswegs interessant. Das Merkmal ist, dass die Mikroschaltung drei MK-Kerne enthält, einen zentralen und zwei periphere, um mit externen Geräten zu arbeiten und über Äther zu interagieren. Was ist der Grund für diese Entscheidung?
Zuallererst der Wunsch, einen minimalen Energieverbrauch zu gewährleisten. Tatsache ist, dass die herkömmliche Methode zur Reduzierung des Verbrauchs durch ressourcenintensive Berechnungen in relativ kurzer Zeit und anschließendes Umschalten in den Standby-Modus mit einer Verringerung der Taktfrequenz natürliche Einschränkungen aufweist und wir einen relativ schnellen Kern mit einer niedrigeren Frequenz verbrauchen, ohne die erforderliche Reaktionszeit dafür bereitzustellen externe Ereignisse. Um diesen Widerspruch zu beseitigen, wurde der zweite Kern der Sensorsteuerung eingeführt, der im Energiesparmodus eine Interaktion mit der Außenwelt ermöglicht. Wenn ressourcenintensive Berechnungen erforderlich sind, wird der Hauptkern aktiviert.
Der dritte Controller löst (wenn auch auf sehr komplizierte Weise) die gleiche Aufgabe der Verbrauchsreduzierung. Tatsache ist, dass die Aufrechterhaltung von Funkaustauschprotokollen häufig die Einhaltung sehr strenger Zeitbeschränkungen erfordert und ein Versuch, sie auf dem zentralen Kern zu implementieren (gleichzeitig mit der Ausführung des Zielprogramms), eine Erhöhung der Kerntaktfrequenz und dementsprechend des von der Stromquelle verbrauchten Stroms erfordert. Durch die Trennung von Funktionen kann dieser Widerspruch beseitigt werden (eine typische Lösung im TRIZ-Stil).
Ich bin mir absolut nicht sicher, ob eine solche Funktionstrennung unbedingt erforderlich war und ob die erforderlichen Parameter mit einfacheren Architekturlösungen nicht erreicht werden konnten. Wenn der Preis jedoch in einem angemessenen Rahmen gehalten und die erforderlichen Fähigkeiten realisiert werden, warum dann nicht? Darüber hinaus geht es in der Post immer noch nicht um die Hardwarekomponente von MK, sondern nur um die Situation abzudecken. Wir werden den Prozess der Erstellung von Software für diese Klasse von MK betrachten.
Zunächst - der Hauptkern, hier ist alles Standard - ist sowohl der M3-Kern selbst bekannt als auch die Toolchain gcc. Das Unternehmen selbst empfiehlt zwei IDEs - ccs und iar. Ich habe viel mit den letzten gearbeitet, also habe ich mich entschlossen zu versuchen, welche Art von Produkt das
düstere germanische Genie des kollektiven Geistes TI hervorgebracht hat. Code Composer Studio ist eine Weiterentwicklung des Unternehmens und absolut uneingeschränkt kostenlos, basierend auf (wer hätte das gedacht) Eclipse und bietet alle Vor- und Nachteile dieser Umgebung.
Das einzige, was ich sofort meine Verwirrung zum Ausdruck bringen möchte, ist, dass das Unternehmen freundlicherweise zusätzliche Dienstprogramme für die Arbeit mit diesem MK anbietet (zum Erstellen eines bootfähigen Firmware-Images über Ether und zum Übertragen auf MK), die jedoch aus irgendeinem Grund nicht in Java geschrieben sind. Dies ist die Basis für die Programmierumgebung und das Laufzeitsystem, für das das Installationspaket Teil ist, sowie für Phyton. Es ist nicht so, dass ich Letzteres nicht mochte (obwohl es eines gibt, akzeptiere ich es nicht, die Programmstruktur mit Einrückungen festzulegen, aber am Ende "die Farben und Farben sind unterschiedlich"), aber es ist einfach nicht klar, warum offensichtlich redundante Entitäten angezogen werden. Darüber hinaus sind die Dienstprogramme selbst nicht kompliziert, sie verwenden keine spezifischen Bibliotheken und wurden vom Autor für eine sehr begrenzte Zeit nach Java übertragen, ohne die geringste Schwierigkeit, die Programmlänge um 20% zu erhöhen, und, was etwas seltsam ist, ohne eine merkliche Änderung der Leistung (da die Hauptbibliothek Laufzeit ist mit dem Lesen von Dateien verbunden, dies ist nicht so überraschend - eine
späte Notiz von Funtik F ...).
Der zweite Teil des Puzzles liegt in der Tatsache, dass Eclipse selbst aufgrund der Möglichkeit, Plugins einfach einzubetten, beliebt ist. Angesichts dieser Tatsache ist die Entscheidung der Entwickler der Programmierumgebung, den Benutzer dazu zu bringen, das Dienstprogramm mit Handles über die Befehlszeile aufzurufen, das Terminal zuvor mit den Handles in der Entwicklungsumgebung zu trennen und das Programm zu starten, um Daten auf dem MK mit den Handles zu empfangen und das Terminal dann wieder mit Handles wiederherzustellen. Vielleicht scheint diese Lösung für „Hindu-Programmierer“ die einzig mögliche und völlig gerechtfertigte zu sein, aber ein großes Unternehmen könnte es sich leisten, mehr qualifiziertes Personal anzuziehen, ich weiß wahrscheinlich nichts.
Darüber hinaus erfolgt die Programmierung der Sensorsteuerung (der Name ist nicht sehr erfolgreich, aber es handelt sich um ein direktes Transparentpapier) mit dem Produkt Sensor Composer Studio. Sofort eine andere Frage - warum es notwendig ist, ein separates Produkt zu haben, nicht, dass es sehr schwierig war, das Fenster zu wechseln, aber dennoch ... zumal der erstellte Code letztendlich Teil des Codes für das Haupt-MK wird (natürlich ist er da nicht ausgeführt, aber im allgemeinen Adressraum des Programmspeichers enthalten).
Und hier ist noch eine weitere Funktion: Sie erzählen uns nichts über diesen Kern (seine Architektur), außer dass er 16-Bit ist, wenig Verbrauch hat und proprietär ist. Im Allgemeinen ist das in Ordnung, es funktioniert und funktioniert gut, aber "das Sediment bleibt". Das Folgende ist eine Beschreibung der Befehle dieses Kernels, wonach wir annehmen können, dass dies eine Modifikation von 430 ist, wenn auch mit Funktionen wie Befehlen zum Organisieren von Zyklen. Die Position der Peripherieregister im allgemeinen und lokalen Adressraum wird angegeben, und dann beginnen wieder seltsame Dinge - viele Register, einschließlich Peripherieregister, werden von der Phrase "wird nur von der TI-Bibliothek verwendet" begleitet, und für einige der Register sind noch Bitfeldzuweisungen angegeben, und für manche nicht. Nicht, dass mich diese Beschreibungen der Register sehr stören, aber warum sie geben, wenn der Benutzer nicht vorhat, sie zu verwenden - ich persönlich verstehe nicht zu viel.
Sie können auch vom Hauptkernel aus mit speziellen Bibliotheken auf die Peripherie dieses Kernels zugreifen. Gleichzeitig können Sie Code in der genannten Programmierumgebung schreiben, wiederum mit einigen Plug-Ins. Hier ist alles in Ordnung, die Dokumentation ist ausreichend, die Einstellungen sind bequem, es gibt eine grafische Darstellung der Einstellungen, eingebautes Debugging in einem speziellen Modus (im allgemeinen Modus ist der Debugger mit dem Hauptkernel beschäftigt), im Allgemeinen ist es ziemlich wertvoll.
Der nächste Teil ist der Kernel für die Arbeit mit Radio, der auf der Basis von M0 erstellt wurde und ein Programm aus seinem eigenen ROM ausführt (höchstwahrscheinlich ist es Teil eines nichtflüchtigen Speichers, es ist unwahrscheinlich, dass ein moderner MK einen maskierten Speicher hatte), der nicht geändert werden kann (zumindest in diesem Fall) Dokumentation kein Wort) vom Benutzer. Informationen über die interne Struktur des Funkkanals sind äußerst knapp. Sie können zwar nur aus der Beschreibung der Moduseinstellungsbefehle extrahiert werden, werden jedoch vom üblichen "eingebauten" Entwickler nicht benötigt.
Die Interaktion zwischen dem Hauptkern und dem Funkteil basiert auf dem Nachrichtenfluss, der ausreichend detailliert dokumentiert ist. Und diese Dokumentation reicht völlig aus, um die einfache Sache zu verstehen - Sie werden Ihre Interaktionsmechanismen zwischen den Kerneln und insbesondere den Kommunikationsprotokollen nicht aufbauen (ich werde es definitiv nicht), aber Sie werden die vom Unternehmen implementierte Bibliothek verwenden, da die Interaktion selbst damit ziemlich kompliziert ist Das Design sollte eine Vielzahl verschiedener Faktoren berücksichtigen, damit die Vorteile des Schreibens eines eigenen Pakets die Kosten für dessen Erstellung nicht ausgleichen. Daher verwenden wir wieder die Bibliotheksunterschicht, um die Interaktion des Hauptkerns mit dem Funkkern zu organisieren, und verwenden höchstwahrscheinlich vorgefertigte Lösungen zum Organisieren eines standardisierten Funkkommunikationskanals unter Verwendung vorgefertigter Module, wobei nur die Kanalparametrisierung verwendet wird.
Ich denke, dem Leser wurde klar, dass das Schreiben eines vollwertigen Programms für diesen MK keine einfache Aufgabe ist, sondern für fortgeschrittene Profis durchaus zugänglich ist, aber was sollte ein „gewöhnlicher“ Entwickler tun (wie Oleg Artamonov kürzlich schrieb: „Sie haben bereits erkannt, dass Sie bei der Auswahl einen großen Fehler gemacht haben Berufe? ”). Das Unternehmen hat sich um diesen Fall gekümmert und stellt zusammen mit der Entwicklungsumgebung ein großes Paket (eine Reihe von Beispielen) von Programmen für alle Gelegenheiten zur Verfügung, das SimpleLink heißt. Darüber hinaus werden die Lösungen in zwei Versionen angeboten - sowohl unter Verwendung des Echtzeitbetriebssystems TI-RTOS (meiner Meinung nach ist dies eine bequemere Methode) als auch in einem Superzyklus (falls Sie das integrierte Betriebssystem so sehr hassen, dass Sie nicht essen können “). Ich bin ruhig in Bezug auf RTOS unter MK, daher verwende ich die erste Option und rate Ihnen, dasselbe zu tun, insbesondere wenn Sie die Konfiguration des Betriebssystemerstellungsprozesses verstehen und an Ihre Aufgabenklasse anpassen, die Benutzerfreundlichkeit gespart und die Kosten für die Aufrechterhaltung dieses Komforts drastisch reduziert werden.
Meine persönliche Einstellung zu diesem Paket ist zweifach - einerseits ein wunderbares Unterfangen, das die Verwendung von MK wirklich dramatisch vereinfacht (daher verwende ich es), andererseits - „Müll, Verbrennungen und Sodomie“, ein gutes Beispiel für den Satz „Wenn die Kosten guter Architektur scheinen Denken Sie über die Kosten einer schlechten Architektur nach. “(Deshalb schimpfe ich mit ihm.) Hier geht es nicht nur um die Verteilung von Funktionen nach Modulen und die Beziehungen zwischen ihnen (obwohl dies nicht alles reibungslos ist), sondern auch um die Verteilung von Modulen nach Datei, Dateiname und Verteilung Dateien nach Verzeichnissen und deren Namen und Struktur usw. usw. Nun, ein Verstoß gegen die Prinzipien von KISS und DRY ist für die Entwickler des Pakets fast die Regel, aber wenn ich den Quellcode des Pakets nicht verstehe (ich kann diese dumme Angewohnheit nicht loswerden). und benutze es "wie es ist", dann funktioniert alles gut, zumindest habe ich in einem bestimmten Projekt keine Probleme gefunden (abgesehen von einem beleidigten ästhetischen Gefühl und dem verlorenen Vertrauen in die Menschheit).
Aber jetzt können Sie problemlos zum Hauptpostulat dieses Beitrags gehen (besser spät als nie). Ich habe immer gedacht, dass es extrem schwierig ist, ein Framework zu schreiben, das echte Vielseitigkeit und hohe Leistung kombiniert. Die vom Unternehmen vorgeschlagenen Entwicklungsbeispiele stellen einen solchen Rahmen dar, bei dem Vielseitigkeit im Vordergrund steht. Tools zur Anwendungsanpassung fehlen fast vollständig, alles ist nur auf der Ebene der Anpassung von Quark. Nehmen Sie eines unserer vielen Beispiele, ändern Sie ein kleines Stück in Bezug auf Messungen und Analysen (und natürlich die Übertragung), und fertig. Natürlich wird der resultierende Code im allgemeinen Fall ziemlich aufgebläht sein, aber wir bieten Ihnen verschiedene Beispiele für unterschiedliche Anwendungsbedingungen, und Sie müssen nur den für Ihre Aufgabe am besten geeigneten auswählen. Im Extremfall ist eine beträchtliche Menge an Programmspeicher in das MK integriert, sodass Sie nicht über das Speichern dieser Ressource nachdenken müssen. Darüber hinaus ist ein erheblicher Teil der ausführenden Bibliotheken bereits im ROM versteckt, und Sie müssen sie nur vorsichtig aufrufen.
Es ist nicht so, dass ich gegen einen solchen Ansatz war und kategorisch auf der Erfindung von Fahrrädern bestand. Die Wiederverwendung von Code ist ein kategorischer Imperativ und eine Garantie für eine hohe Produktivität der Programmierer, unterliegt jedoch den folgenden Bedingungen:
Die Bibliothek der verwendeten Routinen sollte sein:
- sorgfältig entworfen
- ordentlich programmiert
- umfassend dokumentiert
- universell
- effektiv.
Und wenn die letzten beiden Punkte nur wünschenswert sind (sehr wünschenswert, aber dennoch ...), dann sind die ersten drei notwendig.
Was ist mit den Anforderungen des vom Unternehmen angebotenen SimpleLink-Pakets? Das Folgende sind Bewertungen auf einer Fünf-Punkte-Skala, die in der Reihenfolge der oberflächlichen Bekanntschaft mit dem Paket erhalten wurden.
1a) Die Verbindungen zwischen den Modulen sollten durchdacht sein, die Kompetenzgrenzen jedes Moduls sollten klar umrissen sein, um Doppelarbeit zu vermeiden, die Schnittstellen wurden ausgearbeitet - eine solide Vier, die Arbeit als Ganzes wurde erledigt.
1b) Die Verteilung von Modulen in Dateien mit einer durchdachten Verzeichnisstruktur ist wahrscheinlich drei mit einem Plus, was es nur wert ist, den Text von Programmmodulen in verschiedenen Dateien zu wiederholen.
2. Das Paket sollte keine schwer zu erkennenden, selten auftretenden Fehler aufweisen (die Tatsache, dass es nicht ständig Fehler anzeigen sollte, ist offensichtlich). Es ist schwierig, hier Schätzungen vorzunehmen, ich stelle einen unangenehmen Umstand fest: Die meisten Funktionen können sowohl aus dem üblichen Programmspeicher als auch aus dem permanenten Speicher aufgerufen werden, und wenn die Quellen der ersten Option zugänglich und validiert sind, ist die zweite viel schlimmer - wir erhalten keine Anweisungen Die Quellen sind nicht mit der ersten Option identisch, daher kann von einer Überprüfung keine Rede sein.
3. Die Dokumentation für die soliden vier ist bereits die Tatsache, dass die Autoren nicht auf die „Kraft und Ausdruckskraft“ von Doxygen in Bezug auf die Dokumentation zurückgegriffen haben, mindestens 1 Punkt geben, es gibt ein System von Kontextverknüpfungen, es gibt Beschreibungen der Funktionsprinzipien - ich setze die Top 5 nicht nur, weil in Bezug auf die Dokumentation Ich habe es nie eingestellt, nicht einmal ich.
4. Nicht mehr als vier aufgrund der fehlenden entwickelten Konfiguration, aber ich habe dies bereits erwähnt.
5. Es ist schwer zu sagen, dass ich normalerweise die Implementierung von SPI betrachte - es ist einerseits einfach genug, um das Fehlen eines Standard-Rakes zu erkennen, andererseits ist es komplex genug, um zu wissen, wo sie zu stopfen sind. In diesem Paket gibt es also ineffiziente Verfahren zum Schreiben / Lesen von Bytes. Wenn Sie jedoch in die Tiefe eintauchen, können Sie mithilfe der MPD wirklich verwendete Optionen finden. Ich kann noch nichts dazu sagen.
Ein Hinweis zu den Tiefen - sie sind wirklich tief (durch 4-5 verschachtelte Funktionen) und ich kann nicht anders, als ein Merkmal des Pakets zu erwähnen - es ist in C geschrieben. Ich habe nicht vergessen, zwei Pluspunkte nach dem Buchstaben hinzuzufügen, es ist wirklich nicht da. Für diejenigen, die sich mit dem Thema befassen, wird vieles klar. Ich empfehle allen anderen, eine spannende Suche zu durchlaufen, um die Funktionen zu bestimmen, die auf Hardwareebene bei der Implementierung eines nicht trivialen Objekts ausgeführt werden. Natürlich wird eine solche Aufgabe bei der Verwendung von Klassen trivial, aber dies ist nicht der Weg der Jedi von TI. Ich verstehe, dass dies ein notwendiges Anliegen für diejenigen Benutzer ist, die die Pluspunkte vernachlässigen, aber warum hier aufhören, aber was ist mit den unglücklichen Assembler-Benutzern, für die sie beleidigt waren.
Und abschließend - ich möchte betonen, "damit ich oben richtig verstanden werden kann", schimpfe ich überhaupt nicht mit der MK-Familie, der Entwicklungsumgebung oder dem Softwarepaket, ich möchte nur, dass sie für den Benutzer noch besser, bequemer und attraktiver werden . Ich habe meine eigenen Konten bei TI und ich werde ihnen niemals die Übernahme von National oder die noch frühere Übernahme von Luminary mit der anschließenden Tötung einer interessanten MK-Linie (obwohl sie sich im letzteren Fall selbst bestraft haben) sowie das, was sie mir 2014 zurückgegeben haben, verzeihen Geld für die bestellten Kristalle (obwohl ich die Krim definitiv nicht berührt habe), aber dieses tiefe Gefühl hindert mich nicht daran, objektiv zu sein - sie haben gute Arbeit geleistet. Das von der Firma vorgeschlagene Konzept, das im Epigraph vorgestellt wird, kommt mir nicht allzu nahe, aber sie sind wahrscheinlich richtig, und es gibt keinen anderen Weg für komplexe Kristalle. Dies ist ein Trend und es macht keinen Sinn, ihn zu bekämpfen.
Und die Tatsache, dass dies ein Trend ist, bestätigt die Situation mit den neuen Vicor Power Management-Kristallen. Der Kristall selbst ist gut (das Gegenteil wäre für ein seriöses Unternehmen überraschend), die Parameter sind sehr gut, und ich habe ihn nur im Zusammenhang mit dem Abschnitt über die Auswahl externer Komponenten, insbesondere der Induktivität, erwähnt. In der Dokumentation ist dieser Abschnitt nur ein Absatz, der ein bestimmtes Induktivitätsmodell eines bestimmten Herstellers angibt und ausdrücklich angibt, dass andere Optionen nicht berücksichtigt werden (siehe Inschrift). Wenn ich die Gründe für den Entwickler des Kristalls vollständig verstehe (Schaltfrequenz ist hoch, Ströme sind signifikant, das Design der Induktivität für solche Bedingungen ist keine triviale Aufgabe), sollte ich dennoch beachten, dass dieser Ansatz für das Design im Moment für mich ungewöhnlich ist, „aber der Schlüssel hier ist„ für jetzt “.
Vielleicht sollten Sie diese beiden Komponenten in einem Bundle verkaufen, dann gibt es keine Fragen.Der zweite Teil des Marlezon-Balletts.Nun zu der Abteilung, deren Verwendung in einer der Bibliotheken von TI entdeckt wurde, die jedoch nicht direkt für diese Firma gilt, sondern ein Merkmal des gcc-Compilers ist. Wir formulieren das Problem also aus dem Bereich der Adressarithmetik - wir müssen die Differenz der Indizes (nämlich Indizes, nicht Bytes) zwischen zwei Elementen des Arrays (oder einfach sequentiell lokalisierten Daten desselben Typs) berechnen, die durch Zeiger auf sie angegeben werden. In der Regel ist eines der Elemente das erste Element des Arrays, dies ist jedoch nicht wichtig.Die Aufgabe selbst ist einfach und in C ist die Lösung offensichtlich und sieht aus wie
.
Der Teufel versteckt sich in der Implementierung - das Divisionsteam wurde nicht standardmäßig in die gängigen MK-Architekturen implementiert, daher ist es nicht schnell. Wenn der Divisor eine Variable ist, gibt es überhaupt keine gute Lösung für das Wort, aber für einen konstanten Wert gibt es Optionen, die auf Multiplikation basieren. Dank der wunderbaren Eigenschaft der Multiplikation
(Addition ist additiv, danke, Kapitän) Die Hardware-Implementierung der Multiplikation ist in Implementierungen viel häufiger und ziemlich schnell (das Thema Hardware-Multiplikatoren ist an sich interessant, aber darüber nicht jetzt). Leider gibt es keine ähnliche Eigenschaft für die Aufteilung, weshalb es in Bezug auf die Hardware-Implementierung ein seltener Gast ist.Anstatt zu dividieren (durch Konstante ist dies wichtig), möchten wir die Multiplikation anwenden. Achten Sie auf Ihre Hände
wobei N eine zusätzliche Konstante ist. Es stellt sich eine logische Frage: Was für ein Müll, denn jetzt haben wir zwei Divisionsoperationen anstelle von einer und sogar eine Multiplikation, aufgrund derer wir gewinnen. Die Antwort wird richtig N gewählt, wenn es sich um eine Zweierpotenz handelt, aber die Division wird zu einer Verschiebung der Zahl nach rechts, was viel billiger ist, und wenn der Exponent ein Vielfaches von 8 ist, wird die Division zu einer Umnummerierung der Bytes der Zahl, was überhaupt nichts kostet. Da der N / c-Faktor konstant ist, berechnen wir ihn im Voraus und alles scheint in Ordnung zu sein, wenn nicht ein Detail - die Genauigkeit der Darstellung dieses Faktors.Betrachten Sie den speziellen Fall der Division durch 10, der beim Konvertieren von Zahlen von binär in dezimal auftritt. Dann berechnen wir unter Verwendung von H = 256 die Konstante für die Multiplikation 256/10 = 25,6, und es tritt ein Rundungsfehler auf die ganze Zahl 25 (-2,3%) oder 26 (+1,6) auf %). Dann ist zum Beispiel 100 * 26 = 2600 = 256 * 10 + 40 und der höchste Teil des Ergebnisses ist 10, was den erwarteten 100/10 = 10 entspricht. Wir können berechnen, bei welchen Werten der Dividende das Ergebnis um mehr als eins vom richtigen abweicht, aber dafür müssen wir Gleichungen der Form lösen
(wobei die Klammern den ganzzahligen Teil mit Abrundung bedeuten), und dies ist keine sehr klare Prozedur, ist es einfacher, eine numerische Simulation durchzuführen und sicherzustellen, dass das Ergebnis auf ein bestimmtes n korrekt ist. Sie können ein Korrekturadditiv eingeben und den Genauigkeitsverlust durch die Formel ausgleichen
und den zulässigen Bereich von Dividendenwerten erheblich erweitern (bis zu 256, dh bei einer 8-Bit-Ganzzahl ohne Vorzeichen machen wir niemals Fehler), aber wir können den grundlegenden Nachteil der Methode nicht beseitigen - das Vorhandensein eines Fehlers. Außerdem erhalten wir nur eine private Berechnung des Restbetrags (wenn dies der Fall ist) notwendig, aber dies ist nicht unser Fall) es ist möglich, nur eine separate Operation durchzuführen, was sich nachteilig auf die Arbeitsgeschwindigkeit auswirkt. Im Allgemeinen funktioniert die Methode recht gut, ist jedoch in ihrem Umfang eher begrenzt.Daher war ich etwas überrascht, als ich im kompilierten Code (wie immer dank Godbolt für die Gelegenheit) in der Adressarithmetik Multiplikation mit einer bestimmten (groß genug) Konstante sah, anstatt durch eine Konstante (sehr klein) zu dividieren. Eine andere Frage war, dass die Konstante der für das obige Verfahren berechneten überhaupt nicht ähnlich war. Und schließlich ist das Ergebnis nicht die ältere Hälfte der Arbeit, sondern der jüngste Teil davon. Im Allgemeinen eine etwas seltsame Methode, etwas Müll, aber Berechnungen zeigen, dass es funktioniert. Eine kurze Reflexion enthüllt das Geheimnis und die Methode stellt sich als absolut korrekt heraus, aber ... (natürlich erwartete der Leser "aber ...", da es im allgemeinen Fall unmöglich ist, Division durch Multiplikation zu ersetzen) hat er Einschränkungen.Betrachten Sie die magische Zahl 143 und untersuchen Sie ihre amüsanten Eigenschaften 77 * 143 = 11011, ihren jüngsten Teil 011 = 1 = 77/7. Es ist leicht zu erkennen, dass 784 * 143 = 112112, sein jüngster Teil 112 = 784/7 usw. für alle Zahlen, die 999 * 7 = 6993 nicht überschreiten. Hier ist es eine natürliche Einschränkung der Methode, aber wenn wir eine andere magische Zahl 7143 nehmen, werden wir den Bereich der Möglichkeiten auf 9999 * 7 = 69993 erweitern. Es ist nicht schwer, andere magische Zahlen zu finden, die ähnliche magische Eigenschaften haben.Wie man diese Zahlen erhält - wir wollen eine Zahl finden, indem wir multiplizieren, mit der die Dividende ein Ergebnis erhalten kann, das das Teilungsergebnis in seinem jüngsten Teil enthält, in diesem Fall mit 7. Es klingt abstrus, aber es ist wirklich einfach für die eingegebene Zahl 7 Holen Sie sich xxx001, nehmen Sie an, xxx = 001 und hier ist es einfache Straßenmagie 1001/7 = 143. Offensichtlich ist 143 * 7 = 1001, dann ist für jede Zahl = n * 7 (n * 7) * 143 = n * (7 * 143) = n * 1001 wahr, und der untere Teil des Ergebnisses ist n usw.Jetzt sehen wir einen grundlegenden Nachteil dieser Methode - sie funktioniert nur für Zahlen, die Vielfache des Divisors sind, und liefert in allen anderen Fällen ein völlig unvorhersehbares Multiplikationsergebnis (in dem Sinne, dass es in keiner Weise der Division entspricht). Wenn wir jedoch für diese spezielle Anwendung die Adressen der Array-Elemente subtrahieren, ist das Ergebnis genau ein Vielfaches der Größe des Array-Elements, und wir haben das Recht, diese Methode zu verwenden. Wenn wir die falschen Zahlen genommen haben, sollte uns das Ergebnis der Teilung auch nicht interessieren: "Eine Maschine ist eine Mühle. Wenn Sie Steine darauf werfen, funktioniert Mehl nicht."Wir finden magische Zahlen für andere Teiler als 7 sowie einen Beweis für ihre Existenz und überlassen es dem neugierigen Leser. Es ist auch interessant, ein Diagramm von Faktoren in Abhängigkeit vom Divisor zu erstellen und Einbrüche und Spitzen darauf zu sehen, wahrscheinlich korreliert ihre Anwesenheit irgendwie mit der Zahlentheorie. Zum Beispiel ist für Composite 21 = 3 * 7 diese Zahl = 381 (natürlich die Mindestanzahl, der Rest ist für uns nicht von Interesse) deutlich geringer als das Produkt 667 * 143 = 95381 und sogar nicht mehrfach, wie ich naiv dachte, obwohl 381 = 381.Eine weitere interessante Tatsache ist, dass magische Zahlen in verschiedenen Zahlensystemen unterschiedlich sein werden. Zum Beispiel gibt es im Dezimalsystem keine Konstante zum Teilen durch 5, da keine der Zahlen der Form x ... 1 eine Fünf als Teiler haben kann und unsere Methode nicht funktioniert. Gleichzeitig ist dieses Problem im binären (hexadezimalen) System gelöst, da 1024 + 1 = 1025 = 0x401 5 wunderbar mit dem Ergebnis 205 = 0xCD geteilt ist und unser Algorithmus wieder funktioniert, zum Beispiel 130 * 205 = 0x82 * 0xCD = 0xFAFA => FA = 26 = 130/5. Darüber hinaus kann bewiesen werden (nun, ich denke schon), dass jetzt das Problem, einen Faktor zu finden, für jeden ungeraden Teiler gelöst ist und jeder gerade zu einem ungeraden mit einer endlichen Anzahl von Verschiebungen wird (das kann ich definitiv beweisen). Soweit eine binäre Darstellung praktisch und nützlich ist, hatten wir großes Glück damit.PS.
Meine regelmäßigen Leser (ich schmeichle mir mit der Hoffnung, dass es solche gibt) sind ratlos - der Beitrag ist zu Ende und wo ist "Jaroslawnas Schrei". Mach dir keine Sorgen, meine Lieben, da ist er.In den Debug-Boards für CC1350 und CC1352 wird ein Kristall des Antennenschalters verwendet (es wird anders verwendet, aber es spielt keine Rolle), nämlich XMSSJE3G0PA (versuchen Sie nicht, dies in russischer Transkription zu lesen, ich bin sicher, dass muRata nichts dergleichen im Sinn hatte). Also ein Schalter mit bescheidenen Eigenschaften - ein Frequenzband von bis zu 2,7 GHz, Übertragungsdämpfung - 0,28 dB, Isolationsdämpfung - 33 dB, Schaltleistung - 20 dB. All dies wird jedoch durch zwei Parameter kompensiert - Abmessungen 1,5 * 1,5 mm und Kosten - 0,9 USD, trotz der angewandten Technologien "Silicon On Insulator" und "Galliumarsenid".WIE machen sie das - ich spreche hauptsächlich über den Preis und zweitens - warum wir es nicht machen - ist die Frage rhetorisch