Ключевые слова __no_init, __attribute__, IAR_SECTION |
![]() |
Добавил(а) microsin |
Замысловатое выражение типа: __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. |