2017-08-06 4 views
0

Je souhaite lire une valeur de i2c dans uboot, et basé sur la valeur, faire une commande. J'ai besoin qu'il soit dans un scriptbesoin de détecter la valeur i2c dans uboot comme un script

La commande elle-même n'a pas d'importance, cependant, son activation doit être basée sur la valeur de la puce i2c.

Jusqu'à présent, je ne peux imprimer que des valeurs de i2c, mais je ne peux pas les utiliser.

=> i2c md 20.1 0 8 
0000: ff ff ff ff ff ff ff ff ........ 

Je peux aussi avoir des conditions:

=> setenv myvalue 0 
=> if test $myvalue -eq 1; then echo 'hello'; fi 
=> setenv myvalue 1 
=> if test $myvalue -eq 1; then echo 'hello'; fi 
hello 
=> 

que je peux faire certains d'entre eux spécifiques à i2c:

=> if i2c probe; then echo "true"; else echo "false"; fi 
Valid chip addresses: 20 21 22 23 
true 

Mais je ne peux pas utiliser les valeurs du i2c à une condition. Comment puis-je résoudre ceci?

Répondre

1

Je ne vois aucune façon simple de le faire, mais ce qui suit devrait fonctionner:

  1. lire vos données I2C en mémoire quelque part en utilisant i2c read.
  2. Ecrivez la valeur de comparaison ailleurs dans la mémoire en utilisant mw.
  3. Comparer les deux zones de mémoire en utilisant cmp - cela devrait fonctionner sous la forme if cmp pour conditionnellement faire quelque chose en fonction du résultat.

Vous auriez en quelque sorte besoin de connaître les adresses d'un bloc de RAM sur votre système particulier qui pourrait être écrit en toute sécurité à ce stade du processus de démarrage.

0

Il n'y a pas de solution fournie dans u-boot pour réaliser ce que vous recherchez (facilement). J'ai écrit une commande u-boot qui vous permet de lire depuis la RAM et de stocker la valeur dans une variable d'environnement qui vous permet de faire une comparaison.

#include <common.h> 
#include <config.h> 
#include <command.h> 

int do_setenvram(
    cmd_tbl_t *cmdtp, 
    int flag, 
    int argc, 
    char *argv[] 
) { 

    unsigned int *addr; 
    unsigned long len; 
    uint32_t val; 
    char buffer[200]; 
    char type; 
    char returntype; 

    if (argc < 3 || argc > 4) { 
     printf ("Usage:\n%s\n", cmdtp->usage); 
     return 1; 
    } 

    addr = (char *)simple_strtol(argv[2], NULL, 16); 

    if (!addr) { 
     printf ("Usage:\n%s\n", cmdtp->usage); 
     return 1; 
    } 

    if (argc == 4) { 
     len = simple_strtol(argv[3], NULL, 16); 
     if (!len || len >= buffer) { 
      printf ("Usage:\n%s\n", cmdtp->usage); 
      return 1; 
     } 
    } 

    int option = strlen(argv[0]); 

    if (option > 2 && argv[0][option-3] == '.') { 
     type = argv[0][option-2]; 
     returntype = argv[0][option-1]; 
    } else if (option > 2 && argv[0][option-2] == '.') { 
     type = argv[0][option-1]; 
    } else { 
     printf ("Usage:\n%s\n", cmdtp->usage); 
     return 1; 
    } 

    switch (type) { 
     case 'b': 
      val = *((unsigned char *)(addr)); 
      break; 
     case 'w': 
      addr = (unsigned short *)simple_strtol(argv[2], NULL, 16); 
      val = ntohs(*addr); 
      break; 
     case 'l': 
      addr = (unsigned int *)simple_strtol(argv[2], NULL, 16); 
      val = htonl(*addr); 
      break; 
     case 'k': 
      addr = (unsigned int *)simple_strtol(argv[2], NULL, 16); 
      val = (*addr); 
      break; 
     case 's': 
      memset(buffer, 0, sizeof(buffer)); 
      memcpy(buffer, addr, len); 
      break; 
     default: 
      return 0; 
    } 

    if (returntype == 'd') { 
     sprintf(buffer, "%d", val); 
    } else if (type != 's') { 
     sprintf(buffer, "0x%x", val); 
    } 

    setenv(argv[1], buffer); 
    return 0; 
} 

/* ------------------------------------------------------------------------- */ 

U_BOOT_CMD(
    setenvram, 4, 0, do_setenvram, 
    "set environment variable from ram", 
    "name addr {len}\n" 
    "[.b, .w, .l, .s, .k] name address {max_length}\n" 
    " - set environment variable 'name' from addr 'addr'\n" 
); 

Donc dans votre cas:

  1. Lire à partir i2c dans un emplacement en mémoire (qui est libre ou pouvant être écrit sur): i2c read <chip> <memory-location>
  2. confirmer qu'il est écrit dans la mémoire emplacement fourni: md <memory-location>
  3. Vous devez connaître les données attendues que vous allez lire de la mémoire, dans le sens de la longueur et si c'est gros boutiste ou petit boutiste.
  4. Vous serez en mesure d'utiliser la commande u-boot que j'ai fourni ci-dessus en faisant setenvram.x <variable-name> <memory-location> <length> où l'argument .x est l'un des éléments suivants:

ARGUMENT options [1]:

. bit b (1 octet).

.w - mot (2 octets). Octet du réseau hôte converti.

.l - long (4 octets). Octet du réseau hôte converti.

.k - long (4 octets).

.s - chaîne (nombre d'octets spécifiés par l'utilisateur). // Remarque: {length} est requis.

  1. A partir de là les valeurs stockées dans la mémoire sera désormais dans une variable d'environnement u-boot qui peut être utilisé pour la comparaison.

exemples et l'utilisation D'autres sont visibles dans le commit ici: https://github.com/bwenstar/uboot-imx/commit/5996e854f82ecb9005d2b9546a71fca458784204