Перейти к содержанию
    

Как программно загнать STM32 в бутлоадер?

Чуется мне, что собака где-то в привязке к железу зарыта, точнее к архитектуре памяти. В бутлодере полно дефайнов на разные случаи жизни, но возможео разработчики что-то и упустили.

Ну если это прогеры-индийцы-студенты то возможно, в либах ТI частенько встречались баги.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скажите, а во Flаsh должна попадать только та часть строки, которая байты содержит? Длина строки, тип записи - это все обработчиком проглатывается?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скажите, а во Flаsh должна попадать только та часть строки, которая байты содержит? Длина строки, тип записи - это все обработчиком проглатывается?

Да.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну если это прогеры-индийцы-студенты то возможно, в либах ТI частенько встречались баги.

 

Ну знаете, я не склонен думать, что в программе HyperTerminаl закралась ошибка. Это широко применяемый продукт. А вот аппликуха, испытанная не на всех контроллерах вполне может содержать баг.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну знаете, я не склонен думать, что в программе HyperTerminаl закралась ошибка. Это широко применяемый продукт. А вот аппликуха, испытанная не на всех контроллерах вполне может содержать баг.

Это про пример загрузчика было сказано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть вопрос, он конечно ближе к разделу начинающих, но я не буду плодить темы.

Вот функция приема данных

int32_t Ymodem_Receive (uint8_t *buf)
{
 uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
 int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;

 /* Initialize FlashDestination variable */
 FlashDestination = ApplicationAddress;

 for (session_done = 0, errors = 0, session_begin = 0; ;)
 {
   for (packets_received = 0, file_done = 0, buf_ptr = buf; ;)
   {
     switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))
     {
       case 0:
         errors = 0;
         switch (packet_length)
         {
           /* Abort by sender */
           case - 1:
             Send_Byte(ACK);
             return 0;
           /* End of transmission */
           case 0:
             Send_Byte(ACK);
             file_done = 1;
             break;
           /* Normal packet */
           default:
             if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
             {
               Send_Byte(NAK);
             }
             else
             {
               if (packets_received == 0)
               {
                 /* Filename packet */
                 if (packet_data[PACKET_HEADER] != 0)
                 {
                   /* Filename packet has valid data */
                   for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
                   {
                     file_name[i++] = *file_ptr++;
                   }
                   file_name[i++] = '\0';
                   for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);)
                   {
                     file_size[i++] = *file_ptr++;
                   }
                   file_size[i++] = '\0';
                   Str2Int(file_size, &size);

                   /* Test the size of the image to be sent */
                   /* Image size is greater than Flash size */
                   if (size > (FLASH_SIZE - 1))
                   {
                     /* End session */
                     Send_Byte(CA);
                     Send_Byte(CA);
                     return -1;
                   }

                   /* Erase the needed pages where the user application will be loaded */
                   /* Define the number of page to be erased */
                   NbrOfPage = FLASH_PagesMask(size);

                   /* Erase the FLASH pages */
                   for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
                   {
                     FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter));
                   }
                   Send_Byte(ACK);
                   Send_Byte(CRC16);
                 }
                 /* Filename packet is empty, end session */
                 else
                 {
                   Send_Byte(ACK);
                   file_done = 1;
                   session_done = 1;
                   break;
                 }
               }
               /* Data packet */
               else
               {
                 memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
                 RamSource = (uint32_t)buf;
                 for (j = 0;(j < packet_length) && (FlashDestination <  ApplicationAddress + size);j += 4)
                 {
                   /* Program the data received into STM32F10x Flash */
                   FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource);

                   if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource)
                   {
                     /* End session */
                     Send_Byte(CA);
                     Send_Byte(CA);
                     return -2;
                   }
                   FlashDestination += 4;
                   RamSource += 4;
                 }
                 Send_Byte(ACK);
               }
               packets_received ++;
               session_begin = 1;
             }
         }
         break;
       case 1:
         Send_Byte(CA);
         Send_Byte(CA);
         return -3;
       default:
         if (session_begin > 0)
         {
           errors ++;
         }
         if (errors > MAX_ERRORS)
         {
           Send_Byte(CA);
           Send_Byte(CA);
           return 0;
         }
         Send_Byte(CRC16);
         break;
     }
     if (file_done != 0)
     {
       break;
     }
   }
   if (session_done != 0)
   {
     break;
   }
 }
 return (int32_t)size;
}

 

