реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Не могу выполнить команду strcpy над массивами, Один массив во флешь. другой в оперативке
*SERG
сообщение Feb 21 2007, 06:52
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



Вот код. Думаю, что неправильно объявляю переменные

char temp_inf[]="";
__flash char const knopka2[]={"knopka2"};


strcpy(temp_inf, knopka2); эту строчку не хочет компелить

Где ошибка sad.gif ?

Или подскажите плиз, как это правильно делается
Go to the top of the page
 
+Quote Post
mihask
сообщение Feb 21 2007, 08:52
Сообщение #2


Частый гость
**

Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905



Цитата(*SERG @ Feb 21 2007, 09:52) *
Вот код. Думаю, что неправильно объявляю переменные

char temp_inf[]="";
__flash char const knopka2[]={"knopka2"};


strcpy(temp_inf, knopka2); эту строчку не хочет компелить

Где ошибка sad.gif ?

Или подскажите плиз, как это правильно делается


Я наверное сейчас глупость скажу smile.gif
А вдруг в компиляторе реализована возможность копирования данных расположенных только
на одном устройстве, т.е. temp_inf и knopka2 - должны быть расположены обе во flash или
обе в ОЗУ. Или такого быть не может? smile.gif
Go to the top of the page
 
+Quote Post
*SERG
сообщение Feb 21 2007, 09:57
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



Да вроде разобрался, надо подключить библиотеку #include <pgmspace.h> и писать strcpy_Р(temp_inf, knopka2); компилятор вроде не ругается. В отладчике и железе ещё не проверял. Так понял что можно ещё через указатель работать, как лучше то?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 21 2007, 10:01
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(*SERG @ Feb 21 2007, 05:52) *
strcpy(temp_inf, knopka2); эту строчку не хочет компелить
Где ошибка sad.gif ?
Ошибка в том, что вы используете функцию, которой необходимо, чтобы обе строки были в ОЗУ. Для доступа во флеш используются совсем другие команды ассемблера.

Поищите подходящую функцию в pgmspace.h

Цитата(*SERG @ Feb 21 2007, 08:57) *
Так понял что можно ещё через указатель работать, как лучше то?
Что значит "еще"? ваши temp_inf и knopka2 и есть самые настоящие указатели.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
*SERG
сообщение Feb 21 2007, 12:56
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



Цитата(Сергей Борщ @ Feb 21 2007, 10:01) *
Цитата(*SERG @ Feb 21 2007, 05:52) *

strcpy(temp_inf, knopka2); эту строчку не хочет компелить
Где ошибка sad.gif ?
Ошибка в том, что вы используете функцию, которой необходимо, чтобы обе строки были в ОЗУ. Для доступа во флеш используются совсем другие команды ассемблера.

Поищите подходящую функцию в pgmspace.h

Цитата(*SERG @ Feb 21 2007, 08:57) *
Так понял что можно ещё через указатель работать, как лучше то?
Что значит "еще"? ваши temp_inf и knopka2 и есть самые настоящие указатели.


Вот пример из пдф, что же тогда за переменная msg

Examples
A program defines a couple of strings that are stored in flash memory:
__flash char str1[] = "Message 1";
__flash char str2[] = "Message 2";
The program creates a __flash pointer to point to one of these strings, and assigns it
to str1:
char __flash *msg;
msg=str1;
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 21 2007, 13:20
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(*SERG @ Feb 21 2007, 16:56) *
Вот пример из пдф, что же тогда за переменная msg
Examples
A program defines a couple of strings that are stored in flash memory:
__flash char str1[] = "Message 1";
__flash char str2[] = "Message 2";
The program creates a __flash pointer to point to one of these strings, and assigns it
to str1:
char __flash *msg;
msg=str1;
str1, str2 и msg - УКАЗАТЕЛИ НА ТИП __flash char


--------------------
Go to the top of the page
 
+Quote Post
*SERG
сообщение Feb 21 2007, 14:47
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



