|
|
  |
Чтение бинарного файла в проэкт TI C5402, Происходит бардак - помогите разобраться... |
|
|
|
May 29 2007, 13:40
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Вроде элементарная вещь - читаю бинарный файл в память C5402, элементарный код, а виснет ... Код: Код #include <stdio.h> #include <stdlib.h>
void f_write(char *str,int arr[],int N); void f_read(char *str,int arr[],int N);
int z1[1000],Nfloat;
void main() { int i;
char str1[]="C:\\Ti\\myprojects\\Project\\Project\\zoom_inst1"; char str2[]="C:\\Ti\\myprojects\\Project\\Project\\zoom_inst1_out";
for (i=0;i<1000;i++) z1[i]=0; puts("start"); f_read(str1,z1,1000); f_write(str2,z1,1000); puts("end"); } void f_read(char *str,int arr[],int N ) { FILE *fr; fr = fopen(str,"rb"); fseek(fr, 0, 0); fread(arr,1,N,fr); fclose(fr); } void f_write(char *str,int arr[],int N) { FILE *fw; fw = fopen(str, "wb"); fwrite(arr,1,N,fw); fclose(fw); } Бинарный файл содержит 5800 последовательных байт (2900 integres), в коде проведенном выше - читаю первых 1000 байт а массив z1 (массив заявлен как integer). На данный момент работаю на симуятор C5402 (т.е. без подключенного борта). В таком состоянии (чтение 1000 байт) - вроде работает нормально, данные читаются в массив z1. Задача - прочесть все 5800 байт из исходного файла. Проблема возникает когда увеличиваю размеры массива и чтения файла - скажем говорю прочитать 2000 байт (измению 1000 на 2000 везде где надо в сорсе) - тут программа виснет где-то в процессе чтения файла. Не пойму что происходит... Конфигурация памяти очень проста: Код MEMORY { PAGE 0: EPROG: origin = 0x1200, len = 0x7c00 PAGE 1: IDATA: origin = 0x80, len =0x8000 }
SECTIONS { .text: {} > EPROG PAGE 0 .bss: {} > IDATA PAGE 1 .const: {} > IDATA PAGE 1 .switch: {} > IDATA PAGE 1 .sysmem: {} > IDATA PAGE 1 .stack {} > IDATA PAGE 1 } думал проблема может быть в памяти - но вроде ее достаточно в конфигурации. Подскажите что может быть ? Спасибо
|
|
|
|
|
May 29 2007, 19:52
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(BratherLU @ May 29 2007, 18:50)  1 - Внимательно посмотрите datasheet на tms5402 а именно раздел Memory Map В Том диапазоне адресов, что Вы указали для EPROG и DATA в .cmd файле у 5402 есть непрерывный участок размером только 0x4000 слов, как для программной памяти так и для памяти данных Полный объем внутреенней оперативной памяти для с5402 (16 кСлов = 0x4000)) Так что если симулятор стерпел, то при загрузке в реальную железку CCS скорее всего изругается  2 - если в регистре pmst MP/MC=0 и OVLY=1 то диапазон 0x0000 0x4000 Это Физичиски Одна и Таже Оперативная Память Спасибо за ответ, на вас можно положиться... Да, cmd файл я взял общего плана, он не тюненный конкретно под аппликацию. Сейчас его подкорректировал под конкретные объемы кода (согласно map файлу): Код MEMORY CONFIGURATION
name origin length used attr fill ---------------------- -------- --------- -------- ---- -------- PAGE 0: EPROG 00000080 00001200 0000106b RWIX
PAGE 1: IDATA 00001200 00004000 00002527 RWIX Согласно этому и желая все вместить во внутреннюю память процессора (она ка вы и сказали от 0х80 до 0х4000 т.е. около 16 kwords), я дал следущую конфигурацию: Код MEMORY { PAGE 0: EPROG: origin = 0x80, len = 0x1200 PAGE 1: IDATA: origin = 0x1280, len =0x2D80 }
SECTIONS { .text: {} > EPROG PAGE 0 .bss: {} > IDATA PAGE 1 .const: {} > IDATA PAGE 1 .switch: {} > IDATA PAGE 1 .sysmem: {} > IDATA PAGE 1 .stack {} > IDATA PAGE 1 } В сумме получается от 0х80 до 0х4000, т.е. влазит вроде во внутреннюю память процессора, но довольно-таки впритык (согласно map файлу, используется под код и данные в сумме в районе 14kB из чуть менее 16 kB всего внутренней). В симуляторе работает на полный файл данных (5800 байт), подключил на борд - пока тоже работает, вроде стабильно. Вопрос будет ли и дальше стабильно работать... Возникает проблема теперь с дальнейшим расширением программы. Подразумеватеся обработки данных, значит и код и данные увеличаться, наверняка внутренней памяти не хватит. На борту есть внешний SRAM который по идее расширяет системную память до 64 kB (максимум данного процессора в обычном режиме работы). Видимо придется разбиратся как кнофигурировать програмно работу с внешней и внутренней памятью (думаю загружать массивы данных во внешнюю, затем подкачивать по частямво внутреннюю для обработки...)...пока для меня это все ново... Цитата(BratherLU @ May 29 2007, 19:59)  Одним словом Вы скорее всего затираете часть кода во время записи данных в Ваши Массивы ООоо, вот это новая инфа к размышлению для меня... Т.е. вы имеете ввиду то что вследствие частичного перекрытия оговоренных в cmd файле зон памяти между кодом и данными, часть данных пишутся в кодовую зону затирая часть кода ? Я принципе я могу это понять, но я всегда считал что линкер сам позаботиться о физическом разделении зон кода и данных, даже ежели они частично перекрываются в заданной конфигурации памяти.... Я ошибаюсь ?
|
|
|
|
|
May 30 2007, 07:04
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(BratherLU @ May 30 2007, 09:37)  Возможно я неправильно выразился - затирается часть кода уже во время выполнения программы (запись в массивы) Из-за того что память данных отображена на программную память
Линкер не причем, он размещает секции кода и данных на тех страницах памяти которые указаны в .cmd, но он ничего не знает о состоянии регистров управления CPU (PMST, ST0, ST1 для с54x)(для него Page 0 и Page 1 - физически разные участки) Программно ввести процессор в нужный режим после ресета = сконфигурировать карту памяти, задать расположение таблицы векторов прерываний, насыщение результата аривфметических операций... - обязанность разработчика. ОК, т.е. если для линкера Page 0 и Page 1 физиечски разные участки, а в cmd файле их адресованные зоны пересекаются, значит похоже действительно в runtime данные (особенно ежели большие массивы) могут затереть часть кода ежели загружаются в зону наложения Page 0 и Page 1. Вроде логично. Значит во избежании этого все-таки лучше наверно не пересекать адресные пространства Page 0 и Page 1 в конфигурации памяти. Так ? Ежели прерывания не используются - я так понимаю нет надобности задавать расположение таблицы векторов, а ошибаюсь ? Нужно будет еще разобраться как и в каком регистре задавать режим насыщения арифметики (хотя подозреваю это может быть default у процессора, не уверен). На данном этапе нужно будет разобраться как конфигурировать внутреннюю и внешнюю память данных так чтоб большие массивы (закачка из файла) помещались во внешнюю, затем по мелким частям подкачивались в мелкие массивы во внутренней памяти для обработки... Тут наверно нужна комбинация соотв. определения конфигурации в cmd файле, плюс соотв. pragma декларации в теле программы где надо...похоже на правду ?
|
|
|
|
|
May 30 2007, 09:21
|
Частый гость
 
