Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Cortex M4F проблема с памятью
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
vanek18
Добрый день! Я работаю с процессором на ядре Cortex M4F. Среда разработки - Keil 4.23. Устройство для навигации. Проблема такая: при увеличении размера прошивки, начинаются глюки. Поясню. Отлаживаюсь я через uart. Вот как должна работать программа(вотразмер прошивки:Program Size: Code=29044 RO-data=652 RW-data=184 ZI-data=13048):
Нажмите для просмотра прикрепленного файла
Следующим шагом я раскомменчиваю вызов одной функции,размер кода увеличивается(Program Size: Code=35892 RO-data=652 RW-data=184 ZI-data=13048):
Нажмите для просмотра прикрепленного файла
Затем еще вызываю одну функцию(Program Size: Code=40528 RO-data=648 RW-data=184 ZI-data=13048):
Нажмите для просмотра прикрепленного файла.
Подскажите пожалуйста,что копать,куда смотреть.
Golikov A.
проверьте размер стэка, потом кучи...
Я думаю дело не в размере кода, а в дополнительном вызове, и как следствие в сохранении доп данных в стэк. Стэк кончается и гадит нормальную память...
vanek18
Цитата(Golikov A. @ Apr 14 2015, 05:34) *
проверьте размер стэка, потом кучи...

С размерами стэка и кучи я игрался уже,не привело к результатам.
У меня на борту 128 КБайт ОЗУ. Из них на стэк и кучу максимально получается выделить около 20 КБайт. Если делаю больше,то программа просто не выполняется. На данный момент размер стэка 16 КБайт, кучи - 4 КБайт.
Дело еще в том,что те 2 функции, которыя я добавлял последовательно, в процессе выполнения программы не вызываются,до них просто не доходит. Поэиому стэк и куча, я думаю не при чем.(или все-таки может быть?)
Изначально все это дело крутилось в RTX RTOS , я на нее грешил. Поэтому перебил прошивку,упростил, сделал без RTOS. Все равно та же лажа.И почему я не могу под стэк побольше памяти выделить...может дело в ОЗУ?
johnshadow
Цитата(vanek18 @ Apr 14 2015, 09:29) *
С размерами стэка и кучи я игрался уже,не привело к результатам.
У меня на борту 128 КБайт ОЗУ. Из них на стэк и кучу максимально получается выделить около 20 КБайт. Если делаю больше,то программа просто не выполняется. На данный момент размер стэка 16 КБайт, кучи - 4 КБайт.
Дело еще в том,что те 2 функции, которыя я добавлял последовательно, в процессе выполнения программы не вызываются,до них просто не доходит. Поэиому стэк и куча, я думаю не при чем.(или все-таки может быть?)
Изначально все это дело крутилось в RTX RTOS , я на нее грешил. Поэтому перебил прошивку,упростил, сделал без RTOS. Все равно та же лажа.И почему я не могу под стэк побольше памяти выделить...может дело в ОЗУ?


Вы случайно CAN, USB, etc не используете? Я встречал на других arm, что фильтра того же CAN в ram лежат. Т.ч. возможно какая-то периферия вам память портит при работе. Если с DMA работаете посмотрите правильно ли настраиваете указатели куда данные складывать, не выходите ли за границы этих участков. А вообще конечно странно, что у стек не можете увеличить. ЗЫ, вы помните, что ram чаще всего на банки делиться?
Я обычно в первом банке храню статические переменные, а второй банк отдаю под кучу и стек. Остаток первого банка можно к куче добавить, если менеджер памяти позволяет. Я пользуюсь heap by zltigo - местного форумчанина (спасибо ему).
Golikov A.
А у вас случаем нигде не настроено так что программа выполняется из RAM? Потому что больше других логических объяснений я не вижу происходящему.

В кейле можно на файлы тыкать правой кнопкой и выбирать откуда будут исполнятся... Все должно работать из флэши
vanek18
Цитата(Golikov A. @ Apr 14 2015, 09:15) *
А у вас случаем нигде не настроено так что программа выполняется из RAM? Потому что больше других логических объяснений я не вижу происходящему.

