Думаю, тут два варианта - научить программу переводить битмапы в набор инструкций (вызовы для рисования примитивов или точек), либо извращаться с дефайнами, чтобы только при компиляции под AVR подставлялся специфичный для AVR код, препятствующий копированию в RAM. PS. А вы сами пробовали на МК тестировать? В ARM Cortex-M ведь тоже гарвардская архитектура, и для них тоже видимо придется что-то придумывать.
ArtDen, вы что-то путаете. У Cortex-M3 гарвардская архитектура. Как и в вашем STM32F100R6T6B. Посмотрите табличку вот тут, раздел "Instruction sets". Видно, что не у всех Cortex-M архитектура Фон-Неймана.
Всё, разобрался. Мне объяснили, что хотя у CortexM гарвардская архитектура, но для программиста это не важно, т.к. адресное пространство одно и для FLASH-памяти и для ОЗУ, а также команды доступа к ячейкам FLASH и ОЗУ одинаковые. Правда, в вики написано что
Цитата:
Также машина гарвардской архитектуры имеет различные адресные пространства для команд и данных. Так, нулевой адрес инструкций — это не то же самое, что и нулевой адрес данных.
Я тоже для себя разобрался. В английской (и русской тоже) вики в статье про гарвардскую архитектуру приведен также подраздел с описанием т. н. модифицированной гарвардской архитектуры (Modified Harvard architecture) - когда адресное пространство одно, однако доступ к RAM и ROM осуществляется по разным шинам. Так вот ядра Cortex M3 и M4 относятся именно к такой архитектуре, но уточнение "модифицированная" касательно архитектуры часто просто опускается.
Заголовок сообщения: Re: Востребована ли простая GUI-библиотека для LCD?
Добавлено: Сб дек 22, 2012 17:40:28
Друг Кота
Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52 Сообщений: 4468 Откуда: Главный Улей России (Moscow)
Рейтинг сообщения:0
Начал знакомство с STM32 с ядра CortexM4F (STM32F407VG). На сколько я понял из даташита, там вся память (ОЗУ, ПЗУ), регистры и вся периферия идут сплошным файлом. Приведенный пример ниже загружает массив (скомпилированный бинарник) с флеша в ОЗУ и передает ему управление банальным прыжком в область ОЗУ.
main flash firmware (main.cpp)
Код:
#include <ST\iostm32f407VG.h>
////////////////////////////////////////////////////////////////////////////// typedef int (*func)(void);
////////////////////////////////////////////////////////////////////////////// Место, где будет расположена таблица (Начало ОЗУ) #pragma location = 0x20000000 volatile uint32_t io_ptr[20];
////////////////////////////////////////////////////////////////////////////// int main() { uint32_t size =(sizeof(rawData)/4);//Размер бинарника в словах uint32_t start_addr = 0x20000100;//Адрес, куда следует поместить бинарник volatile uint32_t *Raw =(uint32_t*)start_addr;//Передача адреса указателю for(uint32_t x=0; x<size; x++)//Копирование бинарника в ОЗУ { Raw[x]= 0x00000000; Raw[x]|=(uint32_t)(rawData[x][0]<<0); Raw[x]|=(uint32_t)(rawData[x][1]<<8); Raw[x]|=(uint32_t)(rawData[x][2]<<16); Raw[x]|=(uint32_t)(rawData[x][3]<<24); } for(uint32_t y = 0; y<6; y++)//Копирование адресов периферии (для частичного абстрагирования от конкретного камня) { io_ptr[y]= io_p[y]; }
func RAM =(func)Raw[1];//копирование адреса начала программы из Reset_Handler бинарника RAM();//Собственно, само исполнение программы
while(1);//На случай, если программа завершится }
bin array code (main.cpp)
Код:
#include <ST\iostm32f407VG.h> #include "IO_MAP.h"
/////////////////////////////////////////////////////////////////////////////// int main() { RCC_AHB1ENR |= RCC_AHB1ENR_GPIODEN;//Enable GPIO D
GPIOD_MODER |=(GPIO_MODER_MODER15_0 | GPIO_MODER_MODER14_0 | GPIO_MODER_MODER13_0 | GPIO_MODER_MODER12_0);// GPIO Mode Port Out GPIOD_OTYPER = 0x00000000;//Out D type Push-Pull GPIOD_OSPEEDR = 0x00000000;//Out Speed Low (2MHz) GPIOD_PUPDR = 0x00000000;//Not Pull Up/Down while(1) { for(int i = 0 ; i < 0x00FFFFF ; i++){asm("nop");} GPIOD_ODR ^= GPIO_ODR_ODR_15; } }
При компиляции бинарника, в настройках линкера было задано иное адресное пространство для ОЗУ и ПЗУ.
TEST_RAM.icf
Код:
/*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x20000100; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x20000100; define symbol __ICFEDIT_region_ROM_end__ = 0x20017FFE; define symbol __ICFEDIT_region_RAM_start__ = 0x20017FFF; define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_heap__ = 0x800; /**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
initialize by copy { readwrite }; //initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP };
Данный пример говорит о том, что ядру абсолютно начихать на то, где находятся данные, а где программа, несмотря на его гарвардскую архитектуру.
_________________ I am DX168B and this is my favourite forum on internet!
Последний раз редактировалось DX168B Вс дек 23, 2012 13:50:14, всего редактировалось 1 раз.
Заголовок сообщения: Re: Востребована ли простая GUI-библиотека для LCD?
Добавлено: Сб дек 22, 2012 18:41:28
Друг Кота
Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52 Сообщений: 4468 Откуда: Главный Улей России (Moscow)
Рейтинг сообщения:0
Это IARовская директива. Без нее массив копируется в ОЗУ. Причем, хрен знает куда. (в произвольную область ОЗУ) Желательно объявить массив как volatile const , иначе при отсутствии каких либо операций с ним, компилятор его похерит.
Это IARовская директива. Без нее массив копируется в ОЗУ. Причем, хрен знает куда. (в произвольную область ОЗУ)
Очень сильно сомневаюсь, насчёт "копирования в ОЗУ". Константные массивы обычно остаются во флеше. (Ну, если компилятор не совсем глупый, а IAR уж точно не такой)
Заголовок сообщения: Re: Востребована ли простая GUI-библиотека для LCD?
Добавлено: Вс дек 23, 2012 17:58:06
Друг Кота
Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52 Сообщений: 4468 Откуда: Главный Улей России (Moscow)
Рейтинг сообщения:0
Судя по изучению ассемблерного листинга, массив все-таки копировался, несмотря на const. А так, я записал, чтобы оно железно там оставалось. Даже несмотря на утехи компилятора.
_________________ I am DX168B and this is my favourite forum on internet!
Подпрограмму __aeabi_memcpy4 показать немогу, так как она видна только в отладчике. В листинге ее нет. Суть ее, перетащить данные из одной области ОЗУ в другую. С отладчика текст копировать не могу. Если кто покажет как, буду благодарен. Подмечу то, что в данной версии IARа еще плохо проработана поддержка данного камня. В комплекте нет файла iostm32f407vg.h (его я добавил сам, а для других камней есть) Хотя, в отладчике камень есть. По этому, он может и тупить.
Есть еще сомнения?
ArtDen писал(а):
Сделал скроллинг в списке окна выбора. Правда, надо будет скроллер немного по-другому рисовать.
А исходники уже обновлены?
_________________ I am DX168B and this is my favourite forum on internet!
Заголовок сообщения: Re: Востребована ли простая GUI-библиотека для LCD?
Добавлено: Вс дек 23, 2012 21:04:31
Друг Кота
Карма: 25
Рейтинг сообщений: 99
Зарегистрирован: Вс янв 24, 2010 19:19:52 Сообщений: 4468 Откуда: Главный Улей России (Moscow)
Рейтинг сообщения:0
Код:
io_p 0x20018000 0x18 Data Lc main.o [1] //Злосчастный массив. Как видите, ОН В ОЗУ rawData 0x0800021c 0xec Data Lc main.o [1] // Большой массив остался во FLASH
Это плохой пример. Здесь указатели на волатильные регистры, или что-то в этом роде. Поэтому компилятор даже инициализирует их не циклом, а поштучно. (Я думаю, что это не копирование в ОЗУ, а инициализация). Почему вы просто не убрали квалификатор FLASH от rawData? Потому что результат не подтверждает вашу теорию?
Вы правы. Это из-за указателей. Я тоже всегда считал, что модификатор const всегда будет указывать на ПЗУ, но тут это не сработало. Из-за этого и были сомнения.
Вроде и структура объявлена не как volatile:
Код:
typedef struct { __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */ __IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ } GPIO_TypeDef;
Ну, главное что разобрались А с приведением указателей на волатильные структуры к константам во время компиляции и GCC иногда обламывается. (Хотя конкретно этот массив - смог разместить во флеше без проблем). Ладно, думаю что это уже немного оффтопик в данной теме, давайте закруглимся.
Сменилась идеология. 1. Теперь виджет не хранит своё положение и размер для экономии памяти. Размеры и положения теперь задаются в IWidgetVisitor::visit:
2. Координаты и размеры виджетов задаются в процентах относительно ширины и высоты клиентской части экрана. Это позволит проще адаптировать одни и те же окна к разным разрешениям экрана
Ну и по мелочи: виджеты можно раскрашивать. При этом цвет не храниться в самом виджете, а запрашивается каждый раз при отрисовке через WidgetsForm::get_widget_color. Пример раскраски из исходников окна для ввода пина:
Код:
void get_widget_color(const muil::Widget *widget, muil::Color &color) { if (widget == &btn_ent_) color = muil::Color(160, 255, 160); else if (widget == &btn_esc_) color = muil::Color(255, 160, 160); else if (widget == &btn_clr_) color = muil::Color(180, 180, 180); }
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения