В OSTaskCreateExt и OSTaskStkInit есть как parameter function pointer "void (*task)(void *p_arg)". Но в MPLAB C30 все pointers только 16-bit. OSTaskStkInit затем некогда запишет до стека неправильный третий байт и как OSCtxSw пустит retfie, наступит AddressError trap. Ошибка ясная, но решение незнакомое. Я не знаю, как получить полный адрес функций

Помогите пожалуйста!
Alex B._
Jun 15 2007, 12:23
Нет там никакой ошибки, вы просто плохо знакомы с компилятором.
С30 для всех функций которые вызываются по указателю создает таблицу переходов в начале памяти программ (т.е. где адрес заведомо меньше 2^16-1) Скомпилируйте пример и посмотрите.
В первом релизе была другая ошибка из-за которой возникал exception при первом переключении контекста, поэтому если качали давно, скачайте новый.
И еще, может интересно будет:
http://www.pic24.ru/uCOS/uCOS_PIC24_dsPIC.pdfhttp://www.pic24.ru/uCOS/uCOS_PIC24_dsPIC.rar
Цитата(Alex B._ @ Jun 15 2007, 16:23)

С30 для всех функций которые вызываются по указателю создает таблицу переходов в начале памяти программ (т.е. где адрес заведомо меньше 2^16-1) Скомпилируйте пример и посмотрите.
Спасибо за ответ Alex. Я посмотрел, nо не поумнел. Вот код из вашего примерa:
/
////////////////////////////////////////////////////////////////////////////////////////////////////
int main (void)
57: {[font=Courier New]
00470 FA0002 lnk #0x2
58: unsigned char errc;
59:
60: OSInit(); // uCOS-II init
00472 0211AE call 0x0011ae
00474 000000 nop
61:
62: // Create start task, that creates all other tasks and events
63:
64: OSTaskCreateExt(AppStartTask, // Create application start task
00476 200030 mov.w #0x3,0x0000 ;OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR
00478 781F80 mov.w 0x0000,[0x001e++]
0047A EB1F80 clr.w [0x001e++] ;(void *)0,
0047C 200806 mov.w #0x80,0x000c ;APP_TASK_START_STK_SIZE
0047E 200007 mov.w #0x0,0x000e
00480 213265 mov.w #0x1326,0x000a ;&AppStartTaskStk[APP_TASK_START_STK_SIZE - 1]
00482 200054 mov.w #0x5,0x0008 ;APP_TASK_START_PRIO
00484 784184 mov.b 0x0008,0x0006
00486 212282 mov.w #0x1228,0x0004 ;&AppStartTaskStk[0]
00488 EB0080 clr.w 0x0002
0048A 204B00 mov.w #0x4b0,0x0000 ;AppStartTask!!! 0x4b0 = реальный адрес, не таблица
0048C 0221EC call 0x0021ec
0048E 000000 nop
65: (void *)0, // Appl start task parameter
66: (OS_STK *)& AppStartTaskStk[0], // Top of task stack pointer
67: APP_TASK_START_PRIO, // Prioriity
68: APP_TASK_START_PRIO, // Task ID - should be the same as priority
69: (OS_STK *)&AppStartTaskStk[APP_TASK_START_STK_SIZE - 1], // Bottom of task stack pointer
70: APP_TASK_START_STK_SIZE, // Stack size
71: (void *)0, // Supplied memory location
72: OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR); // Options
/////////////////////////////////////////////////////////////////////////////////////////////////////
106: __task static void AppStartTask (void *p_arg)
107: {
004B0 FA0002 lnk #0x2
108: unsigned char errc;
109:
110: // Setup RTOS timer
111:
112: T2CON_bit.TCS = 0; // Clock source - internal
004B2 A92110 bclr.b 0x0110,#1
.....
/////////////////////////////////////////////////////////////////////////////////////////////////////
290: INT8U OSTaskCreateExt (void (*task)(void *p_arg),
291: void *p_arg,
292: OS_STK *ptos,
293: INT8U prio,
294: INT16U id,
295: OS_STK *pbos,
296: INT32U stk_size,
297: void *pext,
298: INT16U opt)
299: {
021EC 4787E8 add.w 0x001e,#8,0x001e
021EE BE9F88 mov.d 0x0010,[0x001e++]
021F0 BE9F8A mov.d 0x0014,[0x001e++]
021F2 BE9F8C mov.d 0x0018,[0x001e++]
021F4 781F8E mov.w 0x001c,[0x001e++]
021F6 780600 mov.w 0x0000,0x0018 ;AppStartTask -> W12
021F8 780581 mov.w 0x0002,0x0016
021FA 780502 mov.w 0x0004,0x0014
021FC 9FEFC3 mov.b 0x0006,[0x001e-20]
021FE 780684 mov.w 0x0008,0x001a
02200 780705 mov.w 0x000a,0x001c
02202 BE0406 mov.d 0x000c,0x0010
......
325: psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the task's stack */
0225C 97B19F mov.w [0x001e-30],0x0006
0225E 78010A mov.w 0x0014,0x0004
02260 78008B mov.w 0x0016,0x0002
02262 78000C mov.w 0x0018,0x0000 ;W12 -> task
02264 02071A call 0x00071a
Никакой таблици я не вижу и адрес на task идёт только через 2 байты.
Newegor
Aug 8 2007, 08:31
Пытаюсь первый раз собрать ось по dsPIC30F6014A, но столкнулся со следующей ошибкой при компиляции:
main.c:28: error: syntax error before 'static'
main.c:30: error: syntax error before 'static'
main.c:31: error: syntax error before 'static'
main.c: In function 'main':
main.c:74: warning: pointer targets in passing argument 2 of 'OSTaskNameSet' differ in signedness
main.c: At top level:
main.c:106: error: syntax error before 'static'
main.c: In function 'AppStartTask':
main.c:151: warning: pointer targets in passing argument 2 of 'OSTaskNameSet' differ in signedness
main.c:163: warning: pointer targets in passing argument 2 of 'OSTaskNameSet' differ in signedness
main.c:175: warning: pointer targets in passing argument 2 of 'OSTaskNameSet' differ in signedness
main.c:178: warning: pointer targets in passing argument 2 of 'OSEventNameSet' differ in signedness
main.c:180: warning: pointer targets in passing argument 2 of 'OSEventNameSet' differ in signedness
main.c: At top level:
main.c:229: error: syntax error before 'static'
main.c:246: error: syntax error before 'static'
за основу брал порт из поста Alex B._ выше. В чем может быть проблема?
Alex B._
Aug 8 2007, 12:26
Newegor
не знаю в чем у вас может быть проблема... только что скачал, все скомпилилось.
На
main.c:151: warning: pointer targets in passing argument 2 of 'OSTaskNameSet' differ in signedness
не обращайте внимания - тип параметра у функци - указатель на unsigned char, хотя констовая строка это всегда signed char
Видимо он у вас ругается на квалификатор функции __task (он через #define определен) - попробуйте их все удалить, смысл не поменяется. Хотя, повторяю, у меня все скомпилилось. Версия компилятора какая у вас?
2jezo
>> Никакой таблици я не вижу
значит не туда смотрите. Надо глядеть после таблицы векторов прерываний
Newegor
Aug 8 2007, 12:41
да действительно ругается на __task, если удалить, то все нормально. спасибо.
Alex B._
Aug 8 2007, 19:22
компилятор-то какой?
__task определен дефайном как __attribute((noreturn))__ , т.е. при вхождении в функцию не выделяется фрейм в стеке для локальных переменных. Если их много, то это помогает чуть меньше памяти под стек задачи выделять...
Newegor
Aug 9 2007, 05:45
Разобрался! При портировании под другой пик, я случайно удалил этот дефайн, поэтому и ругался. Восстановил и все заработало так как надо
Alex B._
Aug 9 2007, 06:56
Только используйте аккуратно - в этом порте есть баги:
1) для прерываний которые могут переключить контекст (в которых вызываются системные сервисы) нужно использовать только один приоритет
2) дурацкий баг с восстановлением флага аппаратного цикла repeat
на днях обновление выложу, все никак руки не доходят. Поучиться пока можно на этом релизе
Newegor
Aug 9 2007, 07:12
И еще вопрос, стоит ли обратить внимание на вот эти варнинги при компиляции (просто не понимаю чем они вызваны)
os_core.c: In function 'OSIntExit':
os_core.c:346: warning: implicit declaration of function 'OSIntCtxSw'
os_core.c: In function 'OSStart':
os_core.c:465: warning: implicit declaration of function 'OSStartHighRdy'
Alex B._
Aug 9 2007, 09:01
это вы опять чего-то с h-файлами намудрили... Нет таких ошибок.
>> просто не понимаю чем они вызваны
это предупреждение копмилятора о том, что вызывается функция, которая ранее не объявлена. Тем не менее линкер все нормально соберет.
Цитата(Alex B._ @ Aug 8 2007, 16:26)

2jezo
>> Никакой таблици я не вижу
значит не туда смотрите. Надо глядеть после таблицы векторов прерываний
Да, таблицa переходов есть, но я не вижу её использовать. Когда просмотришь дисасембл, как параметр OSTaskCreateExt(AppStartTask,...) передается реальный адрес на AppStartTask, не 0x200 (вектор из таблицы)! Затем OSTaskCreateExt перенесёт адрес в OSTaskStkInit и он возложит её до стеку. Если адрес > 0xffff, наступит ошибкa в OS_TASK_SW...
У меня последний C30 и settings:
-g -mlarge-code -mlarge-data -mlarge-scalar -O1
Alex B._
Aug 9 2007, 12:51
>> Да, таблицa переходов есть, но я не вижу её использовать
Да не надо ее пользовать! Ее компилятор пользует. Если функция в адресном пространстве до 0x10000, используется прямой адрес...
Не заморачивайтесь. Можете попробовать указать атрибут у функии задачи, чтобы компилер расположил ее по абсолютном адресу больше 0xFFFF и посмотреть, как будет передаваться указатель
Цитата(Alex B._ @ Aug 9 2007, 16:51)

>> Да, таблицa переходов есть, но я не вижу её использовать
Да не надо ее пользовать! Ее компилятор пользует. Если функция в адресном пространстве до 0x10000, используется прямой адрес...
OK, спасибо за пояснение. Ну затем строчка в OSTaskStkInit:
pc_high = (INT8U)(((INT32U)task >> 16) & 0x7F);
не имеет никакой смысл. На етой строчке мне начал код ошибаться. Моя программa ~80kB, 8 задач и все в нижной памяти. Но с одного времени у одного таску начало наполнять pc_high неправильным номером, и сделалo address error trap. Потому я дал твёрдо pc_high = 0 и пока всё работает правильно.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.