В кейле можно на файлы тыкать правой кнопкой и выбирать откуда будут исполнятся... Все должно работать из флэши

Вообще это конечно да. НО в моем процессоре нет флешек.
Вот собственно описание базовых регистров процессора:
Нажмите для просмотра прикрепленного файла
А вот то,как я настраиваю проект:
Нажмите для просмотра прикрепленного файла
Все остальные настройки по умолчанию, для файлов никаких дополнительных настроек не выполнялось,все выполняется из IROM1.

Цитата(johnshadow @ Apr 14 2015, 07:49) *
Вы случайно CAN, USB, etc не используете? Я встречал на других arm, что фильтра того же CAN в ram лежат. Т.ч. возможно какая-то периферия вам память портит при работе. Если с DMA работаете посмотрите правильно ли настраиваете указатели куда данные складывать, не выходите ли за границы этих участков. А вообще конечно странно, что у стек не можете увеличить. ЗЫ, вы помните, что ram чаще всего на банки делиться?
Я обычно в первом банке храню статические переменные, а второй банк отдаю под кучу и стек. Остаток первого банка можно к куче добавить, если менеджер памяти позволяет. Я пользуюсь heap by zltigo - местного форумчанина (спасибо ему).

Из периферии используется только UART,+ коррелятор через внешнюю шину.
А вот про менеджер памяти можно поподробнее? Я всегда память распределял стандартными средствами keil.
Golikov A.
А почему у вас IRAM зарезан? на 0х400?

А вы на функции поставили чтобы они из RАМ запускались? Или же все же из IROM?

ну еще хорошо бы поглядеть карту памяти, что там куда легло в итоге.
seniorandre
У меня такое было по молодости. Я тогда неправильный размер для переменной хранения указателя сделал, например int16 хранит адрес максимум 65535 иесли переменная уезжает из этого диапазона, то все падает. Появилось с ростом программы.
Golikov A.
Цитата
Я тогда неправильный размер для переменной хранения указателя сделал

А как вы это умудрились сделать? то есть

int16_t *pointer; - это указатель на 16 битное число, но я не вижу никакой возможности задать размер самого указателя? Я как то думал что это определяется архитектурой, битностью процессора и сделать это как-то самому нереально...

или же вы делали int16_t pointer;

а потом вызывали *((int *)pointer) = 10; ?

но и так беды не будет... что-то я не понимаю что вы сделали, можно чуть подробнее?
seniorandre
ну да в лоб сделал что подобное, потом инкремент или смещение.
Цитата(Golikov A. @ Apr 14 2015, 14:14) *
или же вы делали int16_t pointer;


Это было очень давно еще на Pic16, я даже не вспомню какого там было все размера, может и int8, но искал очень долго.
Мне просто с планшета тяжко описывать.
Я в polnter сохранил указатель на массив, потом взял указатель на элемент массива и записал туда значение. Ну и естественно записал не туда, т.к. массив с ростом программы уехал выше верхнего значения указателя.
vanek18
Цитата(Golikov A. @ Apr 14 2015, 10:58) *
А почему у вас IRAM зарезан? на 0х400?

А вы на функции поставили чтобы они из RАМ запускались? Или же все же из IROM?

ну еще хорошо бы поглядеть карту памяти, что там куда легло в итоге.

Первый КБайт зарезервинован... для каких-то тестов разработчика процессора.
И как явно для функции указать чтобы она из ROM запускалась,я думал это только для файла можно сделать?
Нажмите для просмотра прикрепленного файла

Цитата(seniorandre @ Apr 14 2015, 11:22) *
Я в polnter сохранил указатель на массив, потом взял указатель на элемент массива и записал туда значение. Ну и естественно записал не туда, т.к. массив с ростом программы уехал выше верхнего значения указателя.

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

Еще исключил обработчик прерывания,где собственно все и крутилось. Просто зарядил вызов всех функций в main.
Те же самые симптомы.sad.gif
Golikov A.
0x200026b0 0x00001000 Zero RW 2 HEAP startup.o
0x200036b0 0x00004000 Zero RW 1 STACK startup.o

