Jump to content

    

Darth Vader

Участник
  • Content Count

    423
  • Joined

Everything posted by Darth Vader


  1. в корректно написанных программах лучше не делать. Разве что в каком-нить учебном коде (примерах) так сойдёт. С этим что не так? Как надо правильно мониторить состояние флага события в регистре?
  2. вообще непонятно что вычисляется. Если data_size на входе в функцию будет ==8, то получим: n_dwords=2. Так и задумывалось? Да, ошибка. Корректно будет так size_t n_dwords = data_size>>3; // делим на 8 if(data_size&7) { // Если при делении на 8 остаток не нулевой ++n_dwords; // увеличиваем частное на 1 } Что даст тот же результат, что и Да, тоже ошибка. Для проверки выравнивания на 8 байт должно быть ...&7 Прошу прощения. Код набрасывался на скорую руку и не тестировался. Отсюда ошибки. Смысл был сделать универсальный код, чтобы корректно работал в том числе и на М0/М0+/М1, и не приводил к хардфолту от невыровненного доступа к данным. Сначала была идея напрямую копировать из ОЗУ во флеш двойными словами, но потом пришло понимание, что такое корректно работает только если данные в ОЗУ заранее выровнены по двойному слову. Если же это не так, то приходится копировать их через промежуточный буфер. А с ним, как оказалось, всё уже не так красиво получается, как видилось раньше.
  3. Нет. Там я объявляю массив таких объединений: WordUnion_t src_buf[NWORDS]; Вот ещё вариант для сохранения объекта произвольного размера без требований к его выравниванию
  4. На следующее 32-битное слово после src_buf[0]. Чтобы это сказать, нужна постановка задачи. Что вы хотите сохранить во флеш? Сколько данных? Какого типа? 8 чисел типа int? Где они расположены? Тоже во флеше по какому-то известному адресу? Или в ОЗУ?
  5. Указатель в каждый момент времени указывает на структуру. Эту структуру. А не на следующие 4 байта. Он не может одновременно указывать в два разных места. Просто объявите указатель на структуру из 4-х байт (а лучше на объединение 32-битного слова и массива из 4-х байт, как я вам предлагал сделать ранее). В цикле же инкрементируйте указатель. Или индексируйте его счётчиком цикла. Тогда ваш указатель будет сдвигаться на 4 байта вперёд за каждую итерацию цикла..
  6. Тогда ответ для вас очевиден - пишите на Си.
  7. До волшебного слова union не догуглили? Прочитайте об этом пару страниц в любой книжке по Си и многое станет делать проще. Не понадобится приведение указателей.
  8. Возможно, потребуется явно сделать указатель константным: #define MODEM_ID (uint32_t* const)&M_ID Или константный указатель на константу, если первое поле структуры объявлено, как указатель на константу: #define MODEM_ID (const uint32_t* const)&M_ID
  9. Вопросы пока не по конкретному МК, а по ассемблеру Cortex-M3. Так что производитель и тип МК не важен. Каков бы ни был МК вопросы и ответы были бы те же самые.
  10. Уже выше ответили, что платность/бесплатность компилятора никак не влияет на сертификацию. Единственная моя проблема сейчас, это как не передавать наш лицензионный ключ третьим лицам. Удалось сгенерировать пакетный файл сборки проекта (Options->Output->Create Batch File) и собрать его в произвольном месте. Но вот выделить отдельно компилятор и заставить его работать из произвольного места - нет. Ругается, что нет лицензии. Не понимаю, откуда он берет лицензию, работая в своей родной папке, и почему не может найти её, работая в другой.
  11. Нельзя. Проект такой как есть. Разработка завершена, КД утверждена. Осталась сертификация. Надо, чтобы в компетентных органах проект собрался один в один из учтённых исходников в тот самый hex-файл, что лежит на инвентарном учете. А для этого нужен именно тот самый компилятор, которым собирался проект, а не какой-то другой.
  12. Это понятно. Не понятно КАК компилятор определяет: заплатили за него или нет? Я вижу 2 возможных варианта: 1. Триальная бесплатная и полнофункциональная платная версии компилятора разные. В бесплатную жестко вшиты ограничения. В платную нет. 2. Есть лишь одна единая версия компилятора - платная полнофункциональная. Но ей требуется валидный файл ключа в его каталоге. Либо, ключ ему надо передавать в качестве одного из параметров каждый раз при запуске.
  13. Организации, производящей сертификацию ПО вся IDE не нужна. Им нужна инструкция по сборке прошивки из исходников. В идеале, запустили один батник - на выходе получили HEX или BIN - сравнили результат с тем, что в КД на инвентарном учете. Совпало - хорошо, работаем дальше. Нет - до-свиданья, ваша учтенная КД противоречит сама себе: из исходников собирается не то. Всю IDE им посылать нельзя - без ключа она не работает. А наш ключ мы им послать не можем. Юридически, им пользоваться можем только мы, и передавать его третьим лицам не имеем права. Не кейген же им посылать с инструкцией по кряку Кейла Вот я и прорабатываю вариант, как выдрать из IDE только компилятор и утилиту типа make, а из проекта мейкфайл, чтобы отработать сборку ПО без IDE. Но, похоже, с Кейлом это не прокатывает. А как же его тогда запускать в иных IDE, типа Eclipse, VScode, QTCreator? Да и просто, безо всяких IDE? Надо мне вот скомпилировать один файл, создаю батник, где вызываю компилятор с нужными мне параметрами. Что ему ещё нужно, чтобы он работал? Лицензионный ключ в параметрах передать?
  14. Это зависит от построения самой IDE. Можно формировать файл сценария сборки и запускать make или любой его аналог. А можно весь сценарий сборки держать в файле проекта, и при сборке сама IDE будет отрабатывать этот сценарий, запуская компилятор и линкер с нужными параметрами. Видимо, в Кейле реализован второй вариант.
  15. Состав и структура проекта задается в панели дерева проекта - там перечень файлов, подлежащих компиляции. В опциях проекта есть опции компиляции, пути поиска включаемых файлов, путь к линкер-скрипту и пр. По идее, всё это является исходными данными для создания мейкфайла. Но не могу нигде найти его в папке проекта, как и саму утилиту make внутри папки с установленной IDE. Кто разбирался с этим, подскажите, где их искать? Или ничего этого в Кейле раздельно не существует, и мейкфайл формируется внутри файла проекта, а функцию утилиты make выполняет сам исполняемый файл IDE?
  16. Там - это вы именно про TSMC? Я бы не сказал. TSMC - крупнейший контрактный производитель с передовым оборудованием и техпроцессами. Нашим разработчикам и изготовителям микросхем (в терминологии Минпромторга это называется российская интегральная схема 2-го уровня), как правило, такого не надо. Им бы техпроцесс потолще 180-65 нм, да фаб попроще. Да и не интересны они для TSMC со своими объёмами заказов. Это как на нефтебазу с суточным оборотом под 1000 тонн с 15-литровой канистрой за бензином приехать. Кому ты там интересен со своими 15 литрами? Вобщем, большинство "наших" заказывает изготовление пластин на китайских фабах попроще.
  17. В предыдущем сообщении дали ссылку на сайт ARM, откуда видно, что в настоящее время ассемблерный стартап признан устаревшим, а рекомендуемым является стартап на Си. Так что не вижу повода утверждать, что startup.c - это нестандартная кустарщина, а startup.s - железобетонный стандарт, один на все времена.
  18. Есть мнение, что язык написания файла startup_<обозначение_процессора> не имеет принципиального значения. И строгого требования к написанию его именно на ассемблере и ни на чём ином нет. Это отдано на откуп производителя. Ни что не мешает условному производителю Х выложить для своего МК на ядре Cortex файлы поддержки в виде пака/SPL/HAL с файлом startup_<обозначение_процессора>.с или startup_<обозначение_процессора>.срр.
  19. И самостоятельно писали реализации требуемых функций. Либо включали в проект файлы, содержащие их. Вот и сейчас вам надо было поступить также: или взять готовое, или написать своё.
  20. #include "crc32.h" //-------------------------------------------------------------------------------------------------------------------------- // Функция расчёта КС CRC-32 // obj_p - указатель на объект // len - размер объекта в байтах // start_val - начальное значение для расчёта: // - для начала нового надо передать 0 // - для продолжения предыдущего надо передать предыдущее значение КС //-------------------------------------------------------------------------------------------------------------------------- uint32_t calc(const void *obj_p, uint32_t len, uint32_t start_val) { // Таблица предвычисленных констант для быстрого расчёта static const uint32_t Crc32Table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; start_val = ~start_val; // начальное значение суммы для расчёта const uint8_t *CurrByte_p = (const uint8_t*)obj_p; // указатель на текущий байт данных // Накапливаем значение while (len--) { start_val = (start_val >> 8) ^ Crc32Table[(start_val ^ *CurrByte_p++) & 0xFF]; } return ~start_val; // возвращаем значение CRC32, как инверсии накопленной суммы }; Это потоково-безопасный вариант, за счет отказа от статической локальной переменной, хранящей предыдущее рассчитанное значение. Теперь оно передаётся параметром. Собственно, это главное достоинство именно такой реализации перед предыдущей. Стоит заметить, что вариант реализации через класс С++, о котором я говорил ранее, изначально по-определению потоково-безопасный. Там накапливаемая сумма является приватным членом класса. Если надо посчитать КС, то каждый поток создает свой локальный экземпляр класса. В результате потоки никак не влияют друг на друга, каждый из них использует и меняет только свои данные.
  21. Верно. Тут почитайте и далее. Там как раз обсуждается работа v8 совместно с утилитами Сеггера 6.хх. С ядром связывается и по JTAG и по SWD.
  22. Вы про сообщение ...defective..., как в этой теме? Это не неисправность отладчика, а защита ПО Сеггера от китайских клонов. Пропишите корректно лицензии: должно быть GDB, а не GDBfull, не должно быть RDDI, серийный номер не из черного списка, и не будет этого сообщения. Даже серийный номер можно не назначать (будет отображаться -1). У меня китайский J-link v8 нормально работает с утилитами Сеггера версии 6.98с, никаких ругательных сообщений нет. Правда я прошиваю им МК с ядрами Cortex-M0/M1/M3/M4.
  23. Слегка модифицировав предыдущий пример функции расчета, можно получить такую, которой можно считать данные с разрывами #include <stdint.h> //-------------------------------------------------------------------------------------------------------------------------- // Тип расчёта: начать новый или продолжить старый //-------------------------------------------------------------------------------------------------------------------------- typedef enum { CALC_NEW, CALC_CONTINUE } CalcVariant_t; //-------------------------------------------------------------------------------------------------------------------------- // Функция расчёта КС CRC-32 // obj_p - указатель на объект // len - размер объекта в байтах // variant - тип расчёта: начать новый или продолжить старый //-------------------------------------------------------------------------------------------------------------------------- uint32_t calc(const void *obj_p, uint32_t len, CalcVariant_t variant) { // Таблица предвычисленных констант для быстрого расчёта static const uint32_t Crc32Table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; static uint32_t CurrVal = 0xFFFFFFFF; // текущее накопленное значение суммы const uint8_t *CurrByte_p = (const uint8_t*)obj_p; // указатель на текущий байт данных if(variant==CALC_NEW) { CurrVal = 0xFFFFFFFF; // для нового расчёта сбрасываем накопленную сумму } while (len--) { CurrVal = (CurrVal >> 8) ^ Crc32Table[(CurrVal ^ *CurrByte_p++) & 0xFF]; } return ~CurrVal; // возвращаем значение CRC32, как инверсии накопленной суммы }; Хорошо видно, зачем нужны локальные статические константы и переменные.
  24. Можно и так. Я просто обратил внимание автора топика на то, что делать так, как он некрасиво. Общие для его функций данные не должны быть видны никому, кроме этих функций. Их надо скрыть. И вот мы не спеша приходим к концепции класса.