Цитата(prottoss @ Feb 21 2007, 13:20) *
Цитата(*SERG @ Feb 21 2007, 16:56) *
Вот пример из пдф, что же тогда за переменная msg
Examples
A program defines a couple of strings that are stored in flash memory:
__flash char str1[] = "Message 1";
__flash char str2[] = "Message 2";
The program creates a __flash pointer to point to one of these strings, and assigns it
to str1:
char __flash *msg;
msg=str1;
str1, str2 и msg - УКАЗАТЕЛИ НА ТИП __flash char


Т.е. в перменной msg находиться адрес начала массива str1, так чтоли?
И если так, то каким образом массив из флешь в озу можно переписать?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 21 2007, 15:19
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(*SERG @ Feb 21 2007, 13:47) *
Т.е. в перменной msg находиться адрес начала массива str1, так чтоли?
Нет массива str1. Не существует в С понятия "массив". Существуют лишь указатели, и благодаря записи ptr[index] которая тождественна записи *(ptr + index) они могут казаться массивами. Поэтому str1 - это указатель, он хранит адрес того места, в котором размещена строка. Причем поскольку он у вас не константный, вы можете случайно написать str1=str2 и долго потом искать куда же делась первая строка smile.gif
Цитата(*SERG @ Feb 21 2007, 13:47) *
И если так, то каким образом массив из флешь в озу можно переписать?
ищите в том же pgmspace.h аналог функции memcpy.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 21 2007, 16:00
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(*SERG @ Feb 21 2007, 18:47) *
каким образом массив из флешь в озу можно переписать?


Очч просто, и не надо ничего искать smile.gif

Код
void ctrcpy_F(void __flash *fptr, void *sptr){
     char byte;
     char *sp = (char*)sptr;
     char *fp = (char*)fptr;

     while(0 != (byte = *fp++))/* массив fptr обязательно должен заканчиваться нулем, а массив sptr иметь размер равный или больший размеру fptr */
          *sptr++ = byte;
}


--------------------
Go to the top of the page
 
+Quote Post
*SERG
сообщение Feb 21 2007, 19:15
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



Цитата(Сергей Борщ @ Feb 21 2007, 15:19) *
Цитата(*SERG @ Feb 21 2007, 13:47) *

Т.е. в перменной msg находиться адрес начала массива str1, так чтоли?
Нет массива str1. Не существует в С понятия "массив". Существуют лишь указатели, и благодаря записи ptr[index] которая тождественна записи *(ptr + index) они могут казаться массивами. Поэтому str1 - это указатель, он хранит адрес того места, в котором размещена строка. Причем поскольку он у вас не константный, вы можете случайно написать str1=str2 и долго потом искать куда же делась первая строка smile.gif
Цитата(*SERG @ Feb 21 2007, 13:47) *
И если так, то каким образом массив из флешь в озу можно переписать?
ищите в том же pgmspace.h аналог функции memcpy.

Понятно, запишу как const char smile.gif Спасибо!

Цитата(prottoss @ Feb 21 2007, 16:00) *
Цитата(*SERG @ Feb 21 2007, 18:47) *
каким образом массив из флешь в озу можно переписать?


Очч просто, и не надо ничего искать smile.gif

Код
void ctrcpy_F(void __flash *fptr, void *sptr){
     char byte;
     char *sp = (char*)sptr;
     char *fp = (char*)fptr;

     while(0 != (byte = *fp++))/* массив fptr обязательно должен заканчиваться нулем, а массив sptr иметь размер равный или больший размеру fptr */
          *sptr++ = byte;
}



Чёт мне до таких наворотов ещё рановато, надож ещё и понимать что пишешь, что в слепую о перекатывать smile.gif
Пока пишу так

__flash char END[]={0X0D,0X0A};
char temp_inf_usapp[razmer_mas]="";
strcpy_P(temp_inf_flash,END)

а потом работаю с temp_inf_flash

Или это не правельно? Копилятор вроде не ругается smile.gif И Вам спасибо!)
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 21 2007, 19:31
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(*SERG @ Feb 21 2007, 23:15) *
Цитата(Сергей Борщ @ Feb 21 2007, 15:19) *

Цитата(*SERG @ Feb 21 2007, 13:47) *

