À la question de la division et de TI

"Ne te montre pas, Maria Ivanovna, et écoute ta chanson préférée," Valenki "



Malgré le titre, l'ordre de présentation sera l'inverse - d'abord sur Texas Instruments (bien sûr pas sur l'entreprise elle-même, je suis toujours ingénieur, pas formateur, analyste commercial, donc sur les produits fabriqués par l'entreprise), et seulement ensuite sur la division.

La première partie du ballet Marlezon.

Le sujet de discussion sera la famille relativement nouvelle SS13xx (SS1310 / SS1350 / SS1352), mais ce n'est qu'un point de départ pour discuter de la situation dans le domaine de la programmation de systèmes embarqués. Ce MK est destiné à être utilisé dans la conception d'appareils avec des interfaces sans fil de différents types (je n'aime pas vraiment le nouveau mot IoT, d'autant plus qu'il n'épuise pas la possibilité d'utiliser cette famille).

MK est construit sur la base du noyau M3 avec des paramètres tout à fait acceptables, bien que non record pour la fréquence et la taille de la mémoire des programmes et des données, il dispose d'un ensemble suffisant d'interfaces, mais ces paramètres ne sont en aucun cas intéressants. La caractéristique est que le microcircuit contient trois noyaux MK, un central et deux périphériques, pour travailler avec des périphériques externes et pour interagir via l'éther. Quelle est la raison de cette décision?

Tout d'abord, la volonté d'assurer une consommation énergétique minimale. Le fait est que la manière traditionnelle de réduire la consommation en effectuant des calculs gourmands en ressources dans un temps relativement court, puis en passant en mode veille avec une diminution de la fréquence d'horloge a des limites naturelles et nous consommerons un cœur relativement rapide à une fréquence plus basse, tout en ne fournissant pas le temps de réaction requis pour événements externes. Pour éliminer cette contradiction, le deuxième noyau du contrôleur de capteur a été introduit, qui fournit une interaction avec le monde extérieur en mode basse consommation, et lorsque le besoin se fait sentir pour des calculs gourmands en ressources, il active le noyau principal.

Le troisième contrôleur résout (quoique de manière très compliquée) la même tâche de réduction de la consommation. Le fait est que le maintien des protocoles d'échange radio nécessite souvent de maintenir des contraintes de temps très strictes et une tentative de les implémenter sur le cœur central (en même temps que l'exécution du programme cible) nécessitera d'augmenter la fréquence d'horloge du cœur et, par conséquent, la puissance consommée par la source d'alimentation. La séparation des fonctions permet de supprimer cette contradiction (une solution typique dans le style TRIZ).

Je ne suis absolument pas sûr qu'une telle séparation des fonctions était absolument nécessaire et que les paramètres requis ne puissent pas être atteints avec des solutions architecturales plus simples, mais si le prix était maintenu dans un cadre raisonnable et que les capacités nécessaires étaient réalisées, alors pourquoi pas. De plus, la publication ne porte toujours pas sur le composant matériel de MK, c'est juste pour couvrir la situation. Nous considérerons le processus de création de logiciels pour cette classe de MK.

Pour commencer - le noyau principal, tout est standard ici - le noyau M3 lui-même est bien connu et la chaîne d'outils est gcc, la société elle-même recommande deux IDE - ccs et iar. J'ai beaucoup travaillé avec les derniers, j'ai donc décidé d'essayer quel type de produit le sombre génie teutonique de l' esprit collectif généré par TI. Code Composer Studio est un développement de la société et est absolument gratuit sans aucune restriction, basé sur (qui aurait pensé) Eclipse et possède tous les avantages et inconvénients inhérents à cet environnement.