Группа: Свой
Сообщений: 103
Регистрация: 16-05-06
Пользователь №: 17 126

|
Цитата ОК, т.е. если для линкера Page 0 и Page 1 физиечски разные участки, а в cmd файле их адресованные зоны пересекаются, значит похоже действительно в runtime данные (особенно ежели большие массивы) могут затереть часть кода ежели загружаются в зону наложения Page 0 и Page 1. Вроде логично. Да Если память данных отображена на память программ Цитата Значит во избежании этого все-таки лучше наверно не пересекать адресные пространства Page 0 и Page 1 в конфигурации памяти. Так ? Так. Если не собираетесь модифицировать код во время выполнения программы и будете использовать только внутреннюю память процессора для кода и данных. Цитата Ежели прерывания не используются - я так понимаю нет надобности задавать расположение таблицы векторов, а ошибаюсь ? Не ошибаетесь по умалчанию она находится в ROM по 0xff80 Цитата Нужно будет еще разобраться как и в каком регистре задавать режим насыщения арифметики (хотя подозреваю это может быть default у процессора, не уверен). Насыщение по умолчанию отклучено. Управляют им два бита sst в регистре pmst и ovm в регистре st1 Цитата На данном этапе нужно будет разобраться как конфигурировать внутреннюю и внешнюю память данных так чтоб большие массивы (закачка из файла) помещались во внешнюю, затем по мелким частям подкачивались в мелкие массивы во внутренней памяти для обработки... Тут наверно нужна комбинация соотв. определения конфигурации в cmd файле, плюс соотв. pragma декларации в теле программы где надо...похоже на правду ? Да
|
|
|
|
|
May 30 2007, 11:57
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(BratherLU @ May 30 2007, 13:21)  Да Если память данных отображена на память программ
Так. Если не собираетесь модифицировать код во время выполнения программы и будете использовать только внутреннюю память процессора для кода и данных.
Не ошибаетесь по умалчанию она находится в ROM по 0xff80
Насыщение по умолчанию отклучено. Управляют им два бита sst в регистре pmst и ovm в регистре st1
Да ОК, понял, thanks. Насколько понял, у C5402 разделить внутреннюю и внешнюю память можно только соответствующей адресацией (или конфигурацией памяти). Судя по его daatsheet, внутренний RAM заканчивается на 0х3FFF, после чего адрессное пространство (0х4000 - 0хEFFF) относиться ко внешнему RAMу. Предполагая что внешний SRAM и повешен на адреса от 0х4000 и выше, я думаю что для разделения внешней и внутренней памяти, я обязан в cmd файле разделить адреса физически (например PAGE 0 разместить во внутреннем RAMе как программа (адреса то 0х3FFF), PAGE 1 разместить во внешней (т.е. указать адресное пространство от 0х4000 до 0хEFFF) и часть во внутренней. Но все PAGES обязаны быть визически расделены адресами. Это верно ? При этом, в SECTIONS определить секции где хранятся большие массивы данных в простарнство относящееся ко внешней памяти, а секции которые будут содержать малекие оперативные массивы данные для текущей обработки - в пространство данных во внутренней памяти. Пока я не совсем понимаю какие из sections содержат большие массивы данных, а в какие идут оперативные данные.... Вот новый cmd файл для моего проэкта (где закачиваются файлы данных): Код MEMORY { PAGE 0: EPROG : origin = 0x80, len = 0x1200 /* Internal RAM */ PAGE 1: INRAM : origin = 0x1280, len = 0x2D80 /* Internal RAM */ PAGE 1: EXRAM : origin = 0x4000, len = 0xAFFF /* External RAM */ }
SECTIONS { .text: {} > EPROG PAGE 0 .bss: {} > EXRAM PAGE 1 .const: {} > INRAM PAGE 1 .switch: {} > INRAM PAGE 1 .sysmem: {} > INRAM PAGE 1 .stack {} > INRAM PAGE 1 .data {} > EXRAM PAGE 1 } Судя по map файлу, 6kB массив данных (закачка с файла), занесен в секцию .bss, посему ее определил во внешний RAM. Но пока не пойму как указать определение оперативных массивов данных (небольших) во внутренний RAM (INRAM)...
|
|
|
|
|
May 30 2007, 12:29
|
Частый гость
 
Группа: Свой
Сообщений: 103
Регистрация: 16-05-06
Пользователь №: 17 126

|
Цитата(Саша Z @ May 30 2007, 15:57)  Но пока не пойму как указать определение оперативных массивов данных (небольших) во внутренний RAM (INRAM)...  вот так-> Цитата //----------------------------------------------------- *.cmd ... SECTIONS { ... .MiniData: {} > INRAM PAGE 1 /*Определяем секцию и помещаем ее в INRAM*/ ... } //----------------------------------------------------- *.c ... #pragma DATA_SECTION(Mini1,".MiniData"); short Mini1[MINI_ARRAY_SIZE]; #pragma DATA_SECTION(Mini2,".MiniData"); short Mini2[MINI_ARRAY_SIZE]; ... //-----------------------------------------------------
|
|
|
|
|
May 30 2007, 19:44
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(BratherLU @ May 30 2007, 16:29)  вот так-> Большое спасибо, сделал подобное вашей подсказке - вроде работает. MAP файл показывает нужно размещение блоков данных во внешней и внутренней памяти. Вам Теперь такое дело: данные из внешней памяти (назовем это bulk storage) будут подкачиваться по частям в два внутренних буфера (processing buffer). Хотелось бы это делать в backgroundе, т.е. например в процессе обработки первого буфера (фильтрация), данные подкачиваются во второй. Затем, как только второй заполнен и первый окончил обработку - начинается обработка второго, тем временем первый сбразывает обработанные данные куда нужно и в него закачивается следущаю порция из внешнего bulkа. И так продолжается ping-pong до окончания обработки всего bulkа. Думаю такого рода закачку данных в backroundе нужно делать DMAями что-б освободить процессор для обработки текущего буфера. Так ? Буду рад услышать ваше мнение.....
|
|
|
|
|
May 31 2007, 05:53
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(BratherLU @ May 31 2007, 09:24)  Если у Вас камень с5402 (без букв) - то номер не пройдет у него ДМА не поддерживает работу с внешней памятью, насколько я знаю. Если у Вас камень с5402А то такое, думаю, можно реализовать, но такую связку мне самому поднимать не приходилось. Опааа, хмм, обломинго...у меня как раз С5402 (без букв). Вот засада... Спасибо за ценную инфу - я почему-то не видел в его datasheet заявления о том что его DMAи только дня внутренней памяти...наверно плохо смотрел - поищу еще раз для наглядности. Значит выхода нет, в backgroundе не смогу подкачивать из внешней...  и тогда значит нет смысла в двух буферах и ping-pongе ? Или все-таки на ваш вгляд это да поможет каким-то образом ?
|
|
|
|
|
May 31 2007, 08:29
|
Знающий
   
Группа: Свой
Сообщений: 921
Регистрация: 6-04-07
Из: Israel
Пользователь №: 26 822

|
Цитата(BratherLU @ May 31 2007, 12:16)  Если не риалтайм и с периферией не работаете - не вижу смысла заморачиваться с DMA, тока если пощупать что за зверь. Хотя всей специфики задачи не представляю - может где и можно прикрутить... По поводу DMA memory map c5402(без букв) - spru302а.pdf + sprs079e.pdf(datasheet) OK, болэое спасибо  . Будем обходиться без DMAев. Тут такая чайниковская проблема у меня: http://electronix.ru/forum/index.php?act=S...t=0#entry256741Может сможете помочь чайнику ?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|