Есть там такая строки

 memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
                  RamSource = (uint32_t)buf;
                  for (j = 0;(j < packet_length) && (FlashDestination <  ApplicationAddress + size);j += 4)
                  {
                    /* Program the data received into STM32F10x Flash */
                    FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource);

                    if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource)
                    {
                      /* End session */
                      Send_Byte(CA);
                      Send_Byte(CA);
                      return -2;
                    }
                    FlashDestination += 4;
                    RamSource += 4;
                  }

 

Как мне данные из buf вытащить в окно watch, чтобы там был массивчик разворачивающийся? Я попробовал добавть - пишет cannot evaluate....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как мне данные из buf вытащить в окно watch, чтобы там был массивчик разворачивающийся? Я попробовал добавть - пишет cannot evaluate....

У Вас buf это указатель на uint8_t (uint8_t *buf). Чтобы просматривать значения, надо в watch вытащить buf[0], buf[1] и т.д., но это не удобно.

Создайте временный массив uint8_t temp_array[length], скопируйте в него содержимое buf нужной длины, в watch сможете просматривать все элементы temp_array (ещё смотрите, чтобы оптимизация была отключена, возможно проблема изначально в оптимизации, но не каждая среда может просмотреть массив через указатель на первый элемент).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я из интереса добавил парочку buf[0],buf[1] - пишет cannot evaluate. ПРинесет ли пользу заморачивание с временным массивом?

 

Если вытащить в watch (uint32_t)buf то отображается массив с одним элементом, имеющим одно и то же значение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я из интереса добавил парочку buf[0],buf[1] - пишет cannot evaluate. ПРинесет ли пользу заморачивание с временным массивом?

Попробуйте, объявить массив нужной длины и добавить одну memcpy() - это ведь не сложно.

 

Если вытащить в watch (uint32_t)buf то отображается массив с одним элементом, имеющим одно и то же значение.

Ну это Вы вытащили адрес памяти на которую ссылается buf (адрес первого элемента), а не сам элемент. Чтобы просмотреть значение надо тогда так:

*(uint32_t *)buf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 uint8_t temp_array[1024];
memcpy(temp_array, packet_data + PACKET_HEADER, packet_length);

Работает.

ОБращает на себя внимание, что все символы, которые в исходном файле 0x31 в массиве оказываются 0x01

В остальном - пробежался по примерно 200 байт - вроде бы сходится.

 

Кстати, этот почти похожий код получается если передавать бинарный файл. Если подсунуть HEX, то как раз вылазит то, что появлялось в файле, который я выкладывал под именем wrong.hex

 

Код 0x31 - не несет ли он какого-то сакрального смысла в протоколе YModem?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Меня больше смущает соответствие hex 31 и char 1, но как-то связать это не получается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поставил код "ловушку" для символа 0x31 - он принципиально не пролазит. Его просто нет в пакетах данных.

Что за шайтан?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Меня больше смущает соответствие hex 31 и char 1, но как-то связать это не получается.

Как "не получается"?

0х31 == '1'

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все ближе подбираюсь к разгадке.

Как выяснилось - в бинарнике действительно на месте 0x31 был 0x01. И он почему-то не обновился. Перекомпилировал - получил правильный файл.

Как бы почти "ура" - прошивка не бьется. Но только почему-то перепрошивается через раз - беру новый бинарник (в нем светодиод мигает с другой частотой) прошиваю - вроде бы шьется, но диод моргает по прежнему. В общем, какие-то глюки, то ли с кейлом, то ли с бутлодером.

РАзберусь завтра...

 

у меня перестал писаться axf файл (из него собирался бинарник). Я его удалил - кейл не ругается и новый не создает

hex2bin - не работает, пишет *** Error: CreateProcess failed, Command: 'hex2bin ....

 

Есть какой-нибудь идеологически правильный способ получать бинарник на выходе?

 

.......................................................

Наконец-то!!!!

Все пишется!!

Завтра на свежую голову погоняю код туда-сюда..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как "не получается"?

0х31 == '1'

Если читать внимательно то

Меня больше смущает соответствие hex 31 и char 1 ...

равно

0х31 == '1'

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...