La seule chose que je voudrais exprimer ma perplexité à la fois est que la société propose avec bonté des utilitaires supplémentaires pour travailler avec ce MK (pour créer une image de micrologiciel de démarrage via éther et pour la transférer vers MK), mais ils sont écrits, pour une raison quelconque, pas en Java, qui est la base de l'environnement de programmation et du système d'exécution qui fait partie du package d'installation, et sur Phyton. Ce n'est pas que je n'aimais pas beaucoup ce dernier (bien qu'il y en ait un, je n'accepte pas de définir la structure du programme avec indentation, mais au final "les couleurs et les couleurs sont différentes"), mais on ne sait pas pourquoi il est nécessaire d'attirer des entités manifestement redondantes. De plus, les utilitaires eux-mêmes ne sont rien de compliqué, ils n'utilisent pas de bibliothèques spécifiques et ont été transférés par l'auteur à Java pour un temps très limité sans la moindre difficulté à augmenter la longueur du programme de 20%, et, ce qui est un peu étrange, sans changement notable de vitesse (considérant que le principal le runtime est associé à la lecture de fichiers, ce n'est pas si surprenant - une note tardive de Funtik F ...).

La deuxième partie du puzzle réside dans le fait qu'Eclipse lui-même est populaire en raison de la possibilité d'intégrer facilement des plugins. Compte tenu de ce fait, la décision des développeurs de l'environnement de programmation de faire appeler l'utilisateur l'utilitaire avec des poignées à partir de la ligne de commande est extrêmement cryptique, ayant précédemment désactivé le terminal dans l'environnement de développement avec les poignées et lancé le programme de réception de données sur le MK avec les poignées, puis restauré à nouveau le terminal avec les poignées. Peut-être que pour les "programmeurs hindous" cette solution semble être la seule possible et parfaitement justifiée, mais une grande entreprise pourrait se permettre d'attirer du personnel plus qualifié, je ne sais probablement pas quelque chose.

De plus, la programmation du contrôleur de capteur (le nom n'est pas très réussi, mais c'est un papier calque direct) est effectuée en utilisant le produit Sensor Composer Studio. Immédiatement une autre question - pourquoi il est nécessaire d'avoir un produit séparé, non pas qu'il était très difficile de changer de fenêtre, mais quand même ..., d'autant plus que le code créé devient finalement une partie du code pour le MK principal (bien sûr, il est là non exécuté, mais inclus dans l'espace d'adressage général de la mémoire du programme).

Et voici une autre fonctionnalité - ils ne nous disent rien sur ce cœur (son architecture), sauf qu'il est 16 bits, peu consommateur et propriétaire. En général, ça va, ça marche et ça marche bien, mais "les sédiments restent". Ce qui suit est une description des commandes de ce noyau, selon laquelle nous pouvons supposer qu'il s'agit d'une modification de 430, bien qu'avec des fonctionnalités telles que les commandes d'organisation des cycles. L'emplacement des registres périphériques dans l'espace d'adressage général et local est donné, puis l'étrangeté recommence - de nombreux registres, y compris les registres périphériques, sont accompagnés de la phrase «n'est utilisé que par la bibliothèque TI», et pour certains des registres, les affectations de champs binaires sont toujours données, et pour certains ne le sont pas. Non pas que ces descriptions des registres me dérangent beaucoup, mais pourquoi les donner si l'utilisateur n'envisage pas de les utiliser - personnellement, je ne comprends pas trop.

Vous pouvez également accéder à la périphérie de ce noyau à partir du noyau principal en utilisant des bibliothèques spéciales, en même temps, vous pouvez écrire du code dans l'environnement de programmation mentionné, en utilisant à nouveau certains plug-ins. Tout va bien ici, la documentation est suffisante, les paramètres sont pratiques, il y a une représentation graphique des paramètres, le débogage intégré dans un mode spécial (en mode général, le débogueur est occupé avec le noyau principal), en général, cela en vaut la peine.

La partie suivante est le noyau pour travailler avec la radio, construit sur la base de M0, exécute un programme à partir de sa propre ROM (très probablement, il fait partie de la mémoire non volatile, il est peu probable qu'un MK moderne ait une mémoire masquée), qui ne peut pas être modifié (au moins à ce sujet dans documentation pas un mot) par l'utilisateur. Les informations sur la structure interne du canal radio sont extrêmement rares, en fait, elles ne peuvent être extraites que de la description des commandes de réglage de mode, mais elles ne sont pas nécessaires au développeur «intégré» habituel.

L'interaction entre le noyau principal et la partie radio est basée sur le flux de messages, qui est documenté avec suffisamment de détails. Et cette documentation suffit pour comprendre la chose simple - vous ne construirez pas (enfin, je ne le ferai certainement pas) vos mécanismes d'interaction entre les noyaux, et en particulier les protocoles de communication, mais vous utiliserez la bibliothèque implémentée par l'entreprise, car l'interaction est assez compliquée même avec elle La conception doit prendre en compte un grand nombre de facteurs différents, afin que les avantages de l'écriture de votre propre package ne compensent pas le coût de sa création. Par conséquent, nous utilisons à nouveau la sous-couche de bibliothèque pour organiser l'interaction du noyau principal avec le noyau radio et, très probablement, nous utilisons des solutions prêtes à l'emploi pour organiser un canal de communication radio standardisé à l'aide de modules prêts à l'emploi, en utilisant uniquement le paramétrage du canal.

Je pense qu'il est devenu clair pour le lecteur qu'écrire un programme à part entière pour ce MK n'est pas une tâche simple, il est tout à fait accessible pour un professionnel avancé, mais que devrait faire un développeur "ordinaire" (comme Oleg Artamonov l'a écrit récemment: "Vous avez déjà réalisé que vous avez fait une grosse erreur avec le choix professions? ”). La société s'est occupée de ce cas et, avec l'environnement de développement, fournit un grand ensemble (ensemble d'exemples) de programmes pour toutes les occasions, qui s'appelle SimpleLink. De plus, les solutions sont données en deux versions - à la fois en utilisant le système d'exploitation en temps réel TI-RTOS (à mon avis, c'est un moyen plus pratique), et dans un super cycle (au cas où vous détestez tellement le système d'exploitation intégré que vous ne pouvez pas manger “). Je suis calme sur RTOS sur MK, donc j'utilise la première option et je vous conseille de faire de même, surtout si vous comprenez la configuration du processus de construction du système d'exploitation et l'adaptez à votre classe de tâches, la facilité d'utilisation est économisée et le coût de maintenance de cette commodité est considérablement réduit.

Mon attitude personnelle à l'égard de ce paquet est double - d'une part, une merveilleuse entreprise qui simplifie vraiment considérablement l'utilisation de MK (donc je l'utilise), mais d'autre part - «poubelles, brûlures et sodomie», une excellente illustration de la phrase «Si le coût d'une bonne architecture semble C'est élevé pour vous, pensez au coût d'une mauvaise architecture. "(C'est pourquoi je le gronde.) Il ne s'agit pas seulement de la distribution des fonctions par modules et des relations entre eux (bien que ce ne soit pas tout lisse), mais aussi de la distribution des modules par fichier, nom de fichier, distribution fichiers par répertoires et leurs noms et structure, etc. etc. Eh bien, violer les principes de KISS et DRY est presque la règle pour les développeurs du package, mais si je ne comprends pas le code source du package (je ne peux pas me débarrasser de cette stupide habitude), et l'utiliser "tel quel", alors tout fonctionne bien, au moins je n'ai trouvé aucun problème dans un projet spécifique (à part un sentiment esthétique insulté et une perte de foi en l'humanité).

Mais maintenant, vous pouvez facilement accéder au postulat principal de ce message (mieux vaut tard que jamais). J'ai toujours pensé qu'il était extrêmement difficile d'écrire un framework qui combine une véritable polyvalence et de hautes performances. Les exemples de développement proposés par la société représentent exactement un tel cadre avec un accent sur la polyvalence, les outils de personnalisation des applications sont presque totalement absents, tout n'est qu'au niveau de l'ajustement du caillé. Prenez l'un de nos nombreux exemples, modifiez une petite pièce liée aux mesures et à l'analyse (et à la transmission, bien sûr), et vous avez terminé. Bien sûr, le code résultant sera assez gonflé dans le cas général, mais nous vous proposerons divers exemples pour différentes conditions d'application, et il vous suffit de choisir le plus adapté à votre tâche. Dans un cas extrême, une quantité considérable de mémoire de programme est intégrée dans le MK afin que vous n'ayez pas à penser à enregistrer cette ressource. De plus, une partie importante des bibliothèques en cours d'exécution sont déjà cachées à l'intérieur de la ROM et il vous suffit de les appeler avec soin.

Ce n'est pas que j'étais contre une telle approche, et j'ai catégoriquement insisté sur l'invention des vélos, la réutilisation du code est un impératif catégorique et une garantie d'une productivité élevée du programmeur, mais sous réserve de la condition suivante -
La bibliothèque de routines utilisée doit être:

  1. soigneusement conçu
  2. soigneusement programmé
  3. documenté en détail
  4. universel
  5. efficace.

Et si les deux derniers points ne sont que souhaitables (hautement souhaitables, mais néanmoins ...), alors les trois premiers sont nécessaires.

Qu'en est-il des exigences du package SimpleLink proposé par l'entreprise? Ce qui suit sont des évaluations sur une échelle de cinq points, obtenues dans l'ordre de connaissance superficielle du colis.

1a) Les connexions entre les modules doivent être réfléchies, les limites de compétence de chaque module doivent être clairement définies, en éliminant la duplication des fonctions, les interfaces élaborées - quatre solides, le travail dans son ensemble a été fait.

