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.