Т.е. в перменной msg находиться адрес начала массива str1, так чтоли?
Нет массива str1. Не существует в С понятия "массив". Существуют лишь указатели, и благодаря записи ptr[index] которая тождественна записи *(ptr + index) они могут казаться массивами. Поэтому str1 - это указатель, он хранит адрес того места, в котором размещена строка. Причем поскольку он у вас не константный, вы можете случайно написать str1=str2 и долго потом искать куда же делась первая строка smile.gif
Цитата(*SERG @ Feb 21 2007, 13:47) *
И если так, то каким образом массив из флешь в озу можно переписать?
ищите в том же pgmspace.h аналог функции memcpy.

Понятно, запишу как const char smile.gif Спасибо!

Цитата(prottoss @ Feb 21 2007, 16:00) *
Цитата(*SERG @ Feb 21 2007, 18:47) *
каким образом массив из флешь в озу можно переписать?


Очч просто, и не надо ничего искать smile.gif

Код
void ctrcpy_F(void __flash *fptr, void *sptr){
     char byte;
     char *sp = (char*)sptr;
     char *fp = (char*)fptr;

     while(0 != (byte = *fp++))/* массив fptr обязательно должен заканчиваться нулем, а массив sptr иметь размер равный или больший размеру fptr */
          *sptr++ = byte;
}



Чёт мне до таких наворотов ещё рановато, надож ещё и понимать что пишешь, что в слепую о перекатывать smile.gif
Пока пишу так

__flash char END[]={0X0D,0X0A};
char temp_inf_usapp[razmer_mas]="";
strcpy_P(temp_inf_flash,END)

а потом работаю с temp_inf_flash

Или это не правельно? Копилятор вроде не ругается smile.gif И Вам спасибо!)
Блин!!! счас только заметил, что не правильный код написал Вам. Сорри smile.gif Переписываю с подробными комментариями
Код
void strcpy_F(void __flash *fptr, void *sptr){
     char byte;

/* Так как входные указатели имеют "пустой" тип (а это, между прочим, очень удобно, допустим при передаче указателей типов, отличных от char) преобразуем их к типу char */
     char *sp = (char*)sptr; /* преобразовываем указатель к типу char */
     char __flash *fp = (char*)fptr; /* преобразовываем указатель к типу __flash char */
    

/* Массив fptr обязательно должен заканчиваться нулем, а массив sptr иметь размер равный или больший размеру fptr. Нижележащая строчка копирует данные в byte по указателю fp, инкрементирует этот указатель, и проверяет byte на равенство нулю. Если byte НЕ равен нулю, выполняется тело цикла, иначе выход */
     while(0 != (byte = *fp++))

          *sp++ = byte; /* записываем байт по указателю sp и инкрементируем указатель для следующего байта */
}


--------------------
Go to the top of the page
 
+Quote Post
*SERG
сообщение Feb 21 2007, 19:50
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



Цитата(prottoss @ Feb 21 2007, 19:31) *
Цитата(*SERG @ Feb 21 2007, 23:15) *
Цитата(Сергей Борщ @ Feb 21 2007, 15:19) *

Цитата(*SERG @ Feb 21 2007, 13:47) *

Т.е. в перменной msg находиться адрес начала массива str1, так чтоли?
Нет массива str1. Не существует в С понятия "массив". Существуют лишь указатели, и благодаря записи ptr[index] которая тождественна записи *(ptr + index) они могут казаться массивами. Поэтому str1 - это указатель, он хранит адрес того места, в котором размещена строка. Причем поскольку он у вас не константный, вы можете случайно написать str1=str2 и долго потом искать куда же делась первая строка smile.gif
Цитата(*SERG @ Feb 21 2007, 13:47) *
И если так, то каким образом массив из флешь в озу можно переписать?
ищите в том же pgmspace.h аналог функции memcpy.

Понятно, запишу как const char smile.gif Спасибо!

Цитата(prottoss @ Feb 21 2007, 16:00) *
Цитата(*SERG @ Feb 21 2007, 18:47) *
каким образом массив из флешь в озу можно переписать?


Очч просто, и не надо ничего искать smile.gif