у вас память до адреса 20000, а вы используете ее до адреса 76B0, странно это...
может у вас табличка с памятью не от того проца, по идее у вас на стэк еще дофига места...





про первый килобайт памяти занятый разработчиком проца - тоже не очень понятно...
что за проц то такой?
vanek18
Цитата(Golikov A. @ Apr 15 2015, 05:00) *
0x200026b0 0x00001000 Zero RW 2 HEAP startup.o
0x200036b0 0x00004000 Zero RW 1 STACK startup.o

у вас память до адреса 20000, а вы используете ее до адреса 76B0, странно это...
может у вас табличка с памятью не от того проца, по идее у вас на стэк еще дофига места...

про первый килобайт памяти занятый разработчиком проца - тоже не очень понятно...
что за проц то такой?

Детище местного подразделения микроэлектроники.
Это опытный образец,поэтому косяки быть могут. Моя задача либо сделать рабочую прошивку,либо указать где косяк,и почему я не могу эту прошивку написать.
Может быть проблема в ОЗУ?
редактор
Может данные в UART идут из локального буфера, поэтому и портятся другими функциями??
vanek18
Цитата(редактор @ Apr 15 2015, 06:09) *
Может данные в UART идут из локального буфера, поэтому и портятся другими функциями??

Дело точно не в uart,потому как я делал прошивку без его использования, и просто через порт на одну из ног процессора посылал единичку, и осциллографом смотрел, выполняется прога или нет. Она НЕ выполнялась.
Еще вопрос...хочу просто протестить RAM. Ограничение на размер стэка или кучи есть какое то?
Golikov A.
на кучу нет, можно вообще без нее,
А стек какой-то минимум имеет, в нем локальные переменные живут и между вызовами функций регистры-данные сохраняются.

Но его можно потаскать по памяти
то есть сначала в конец задвинуть, потом протестить начала памяти, а потом передвинуть на начало и протестить конец
johnshadow
Цитата(vanek18 @ Apr 14 2015, 12:48) *
А вот про менеджер памяти можно поподробнее? Я всегда память распределял стандартными средствами keil.


Брал в этой теме.
Остаток памяти для первого банка берется из переменных в скрипте линковщика (пример для lpc1754):
CODE
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
SEARCH_DIR(.)
/*INCLUDE "memory.ld"*/

MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000
ram (rwx) : ORIGIN = 0x10000000, LENGTH = 0x00004000
ram1 (rwx) : ORIGIN = 0x2007C000, LENGTH = 0x00004000
}

_eram = 0x10000000 + 0x00004000;

/* Section Definitions */
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
KEEP(*(.hware))
KEEP(*(.offset))
KEEP(*(.templ))
KEEP(*(.swvers1))
KEEP(*(.swvers2))
KEEP(*(.swvers3))

*(.text*)

KEEP(*(.init))
KEEP(*(.fini))

/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)

/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)

*(.rodata*)

KEEP(*(.eh_frame*))
} > rom

.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > rom

__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > rom
__exidx_end = .;

. = ALIGN(4);
_etext = .;
_sidata = .;

.data : AT (_etext)
{
_sdata = .;
*(.data .data.*)
. = ALIGN(4);
_edata = .;
} > ram

/* .bss section which is used for uninitialized data */
.bss (NOLOAD) :
{
_sbss = .;
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} > ram

/* heap section */
.heap (COPY):
{
__Heap_Start = .;
_end = __Heap_Start;
end = __Heap_Start;
*(.heap*)
__Heap_End = .;

} > ram

/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.co_stack (NOLOAD):
{
. = ALIGN(8);
*(.co_stack .co_stack.*)
} > ram

/* Set stack top to end of ram , and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(ram ) + LENGTH(ram );
__StackLimit = __StackTop - SIZEOF(.co_stack);
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds ram limit */
ASSERT(__StackLimit >= __Heap_End, "region ram overflowed with stack")

.data_dma (COPY): ALIGN(4)
{
__data_dma_start = .;
KEEP(*(.dma_vars))
} > ram1
. = ALIGN(4);

