Замысловатое выражение типа:
__no_init UCHAR usbRxBuf[2][USB_BUFSIZE] __attribute__ ((section (USB_BUFFER_SECTION)))
IAR_SECTION(USB_BUFFER_SECTION); /* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */
Означает: два неинициализируемых массива переменных типа unsigned char размером USB_BUFSIZE расположены в области памяти USB_BUFFER_SECTION.
Смысл прост - статические переменные (те, которые не auto) инициализируются нулями, если не инициализированы явно. __no_init это отменяет. Остальное - похоже на попытку сделать исходник, который может компилироваться как IAR-ом, так и GCC. __attribute__ нужен для GCC, при компиляции IAR-ом эта часть с помощью препроцессора заменяется на пустое место, а IAR_SECTION(section) превращается в @ section - это указание в какой секции разместить переменную.
В результате компилятору достаётся строка:
__no_init unsigned char usbRxBuf[2][USB_BUFSIZE] @ USB_BUFFER_SECTION;
При компиляции GCC - наоборот убирают IAR_SECTION(...), оставляют __attribute__(...).
Что касается примера, то он из серии размещения переменных или массивов в заданных областях памяти. Типично такая кострукция имеет вид:
__no_init UCHAR usbRxBuf[2][USB_BUFSIZE] @ segname
где segname означает имя сегмента памяти, в котором размещается переменная или массив, а __no_init обязательная в таких случаях индульгенция, разрешающая компилятору эту область не инициализировать. Если этого не разрешить, то он, скорее всего, откажется сделать такое размещение. Имена сегментов обычно запрятаны в xcl-файлах линкера, там это имя (USB_BUFFER_SECTION) и нужно искать.
Поскольку компилятор не может принять в качестве segname переменную или константу, а требует явного названия в этом месте имени, то такую подмену приходится делать при помощи дефиниций прекомпилятора #define. #define __attribute__(arg) и #define IAR_SECTION(section) @ section являются такими средствами.
Вторая дефиниция как раз делает такую подстановку, вставляя значок @, а затем приписывая после него то слово, что записано в ее аргументе. А первая дефиниция утрясает согласование типов (впрочем, необходимость этой конструкции мне не до конца понятна).
Таким образом, массив usbRxBuf[2][USB_BUFSIZE] размещается в том месте памяти, которая используется как буфер для USB-канала. Скорее всего, речь идет о режиме работы с двойной буферизацией данных, т.к. массив состоит из двух кусков по USB_BUFSIZE. Такая конструкция позволяет программисту напрямую обращаться к произвольному байту буфера принимаемых данных.
Источник: форум на electronix.ru. |