1b) La distribution des modules dans des fichiers avec une structure de répertoire bien pensée est probablement trois avec un plus, ce qui ne vaut que répéter le texte des modules du programme dans différents fichiers.

2. Le paquet ne doit pas contenir d'erreurs rarement manifestées difficiles à détecter (le fait qu'il ne doit pas présenter constamment d'erreurs est évident). Il est difficile de donner des estimations ici, je note une circonstance désagréable - la plupart des fonctions peuvent être appelées à la fois depuis la mémoire de programme habituelle et depuis la mémoire permanente, et si les sources de la première option sont accessibles et validées, alors la seconde est bien pire - nous ne recevons aucune instruction ses sources ne sont pas identiques à la première option, il ne peut donc être question de vérification.

3. La documentation pour les quatre solides est déjà le fait que les auteurs n'ont pas recouru à la «puissance et expressivité» de Doxygen en termes de documentation, donne un minimum de 1 point, il y a un système de liens contextuels, il y a des descriptions des principes de fonctionnement - je ne mets pas les cinq premiers uniquement parce qu'en termes de documentation Je ne l'ai jamais réglé, pas même moi-même.

4. Pas plus de quatre en raison du manque de configuration développée, mais je l'ai déjà mentionné.

5. Il est difficile de dire que je regarde généralement la mise en œuvre de SPI - elle est, d'une part, assez simple pour apprécier le manque de râteau standard, d'autre part, elle est suffisamment complexe pour savoir où les entasser. Donc, dans ce paquet, il y a des procédures inefficaces de référence pour écrire / lire des octets, mais si vous plongez dans les profondeurs, vous pouvez trouver des options vraiment utilisées en utilisant le MPD, je ne peux rien dire à leur sujet pour le moment.