Код
void ctrcpy_F(void __flash *fptr, void *sptr){
     char byte;
     char *sp = (char*)sptr;
     char *fp = (char*)fptr;

     while(0 != (byte = *fp++))/* массив fptr обязательно должен заканчиваться нулем, а массив sptr иметь размер равный или больший размеру fptr */
          *sptr++ = byte;
}



Чёт мне до таких наворотов ещё рановато, надож ещё и понимать что пишешь, что в слепую о перекатывать smile.gif
Пока пишу так

__flash char END[]={0X0D,0X0A};
char temp_inf_usapp[razmer_mas]="";
strcpy_P(temp_inf_flash,END)

а потом работаю с temp_inf_flash

Или это не правельно? Копилятор вроде не ругается smile.gif И Вам спасибо!)
Блин!!! счас только заметил, что не правильный код написал Вам. Сорри smile.gif Переписываю с подробными комментариями
Код
void strcpy_F(void __flash *fptr, void *sptr){
     char byte;

/* Так как входные указатели имеют "пустой" тип (а это, между прочим, очень удобно, допустим при передаче указателей типов, отличных от char) преобразуем их к типу char */
     char *sp = (char*)sptr; /* преобразовываем указатель к типу char */
     char __flash *fp = (char*)fptr; /* преобразовываем указатель к типу __flash char */
    

/* Массив fptr обязательно должен заканчиваться нулем, а массив sptr иметь размер равный или больший размеру fptr. Нижележащая строчка копирует данные в byte по указателю fp, инкрементирует этот указатель, и проверяет byte на равенство нулю. Если byte НЕ равен нулю, выполняется тело цикла, иначе выход */
     while(0 != (byte = *fp++))

          *sp++ = byte; /* записываем байт по указателю sp и инкрементируем указатель для следующего байта */
}



Понял местами (ну есть за что зацепится, книжку почитаю), спасибо! Ну как я пишу вроде как более читабельней smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 21 2007, 19:57
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(*SERG @ Feb 21 2007, 18:15) *
Пока пишу так

__flash char END[]={0X0D,0X0A};
char temp_inf_usapp[razmer_mas]="";
strcpy_P(temp_inf_flash,END)

а потом работаю с temp_inf_flash

Или это не правельно? Копилятор вроде не ругается smile.gif И Вам спасибо!)
Почти. Поскольку вы выбрали функцию strcpy_P, ваши "массивы" являются строками. В идеологии С строка - это последовательность байт, оканчивающаяся нулем. Именно по этому нулю строковые функции определяют длину строки (вы ведь не передаете в strcpy_P размер). А ваш массив END содержит всего два байта и нулем не оканчивается. Резюме - это будет работать, если по случайному стечению обстоятельств следующий за END байт во флеш окажется нулевым. Лечить просто: либо __flash char END[]={0X0D,0X0A,0x00}; либо __flash char END[]="\r\n"; либо __flash char END[]="\x0D\x0A"; Вот теперь должно работать. А функцию имени protossa разберите, будет очень полезно - именно так и работает strcpy_P.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
xemul
сообщение Feb 21 2007, 20:49
Сообщение #14



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Может просто слегка подправить стандартную strcpy?
Код
char* strcpy_F(const __flash char* from, char* to)
{
   char* cp = to;
   while(*cp++ = *from++) continue;
   return to;
}
Go to the top of the page
 
+Quote Post
exSSerge
сообщение Feb 21 2007, 21:27
Сообщение #15


Частый гость
**

Группа: Новичок
Сообщений: 136
Регистрация: 18-08-06
Из: Novosibirsk
Пользователь №: 19 655



IAR для AVR имеет специальное расширение для указателей __generic (посмотрите в доке на компилятор).

Как раз для подобных случаев - когда нужно работать то с памятью кода то с данными. При передаче параметров компилятор сам сделает необходимые преобразования типов.

// *to всегда в памяти данных, а from может указывать как на flash, так и на RAM.
char* strcpy_F(const __generic char* from, char* to)
{
.....
}
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 04:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01746 секунд с 7
ELECTRONIX ©2004-2016