Blue Pill 120kb ?
- Войдите на сайт для отправки комментариев
Предыстория достаточно банальная: прикинул, что нужно для проекта, все проверил на беспаечной макетке, убедился, что работает. Все распаял, напечатал корпус и засунул в него. Теперь: пиши себе софт - не хочу!
Но постепенно запас свободной памяти стал уменьшаться. Был даже курьез: для вывода числа в строку попытался использовать sprintf(). Объем занятой памяти сразу подскочил с 49к до 63к. 63к при доступных 64к и далеком от завершения проекте - это катастрофа! Локально, конечно, проблему я решил, заменив sprintf на короткую функцию объемом в десятки байтов, которая делает ровно то, что мне нужно, и ничего лишнего. И в дальнейшем стал за расходом памяти пристально следить.
Но, чудес не бывает - объем программы на настоящий момент перевалил за 57к. Так что осталось совсем немного. Что делать?
Ну, первое, обратить внимание, естественно, на stm32f103cb. Поиск, однако, показал, что найти плату на 103cb в конструктиве Blue Pill весьма проблематично. Почему-то мне попадались исключительно Maple Mini, которые отличаются от Blue Pill расположением выводов.
Можно, конечно, попытаться переделать существующую плату либо сделать новую. Но геморрой!
Ну и вообще пайка мне как-то удовольствия не доставляет.
В И-нете полно информации, что у обычного 103c8, оказывается не 64, а на самом деле 128к памяти. В принципе, информация правдоподобная, т.к. проще выпускать несколько разных камней по одной маске, ав потом распределять методом отбраковки. Ну а т.к. дешевых камней, как правило, нужно существенно больше, то помимо отбраковки в число дешевых попадают и вполне исправные. Правда - никаких гарантий!
Ну да ладно.
Полей в дэйташит, а именно на стр. 34, где и расположена карта памяти. И вот что любопытно: под область flach там отведено ровно 128к с 0x08000000 по 0x0801ffff. Что, собственно, и следовало ожидать. Но интересно другое: отчет о загрузке явно указывает:
// попытка чтения flash выше 0x8002000+0x1e000=0x8020000 приводит к зависанию, до этого читается "255" //#include "arr44k.c" #include "arr100k.c" byte aRAM[8] = {0,1,2,3,4,5,6,7}; const byte aFLASH[8] = {8,9,10,11,12,13,14,15}; int ledState = LOW; // ledState used to set the LED unsigned long previousMillis = 0; // will store last time LED was updated const long interval = 1000; // interval at which to blink (milliseconds) void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); while(!Serial); Serial.print("Setup: "); Serial.print((uint32_t)setup, HEX); Serial.print(", "); Serial.println((uint32_t)setup - 0x8002000); Serial.print("aRAM: "); Serial.print((uint32_t)aRAM, HEX); Serial.print(", "); Serial.println((uint32_t)aRAM - 0x20000000); Serial.print("aFLASH: "); Serial.print((uint32_t)aFLASH, HEX); Serial.print(", "); Serial.println((uint32_t)aFLASH - 0x8002000); int n_succ = 0, n_fail = 0; uint32_t t0 = millis(); // for(int i = 0; i < size_arr44k; i++) { // if(arr44k[i] == i) for(int i = 0; i < size_arr100k; i++) { if(arr100k[i] == i) n_succ++; else n_fail++; } uint32_t t1 = millis(); Serial.print("Test results: success: "); Serial.print(n_succ); Serial.print(", fail: "); Serial.print(n_fail); Serial.print(", elapsed time: "); Serial.println(t1-t0); } void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; // ledState = !ledState; digitalWrite(LED_BUILTIN, ledState = !ledState); } if(Serial.available()) { char ch = Serial.read(); if(ch == 'd') { int n = Serial.parseInt(); Serial.println(n, HEX); for(int i = 0; i < 16; i++) { byte* b = (byte*)(n + i + 0x8002000); Serial.print(*b); Serial.print(' '); } Serial.println(); } } }
в скетче используется включаемый файл с данными (константами) на 100к, который, собственно, и используется для проверки, что читается именно то, что записано. По понятным соображениям весь его приводить я не буду:
const int size_arr100k = 25600; const int arr100k[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0.0625 k 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 0.125 k 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 0.1875 k 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 0.25 k 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 0.3125 k 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 0.375 k 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, // 0.4375 k 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, // 0.5 k 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, // 0.5625 k 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, // 0.625 k 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, // 0.6875 k 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, // 0.75 k 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, // 0.8125 k 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, // 0.875 k 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, // 0.9375 k 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, // 1 k 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, // 1.0625 k ... 25552, 25553, 25554, 25555, 25556, 25557, 25558, 25559, 25560, 25561, 25562, 25563, 25564, 25565, 25566, 25567, // 99.875 k 25568, 25569, 25570, 25571, 25572, 25573, 25574, 25575, 25576, 25577, 25578, 25579, 25580, 25581, 25582, 25583, // 99.9375 k 25584, 25585, 25586, 25587, 25588, 25589, 25590, 25591, 25592, 25593, 25594, 25595, 25596, 25597, 25598, 25599 // 100 k };
но при желании каждый может создать его сам при помощи следующей функции:
ofstream outf; // функция для изготовления массива констант для проверки объема памяти stm32f103c8t6 void makeArray(int size, const char * fname) { char fn[32]; strcpy_s(fn, 28, fname); strcat_s(fn, 31, ".c"); outf.open(fn); outf << "const int size_" << fname << " = " << (size / sizeof(int)) << ';' << endl << endl; outf << "const int " << fname << "[] = {" << endl; for (int i = 0; i < (size / sizeof(int)); i++) { outf << i; if(i != (size / sizeof(int) - 1)) outf << ", "; if ((i % 16) == 15) outf << " // " << (i+1)*sizeof(int)/1024.0 << " k" << endl; } outf << "};" << endl; outf.close(); }
Это можно выяснить значительно проще. Когда вы прошиваете в Блюпилл ардуиновский загрузчик - утилита Flash Load Demonstrator сразу пишет, сколько в вашем чипе памяти:
В прошлом году все Блюпиллы. что я купил на Али - были 128К. В последнее время все чаще 64к
Везёт тебе. Мне на пару десятков ни разу 128 не написал.
А подделки blue pill STM32 с 128k попадались ?
типа GD32 , SK32 , CS32 , STM32FEB...
https://cnx-software.ru/2020/03/23/%D0%BA%D0%B0%D0%BA-%D1%80%D0%B0%D1%81%D0%BF%D0%BE%D0%B7%D0%BD%D0%B0%D1%82%D1%8C-%D0%BF%D0%BE%D0%B4%D0%B4%D0%B5%D0%BB%D0%BA%D0%B8-stm32/
фото STM32F103C8 с 64к и 128к : http://we.easyelectronics.ru/qic/podozritelnye-stm32f103c8t6-ugaday-po-vidu-originalnyy.html
Пральна, этт тибе не дурдуина - куда хачу, туда и "руки сую" - эта, панимашъ, эстЭэмина))))))))))))
Вообще у STM32 есть отдельный вектор на случай "чтения байта (слова) из ниоткуда" , т.о. просто взять "любой" адрес и произвести чтение (запись похоже тоже) НЕЛЬЗЯ!
По поводу зависания: если собирать в "кубе" - он на этот вектор ставит "затычку" вида while(1) .
А ток вообще тема интересная, пейшите исчо))))))))))))))))))))
Это можно выяснить значительно проще. Когда вы прошиваете в Блюпилл ардуиновский загрузчик - утилита Flash Load Demonstrator сразу пишет, сколько в вашем чипе памяти:
В прошлом году все Блюпиллы. что я купил на Али - были 128К. В последнее время все чаще 64к
Ну да, через ST-Link Utillity видно то же самое. Правда, беру два контроллера из одной партии, у одного показывает 128к, другого - 64к, но размещенный выше скетч одинаково показывает наличие по 120к у каждого.
Интересно другое: в Ардуино не может быть BluePill с 64 кбайтами памяти, может быть либо только 56к, либо 120к, т.к. загрузка прошивки осуществляется на 8к выше нижней границы flash. Но что-то мне не попадались массовые жалобы на невозможность прошить в stmduino более 56к.
Пральна, этт тибе не дурдуина - куда хачу, туда и "руки сую" - эта, панимашъ, эстЭэмина))))))))))))
Вообще у STM32 есть отдельный вектор на случай "чтения байта (слова) из ниоткуда" , т.о. просто взять "любой" адрес и произвести чтение (запись похоже тоже) НЕЛЬЗЯ!
По поводу зависания: если собирать в "кубе" - он на этот вектор ставит "затычку" вида while(1) .
А ток вообще тема интересная, пейшите исчо))))))))))))))))))))
А где собирался загрузчик для stmduino, я не знаю. Но если бы было просто while(1), светодиод вряд ли бы мигал. Впрочем, зависит от того, что внутри этого самого while.