Une note sur les profondeurs - elles sont vraiment profondes (à travers 4 à 5 fonctions imbriquées) et je ne peux pas m'empêcher de mentionner une caractéristique du paquet - elle est écrite en C. Je n'ai pas oublié d'ajouter deux points après la lettre, elle n'est vraiment pas là. Pour ceux qui sont dans le sujet, beaucoup devient clair, je recommande à tous les autres de passer par une quête passionnante afin de déterminer l'ensemble des fonctions effectuées au niveau matériel lors de la mise en œuvre d'un objet non trivial. Bien sûr, lors de l'utilisation de classes, une telle tâche devient triviale, mais ce n'est pas la manière du Jedi de TI. Je comprends que c'est une préoccupation nécessaire pour les utilisateurs qui négligent les avantages, mais pourquoi s'arrêter là, mais qu'en est-il des malheureux utilisateurs d'assembleurs, pour lesquels ils ont été offensés.

Et en conclusion - je veux souligner, "afin que je puisse être correctement compris au sommet", je ne gronde pas du tout la famille MK, ni l'environnement de développement, ni le progiciel, je veux juste qu'ils deviennent encore meilleurs, plus pratiques et plus attrayants pour l'utilisateur . J'ai mes propres comptes avec TI et je ne leur pardonnerai jamais la prise de contrôle de National ou l'acquisition même antérieure de Luminary avec le meurtre ultérieur d'une ligne MK intéressante (bien que dans ce dernier cas ils se soient punis), ainsi que ce qu'ils m'ont rendu en 2014 de l'argent pour les cristaux commandés (même si je n'ai certainement pas touché la Crimée), mais ce sentiment profond ne m'empêche pas d'être objectif - ils ont fait du bon travail. Le concept proposé par la société, qui est présenté dans l'épigraphe, n'est pas trop proche de moi, mais ils ont probablement raison, et il n'y a pas d'autre moyen pour les cristaux complexes. C'est une tendance et cela n'a aucun sens de la combattre.