__data_dma_finish = .;
}

а дальше:

Код
#define SECOND_BANK_END (0x2007FFFFUL)

void init_system_heap(void) {
    extern unsigned long __Heap_Start;
    extern unsigned long __Heap_End;
    extern unsigned long __data_dma_finish;
    system_heap.start = (heap_mcb *) (&__Heap_Start);
    system_heap.freem = (heap_mcb *) (&__Heap_Start);
    system_heap.hsize = (unsigned long) (&__Heap_End) - (unsigned long) (&__Heap_Start) + (unsigned long) 1;

    heapinit(&system_heap);
    heapadd(&system_heap, (heap_mcb *) (&__data_dma_finish), (unsigned long) SECOND_BANK_END - (unsigned long) (&__data_dma_finish));
}

второй банк добавляю соответственно после памяти выделенной для DMA буферов (__data_dma_finish) и до конца второго банка. Для себя добавлял еще обертки для freeRTOS. Только сейчас понял что SECOND_BANK_END можно считать из ram1_ORIGIN+ram1_LENGTH.
Секция .co_stack соответственно используются для стека - т.к. я использую rtos то этот стек используется насколько я понимаю только функцией main до старта шедулера и в обработчиках прерываний).
Код из startup_LPC17xx.c:
Код
#define STACK_SIZE       0x00000100      /*!< The Stack size suggest using even number   */
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];