Et le fait qu'il s'agisse d'une tendance confirme la situation avec les nouveaux cristaux de gestion de l'alimentation Vicor. Le cristal lui-même est bon (le contraire serait surprenant pour une entreprise réputée), les paramètres sont très bons, et je ne l'ai mentionné qu'en relation avec la section sur le choix des composants externes, en particulier l'inductance. Dans la documentation, cette section n'est qu'un paragraphe, qui indique un modèle spécifique d'inductance d'un fabricant particulier et déclare explicitement que d'autres options ne sont pas prises en compte, voir épigraphe. Comprendre pleinement les raisons du développeur du cristal (la fréquence de commutation est élevée, les courants sont importants, la conception de l'inductance pour de telles conditions n'est pas une tâche triviale), néanmoins, je dois noter que pour l'instant cette approche de la conception est inhabituelle pour moi ", mais la clé ici est" pour l'instant ". Peut-être devriez-vous vendre ces deux composants en bundle, alors il n'y aurait pas de questions.

La deuxième partie du ballet Marlezon.

Eh bien, maintenant sur la division, dont l'utilisation a été découverte dans l'une des bibliothèques de TI, mais ne s'applique pas directement à cette entreprise, mais est une fonctionnalité du compilateur gcc. Donc, nous formulons le problème à partir du domaine de l'arithmétique des adresses - nous devons calculer la différence dans les indices (à savoir les indices, pas les octets) entre deux éléments du tableau (ou simplement des données localisées séquentiellement du même type) spécifiées par des pointeurs vers eux.En règle générale, l'un des éléments est le premier élément du tableau, mais ce n'est pas important.

La tâche elle-même est simple et en C, la solution est évidente et ressemble à

(pointer1pointer0)/sizeof(type)

.Le diable se cache dans l'implémentation - l'équipe de division n'est pas devenue implémentée de manière standard dans les architectures MK communes, donc ce n'est pas rapide. Si le diviseur est une variable, il n'y a pas du tout de bonne solution du mot, mais pour une valeur constante, il existe des options basées sur la multiplication. Merci à la merveilleuse propriété de la multiplication

(a+b)(c+d)=ac+ad+bc+bd