......
__attribute__ ((used,section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
    /*----------Core Exceptions------------------------------------------------ */
    (void *)&pulStack[STACK_SIZE], /*!< The initial stack pointer         */
    Reset_Handler, /*!< Reset Handler                               */
    NMI_Handler, /*!< NMI Handler                                 */
    HardFault_Handler, /*!< Hard Fault Handler                          */
    MemManage_Handler, /*!< MPU Fault Handler                           */
    BusFault_Handler, /*!< Bus Fault Handler                           */
    UsageFault_Handler, /*!< Usage Fault Handler                         */
    0,0,0,0, /*!< Reserved                                    */
    SVC_Handler, /*!< SVCall Handler                              */
    DebugMon_Handler, /*!< Debug Monitor Handler                       */
    0, /*!< Reserved                                    */
    PendSV_Handler, /*!< PendSV Handler                              */
    SysTick_Handler, /*!< SysTick Handler                             */
....
vanek18
Цитата(Golikov A. @ Apr 15 2015, 07:52) *
на кучу нет, можно вообще без нее,
А стек какой-то минимум имеет, в нем локальные переменные живут и между вызовами функций регистры-данные сохраняются.

Но его можно потаскать по памяти
то есть сначала в конец задвинуть, потом протестить начала памяти, а потом передвинуть на начало и протестить конец

Я конечео имел в виду про максимальный размер...ну да ладно,расскажу что я щас сделал.
Итак, написал прогу которая просто печатает через UART "Hello world" biggrin.gif причем без использования retarget,напрямую через регистры.
Выявил максимальный размер стэка при котором прога работает
Он оказался равным 0х7BBF.
Затем прибавляю 1 байт(стэк = 0x7BC0) прога не работает.
Следущее, сдвигаю область памяти RAM на 64 КБайт, выставляю размер стека 0x7FBF(это как раз 0x7BBF + 0x400 байт урезанных вначале области памяти)-программа работает.
Увеличиваю стек на 1 байт - не работает.
Файл с картой памяти прилагается.
Что за беда?
Кстати как стэк по памяти можно потаскать?
Нажмите для просмотра прикрепленного файла
scifi
Цитата(vanek18 @ Apr 15 2015, 12:49) *
Итак, написал прогу которая просто печатает через UART "Hello world" biggrin.gif причем без использования retarget,напрямую через регистры.
Выявил максимальный размер стэка при котором прога работает
Он оказался равным 0х7BBF.
Затем прибавляю 1 байт(стэк = 0x7BC0) прога не работает.

Какой ужас! Как можно так жить? К чему эти пляски с бубном?

Цитата(Golikov A. @ Apr 15 2015, 10:52) *
Но его можно потаскать по памяти
то есть сначала в конец задвинуть, потом протестить начала памяти, а потом передвинуть на начало и протестить конец

Есть гораздо более цивилизованный способ протестировать макс. использование стека: заполнять стек определённой последовательностью при старте (скажем, 0xDEADBEEF), а потом в любой момент можно посчитать, сколько затёрлось, а сколько - нет.
Golikov A.
Цитата
Какой ужас! Как можно так жить? К чему эти пляски с бубном?


к тому что

Цитата
Детище местного подразделения микроэлектроники.
Это опытный образец,поэтому косяки быть могут. Моя задача либо сделать рабочую прошивку,либо указать где косяк,и почему я не могу эту прошивку написать.
Может быть проблема в ОЗУ?


Общее правила размещение секций производиться в линкере, то есть там можно выделить секцию, указать ей явно где она должна сидеть, и сказать чтобы стэк жил в ней. А как конкретно надо в хелпе читать...


А что если стэк увеличить ни на 1 байт а в 2 раза? Может там что-то с выравниванием? Увеличить на 4 байта?

Ограничение по любой памяти сверху - это ограничение памяти не больше. То есть раздувая стэк на этапе сборки вы получите сообщение что стэк залез на данные и собрать нельзя, но так чтобы что-то не работало из-за большого стека, я еще не слышал... По идее весь РАМ должен быть адресуемым, и потому мало вероятно что какой-то указатель не до тянется...
vanek18
Цитата(Golikov A. @ Apr 15 2015, 10:54) *
А что если стэк увеличить ни на 1 байт а в 2 раза? Может там что-то с выравниванием? Увеличить на 4 байта?

На сколько ни увеличивай,ничего не происходит.
scifi
Кстати, выстрел наугад: у меня когда стек не был выравнен по границе 8 байт, не работали операции с плавучкой. А вдруг это оно?
Golikov A.
А стэк пишется с конца, тут ничего не изменилось? То есть на самом деле размер стэка определяет адрес первого сохраняемого значения.
Смещение на 64 К не привило к падению, а что если размер стека увеличить на 64 К? Взять тот размер что работает и 64К прибавить?
johnshadow
Цитата(scifi @ Apr 15 2015, 14:50) *
Кстати, выстрел наугад: у меня когда стек не был выравнен по границе 8 байт, не работали операции с плавучкой. А вдруг это оно?


Согласен, насколько я встречал стек располагают с выравниванием и размером кратным sizeof(unsigned long). Для cortex m3 размер unsigned int = 4 байта, думаю что и для m4f размер такой же. Т.е. увеличивать\уменьшать размер стека нужно с шагом 4.
aaarrr
Для ARM выравнивание стека производится по границе двух слов (8 байт).

А топикстартеру лучше посмотреть map и проверить значение SP непосредственно перед вызовом printf().
vanek18
Цитата(aaarrr @ Apr 15 2015, 18:56) *
Для ARM выравнивание стека производится по границе двух слов (8 байт).

А топикстартеру лучше посмотреть map и проверить значение SP непосредственно перед вызовом printf().

Итак, выравнивание по границе не привело к успеху. Выравнивать кстати нужно по 8 байтам,там прям в starup.s это указано. Отладчик в моем проце отсутствует.


Цитата(Golikov A. @ Apr 15 2015, 11:56) *
А стэк пишется с конца, тут ничего не изменилось? То есть на самом деле размер стэка определяет адрес первого сохраняемого значения.
Смещение на 64 К не привило к падению, а что если размер стека увеличить на 64 К? Взять тот размер что работает и 64К прибавить?

Увеличение размера стека не помогло.
Я освоил scatter файл,и с его помощью разбил память,отдельно для стека,отдельно для кучи и все остальное пространство собственно для программы.
Вот так выглядит мой scatter
CODE
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************


LOAD_ROM 0x08000000 0x0005FFFF ; load region size_region
{
EXEC_ROM 0x08000000 0x0005FFFF ; load address = execution address
{
*.o (START, +First)
*(InRoot$$Sections)
.ANY (+RO )
}
HEAP_RAM 0x20000400 0x00007BFF ; Heap region Heap_size = 31K
{
*(HEAP)
}
SRAM 0x20008000 0x000FFFF ; RW region RW_size = 64K
{
.ANY (+RW +ZI)
}
STACK_RAM 0x20018000 0x00007FFF ; Stack region Stack_size = 32K
{
*(STACK)
}
}

Карта памяти в приложении.
И моя программа с приветствием миру заработала при любых комбинациях и размерах областей памяти и ее содержимого.
О чудо,подумал я!
И на всякий случай решил удостовериться что ничего не работало. Я снова скомпилировал проект,но уже со стандартными настройками...такой какой был раньше и не работал.
И он ЗАРАБОТАЛ laughing.gif
Что это? И что я сделал этим разбиение памяти?
Нажмите для просмотра прикрепленного файла
aaarrr
Цитата(vanek18 @ Apr 23 2015, 14:46) *
И он ЗАРАБОТАЛ laughing.gif
Что это? И что я сделал этим разбиение памяти?

Можете привести map от неработающего варианта?
vanek18
Цитата(aaarrr @ Apr 23 2015, 11:56) *
Можете привести map от неработающего варианта?

Он чуть выше уже был
aaarrr
Цитата(vanek18 @ Apr 23 2015, 15:06) *

Вот тут интересно было бы узнать значение SP при входе в main().
vanek18
Цитата(aaarrr @ Apr 23 2015, 13:10) *
Вот тут интересно было бы узнать значение SP при входе в main().

Это можно как-то без отладчика сделать?
И факт в том,что сейчас с этой картой памяти он работает! wacko.gif
И кстати тот проект,который вначале темы, работает всегда.
Но когда я все это ставлю на rtx, та же лажа,что и раньше((
aaarrr
Цитата(vanek18 @ Apr 23 2015, 15:18) *
Это можно как-то без отладчика сделать?

Можно как-нибудь так:
Код
int main(void)
{
     unsigned int sp = __current_sp();

     ...
     for(int a = 0; a < 8; a++)
     {
         unsigned int n = sp >> 28;

         uart_putc(n > 9 ? n + 'A' - 10 : n + '0');
         sp <<= 4;
     }
}


Цитата(vanek18 @ Apr 23 2015, 15:18) *
И факт в том,что сейчас с этой картой памяти он работает! wacko.gif

С той, с которой не работал раньше?
seniorandre
Цитата(seniorandre @ Apr 14 2015, 14:06) *
У меня такое было по молодости. Я тогда неправильный размер для переменной хранения указателя сделал, например int16 хранит адрес максимум 65535 иесли переменная уезжает из этого диапазона, то все падает. Появилось с ростом программы.

Сдается что у Вас все таки проблема по работе с указателями. Я сейчас разбирался как раз с проектом, про который я собственно и писал выше. У меня ошибка была когда я сдвигал несколько байт командой компилятора CCS вправо. Вчера глянул на ассемблерный код, который он генерил и понял почему ошибка. Оказывается он почему-то изменял только адрес младшего байта адреса, даже если надо было сдвигать данные в ячейке у которой уже надо менять и старший адрес. И соотв. если группа ячеек попадала в адреса, у которых все байты находятся в группе, у которых старший байт не меняется, то все ок, а если группа адресов смещается, то все перестает работать.
Так и у Вас просто какая-то переменная смещается и все перестает работать. И скорее всего неважно, растет прошивка или уменьшается.
Golikov A.
Цитата
Сдается что у Вас все таки проблема по работе с указателями. Я сейчас разбирался как раз с проектом, про который я собственно и писал выше. У меня ошибка была когда я сдвигал несколько байт командой компилятора CCS вправо.


приведите код пожалуйста, потому что то что вы пишите какой-то запредел...
vanek18
Цитата(aaarrr @ Apr 23 2015, 12:28) *
С той, с которой не работал раньше?

Да,именно та,которая не работала,изменил лишь однажды распределение памяти. И все.
В приложении значения SP и map при распределении памяти *.sct и автоматически соответственно.
Нажмите для просмотра прикрепленного файла
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.