(l'ajout est additif, merci, capitaine) l'implémentation matérielle de la multiplication est beaucoup plus courante dans les implémentations et est assez rapide (le sujet des multiplicateurs matériels est intéressant en soi, mais pas à ce sujet maintenant). Malheureusement, il n'y a pas de propriété similaire pour la division, c'est pourquoi c'est un invité rare en termes d'implémentation matérielle.

Donc, au lieu de diviser (par constante, c'est important), nous voulons appliquer la multiplication, surveillez vos mains

a/c=a(1/c)=a(N/(Nc))=a(N/c)/N

où N est une constante supplémentaire. Une question logique se pose - quel genre de déchets, car maintenant nous avons deux opérations de division au lieu d'une, et même la multiplication, grâce à laquelle nous gagnons. La réponse est correctement choisie N, si c'est une puissance de deux, mais la division se transforme en un décalage du nombre vers la droite, ce qui est beaucoup moins cher, et si l'exposant est un multiple de 8, alors la division se transforme en une renumérotation des octets du nombre, ce qui ne coûte rien du tout. Puisque le facteur N / c est constant, nous le calculons à l'avance et tout semble bien se passer, si ce n'était pour un détail - la précision de la représentation de ce facteur.

Considérons le cas spécifique de la division par 10, qui se produit lors de la conversion des nombres du binaire en décimal, puis, en prenant H = 256, nous calculons la constante pour la multiplication 256/10 = 25,6 et une erreur d'arrondi se produit à l'entier 25 (-2,3%) ou 26 (+1,6 %). Ensuite, par exemple, 100 * 26 = 2600 = 256 * 10 + 40 et la partie la plus élevée du résultat est 10, ce qui correspond aux 100/10 = 10 attendus. Nous pouvons calculer à quelles valeurs du dividende le résultat s'écarte du bon par plus d'un, mais pour cela nous devrons résoudre des équations de la forme

[n/10]=[nk/N]+1

(où les crochets signifient la partie entière avec arrondi), et ce n'est pas une procédure très claire, il est plus facile de faire une simulation numérique et de s'assurer que le résultat est correct pour un certain n. Vous pouvez saisir un additif de correction et compenser la perte de précision par la formule

(26/2+1)/256

et élargir considérablement la plage autorisée de valeurs de dividende (jusqu'à 256, c'est-à-dire que sur un entier non signé de 8 bits, nous ne commettons jamais d'erreur), mais nous ne pouvons pas éliminer l'inconvénient fondamental de la méthode - la présence d'une erreur, en outre, nous n'obtenons qu'un calcul privé du reste (si cela nécessaire, mais ce n'est pas notre cas), il est possible de ne faire qu'une opération distincte, ce qui affecte négativement la vitesse de travail. En général, la méthode fonctionne assez bien, mais sa portée est plutôt limitée.

Par conséquent, j'ai été légèrement surpris lorsque dans le code compilé (comme toujours, grâce à Godbolt pour l'occasion), j'ai vu dans l'adresse une multiplication arithmétique par une certaine constante (assez grande) au lieu de diviser par une constante (très petite). Une autre question était que la constante n'était pas du tout similaire à celle calculée pour la méthode ci-dessus. Et enfin, le résultat n'est pas la moitié supérieure du travail, mais la partie la plus jeune. En général, une méthode un peu étrange, quelques ordures, mais les calculs montrent que cela fonctionne. Une brève réflexion révèle le secret et la méthode s'avère tout à fait correcte, mais ... (bien sûr, le lecteur s'attendait à "mais ...", puisqu'il est impossible de remplacer la division par la multiplication dans le cas général) il a ses limites.

Considérez le nombre magique 143 et examinez ses propriétés amusantes 77 * 143 = 11011, sa partie la plus jeune 011 = 1 = 77/7. Il est facile de voir que 784 * 143 = 112112, sa partie la plus jeune est 112 = 784/7 et ainsi de suite pour tous les nombres ne dépassant pas 999 * 7 = 6993. La voici, une limitation naturelle de la méthode, mais en prenant un autre nombre magique 7143, nous étendrons l'éventail des possibilités à 9999 * 7 = 69993. Il n'est pas difficile de trouver d'autres nombres magiques qui ont des propriétés magiques similaires.

Comment obtenir ces nombres - nous voulons trouver un nombre, en multipliant par lequel le dividende peut obtenir un résultat qui contient le résultat de la division dans sa partie la plus jeune, dans ce cas par 7. Cela semble abstrus, mais c'est vraiment simple, pour le nombre d'entrée 7 que nous voulons obtenir xxx001, supposons xxx = 001 et ici c'est de la magie de la rue simple 1001/7 = 143. Évidemment, 143 * 7 = 1001, alors pour tout nombre = n * 7, (n * 7) * 143 = n * (7 * 143) = n * 1001 est vrai, et la partie inférieure du résultat est n, etc.

Nous voyons maintenant un inconvénient fondamental de cette méthode - elle ne fonctionne que pour les nombres qui sont des multiples du diviseur et donne un résultat de multiplication complètement imprévisible (dans le sens où il ne correspond à aucune division) dans tous les autres cas. Mais pour cette application particulière, lorsque nous soustrayons les adresses des éléments du tableau, le résultat sera exactement un multiple de la taille de l'élément du tableau et nous avons le droit d'utiliser cette méthode. Si nous prenions les mauvais chiffres, le résultat de la division ne devrait pas non plus nous intéresser: «une machine est un moulin, si vous lui jetez des pierres, la farine ne fonctionnera pas.»

Trouver des nombres magiques pour les diviseurs autres que 7, ainsi que la preuve de leur existence, nous laissons le lecteur curieux. Il est également intéressant de construire un graphique des facteurs en fonction du diviseur et de voir les creux et les pics sur celui-ci, probablement leur présence est en quelque sorte corrélée avec la théorie des nombres. Par exemple, pour le composite 21 = 3 * 7, ce nombre = 381 (bien sûr, le nombre minimum, le reste ne nous intéresse pas) est clairement inférieur au produit 667 * 143 = 95381 et même il n'est pas multiple, comme je le pensais naïvement, bien que 381 = 381.

Un autre fait intéressant est que les nombres magiques seront différents dans différents systèmes numériques. Par exemple, dans le système décimal, il n'y a pas de constante pour diviser par 5, car aucun des nombres de la forme x ... 1 ne peut avoir un cinq comme diviseur et notre méthode ne fonctionne pas. Mais, en même temps, dans le système binaire (hexadécimal), ce problème est résolu, car 1024 + 1 = 1025 = 0x401 est 5 merveilleusement divisé avec le résultat 205 = 0xCD et notre algorithme fonctionne à nouveau, par exemple 130 * 205 = 0x82 * 0xCD = 0xFAFA => FA = 26 = 130/5. De plus, il peut être prouvé (enfin, je pense que oui) que maintenant le problème de trouver le facteur est résolu pour tout diviseur impair, et que tout pair se transforme en un impair avec un nombre fini de décalages (je peux certainement le prouver). Dans la mesure où une représentation binaire est pratique et utile, nous en avons eu beaucoup de chance.

PS.Mes lecteurs réguliers (je me flatte d’espérer qu’il en existe) sont perplexes - la publication est terminée et où se trouve «le cri de Yaroslavna». Ne vous inquiétez pas, mes chers, le voilà.

Dans les cartes de débogage pour CC1350 et CC1352, un cristal du commutateur d'antenne est utilisé (il est utilisé différemment, mais cela n'a pas d'importance), à ​​savoir XMSSJE3G0PA (n'essayez pas de lire ceci en transcription russe, je suis sûr que muRata n'avait rien de ce genre à l'esprit). Ainsi, un commutateur avec des caractéristiques modestes - une bande de fréquence jusqu'à 2,7 GHz, une atténuation de transmission - 0,28 dB, une atténuation d'isolement - 33 dB, une puissance de commutation - 20 dB. Mais tout cela est compensé par deux paramètres - dimensions 1,5 * 1,5 mm et coût - 0,9 $, malgré les technologies appliquées "Silicon On Insulator" et "gallium arsenide".

COMMENT font-ils - je parle principalement du prix, et deuxièmement - pourquoi nous ne le faisons pas - la question est rhétorique

Source: https://habr.com/ru/post/fr430732/


All Articles