This N°9 Posted September 8, 2008 Report Share Posted September 8, 2008 hi there,I'am currently working with the c-MIOS-skeleton. I thought it would be wise to define all fields that will not be changed as const. In some sdcc howtoI read, that there's an explicit directive __code that can be put instead of const, and that tutorialsuggested this too.however the linker seems not to like that. the sdcc says:"gen.c:12715 symbol iTemp6 = [ chn_msg_mask ] is in code space"and the linker says:"gplink: lst.c:187: write_src: Assertion `data & 0x80000000' failed.make: *** [project.hex] Aborted"It seems that it concerns only fields that I pass to a function:MIOS_TIMER_Init(0x00,clear_request_period);unsigned int clear_request_period = 10000000*3;//this worksconst unsigned int clear_request_period = 10000000*3;//doesn't workthanks in advance,this (is my name) Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 8, 2008 Author Report Share Posted September 8, 2008 hmm... It happens just for int-types, and only for some values.. maybe thisis kind of a code-space protecting mechanism or so.. Quote Link to comment Share on other sites More sharing options...
audiocommander Posted September 8, 2008 Report Share Posted September 8, 2008 if the values don't change anyway, why don't you simply define them? A compiler-replaced plain number in code is a constant value as well.#define CLEAR_REQU_PERIOD 30000000and moreover: IMHO in SDCC an int is 16 bit (long is 32 bit), which means that the max size for an int can be 65535. So you are not only trying to put 30000000 in an unsigned int which produces an overflow but also multiplicating 10000000, which I wouldn't regard as very efficient.Cheers,Michael Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 9, 2008 Author Report Share Posted September 9, 2008 ok, thats very true. I didnt see it.but anyway, the error occurs also with small numbers in int-range. and I can't pass a number this large to the timer function, because it requires an int. so I will have tocount.I beleive its not wise to generally use defines, because it's not typed.In some contexts this could generate unnecessary promotions. this is from the sdcc-manual:Here are a few guidelines that will help the compiler generate more efcient code, some of the tips are specic tothis compiler others are generally good programming practice. • Use the smallest data type to represent your data-value. If it is known in advance that the value is going to be less than 256 then use an ’unsigned char’ instead of a ’short’ or ’int’. Please note, that ANSI C requires both signed and unsigned chars to be promoted to ’signed int’ before doing any operation. This promotion can be ! omitted, if the result is the same. The effect of the promotion rules together with the sign-extension is often surprising: unsigned char uc = 0xfe; if (uc * uc < 0) /* this is true! */ { .... } uc * uc is evaluated as (int) uc * (int) uc = (int) 0xfe * (int) 0xfe = (int) 0xfc04 = -1024. Another one: (unsigned char) -12 / (signed char) -3 = ... No, the result is not 4: (int) (unsigned char) -12 / (int) (signed char) -3 = (int) (unsigned char) 0xf4 / (int) (signed char) 0xfd = (int) 0x00f4 / (int) 0xfffd = (int) 0x00f4 / (int) 0xfffd = (int) 244 / (int) -3 = (int) -81 = (int) 0xffaf; Don’t complain, that gcc gives you a different result. gcc uses 32 bit ints, while SDCC uses 16 bit ints. Therefore the results are different. From â€comp.lang.c FAQâ€:I think the multiplication would be optimized by the compiler anyway. Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 9, 2008 Author Report Share Posted September 9, 2008 I tried to reproduce the error. Its not the overflow:no error on compilingconst unsigned int dummy = 20000000;but.. this causes a linker error:const unsigned int dummy = 30000000;gplink: lst.c:187: write_src: Assertion `data & 0x80000000' failed.well, it IS the overflow, combined with some kind of protection for fields in the code space (?)this one works, it's a field in the RAM:unsigned int dummy = 30000000;strange effect, but with no real relevance. I'am brand new to microcontrollers & quite new to c++, so I have to getused to the limitations :-)cheers Quote Link to comment Share on other sites More sharing options...
Durisian Posted September 9, 2008 Report Share Posted September 9, 2008 I'm speculating that the number might wrap aroundI had issues a while back with char not being big enough - I got what I thought at first to be some strange random results when the math gave numbers that were too big.eg: unsigned char test = 255 = 255unsigned char test2 = 257 = 1 Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 9, 2008 Author Report Share Posted September 9, 2008 its more than this, the wrapping is because of the overflow, butthe error appears only if a const is created. consts are stored in the program code space (variables are storedin RAM / stack).so I suppose its a protection mechanism for the program code space.but I think the best solutions is just not creating overflows ;D Quote Link to comment Share on other sites More sharing options...
stryd_one Posted September 13, 2008 Report Share Posted September 13, 2008 Would help if you posted your code....... Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 14, 2008 Author Report Share Posted September 14, 2008 hello stryd_one,Would help if you posted your code.......no, I don't think so.. because the linker error occurs also if I don't do anything with the const. so this post says everything necessary (the const / var is created outside of any function in main.c of the c-skelleton):no error on compilingconst unsigned int dummy = 20000000;but.. this causes a linker error:const unsigned int dummy = 30000000;gplink: lst.c:187: write_src: Assertion `data & 0x80000000' failed.well, it IS the overflow, combined with some kind of protection for fields in the code space (?)this one works, it's a field in the RAM:unsigned int dummy = 30000000;strange effect, but with no real relevance.check it out yourself, If you likeregards, this Quote Link to comment Share on other sites More sharing options...
stryd_one Posted September 16, 2008 Report Share Posted September 16, 2008 no, I don't think so.. Then you're wrong. It's much faster for me to test it if you post your code. Faster means I spend less time on it, which is helpful to me, because I'm too busy to mess around. If you want help, please post your code.Edit: Of course, we don't need the *whole* app... but enough code to replicate the fault is helpful. Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 20, 2008 Author Report Share Posted September 20, 2008 ok, that's what you need to do:-take any application or a fresh and empty c skelleton.-add (one of) these lines to the body of main.c:const unsigned int dummy = 20000000;//no error on compilingconst unsigned int dummy = 30000000;//but.. this causes a linker error:that's all.besides I think this isn't an issue that is worth making much mess about it.It's not an error, it would be just interesting *why* the linker throws an error.I'am sure there is a good reason for it.If you are too busy, just forget it. Quote Link to comment Share on other sites More sharing options...
stryd_one Posted September 20, 2008 Report Share Posted September 20, 2008 What about that assertion error you posted? I don't see why this code should generate that error. I think maybe there's something else here....I tried as you said and got no errors....main.c: ///////////////////////////////////////////////////////////////////////////// // Include files ///////////////////////////////////////////////////////////////////////////// #include <cmios.h> #include <pic18fregs.h> const unsigned int dummya = 20000000; const unsigned int dummyb = 30000000; ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS after startup to initialize the // application ///////////////////////////////////////////////////////////////////////////// void Init(void) __wparam { } ..................etc etc etc............ Compiles fine: C:\Temp\sdcc_skeleton>make rm -rf _output/* rm -rf _output rm -rf *.cod *.map *.lst rm -rf *.hex mkdir -p _output sh C:\MIOS\_SVNMIOS\trunk\bin/mios-gpasm -c -p p18f452 -I./src -I C:\MIOS\_SVNMIOS\trunk/include/asm -I C:\MIOS\_SVNMIOS\trunk/include/share -I C:\MIOS\_SVNMIOS\trunk/modules/app_lcd/dummy -DDEBUG_MODE=0 -DSTACK_HEAD=0x37f -DSTACK_IRQ_HEAD=0x33f -I C:\MIOS\_SVNMIOS\trunk/modules/mios_wrapper C:\MIOS\_SVNMIOS\trunk/modules/mios_wrapper/mios_wrapper.asm -o _output/mios_wrapper.o sh C:\MIOS\_SVNMIOS\trunk\bin/mios-gpasm -c -p p18f452 -I./src -I C:\MIOS\_SVNMIOS\trunk/include/asm -I C:\MIOS\_SVNMIOS\trunk/include/share -I C:\MIOS\_SVNMIOS\trunk/modules/app_lcd/dummy -DDEBUG_MODE=0 C:\MIOS\_SVNMIOS\trunk/modules/app_lcd/dummy/app_lcd.asm -o _output/app_lcd.o sh C:\MIOS\_SVNMIOS\trunk\bin/mios-sdcc -c -mpic16 -p18f452 --fommit-frame-pointer --optimize-goto --optimize-cmp --disable-warning 85 --obanksel=2 -I./src -I C:\MIOS\_SVNMIOS\trunk/include/c -I C:\MIOS\_SVNMIOS\trunk/include/share -DDEBUG_MODE=0 main.c -o _output/main.o C:\MIOS\_SVNMIOS\trunk\bin/mios-gpasm modifies _output/main.asm, result in _output/main__mios-gpasm-tmp.asm gplink -s C:\MIOS\_SVNMIOS\trunk/etc/lkr/p18f452.lkr -m -o project.hex C:\MIOS\_SVNMIOS\trunk/lib/libsdcc.lib C:\MIOS\_SVNMIOS\trunk/lib/pic18f452.lib _output/mios_wrapper.o _output/app_lcd.o _output/main.o C:\Temp\sdcc_skeleton> output ASM... I checked this to ensure the unused variable was not optimised away. ..................etc etc etc............ global _dummya global _dummyb ..................etc etc etc............ ; ; Starting pCode block for Ival code _dummya: DB 0x00, 0x2d ; ; Starting pCode block for Ival _dummyb: DB 0x80, 0xc3 ; ; Starting pCode block Note that it handled the overflow by simply discarding the upper bytes. Interesting, and related to the other thread you helped me on :) project.map (shows memory locations where the data is stored): _dummya 0x0035b6 program extern _output/main__mios-gpasm-tmp.asm _dummyb 0x0035b8 program extern _output/main__mios-gpasm-tmp.asm __str_0 0x0035ba program static _output/main__mios-gpasm-tmp.asm I included the string (That's the "hello world" string) to demonstrate that each variable has reserved sufficient space for both of the two bytes. It all looks ok? To test it, I also tried to add some code which would use these variables, just to ensure the optimiser was not toying with us. It generated some warnings, but the code looks ok. As well as the above, I added: unsigned int dummyc; ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS after startup to initialize the // application ///////////////////////////////////////////////////////////////////////////// void Init(void) __wparam { dummyc = dummya+dummyb; } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS in the mainloop when nothing else is to do ///////////////////////////////////////////////////////////////////////////// void Tick(void) __wparam { dummyc++; } Does generate the same notification you posted in the topic: C:\Temp\sdcc_skeleton>make rm -rf _output/* rm -rf _output rm -rf *.cod *.map *.lst rm -rf *.hex mkdir -p _output sh C:\MIOS\_SVNMIOS\trunk\bin/mios-gpasm -c -p p18f452 -I./src -I C:\MIOS\_SVNMIOS\trunk/include/asm -I C:\MIOS\_SVNMIOS\trunk/include/share -I C:\MIOS\_SVNMIOS\trunk/modules/app_lcd/dummy -DDEBUG_MODE=0 -DSTACK_HEAD=0x37f -DSTACK_IRQ_HEAD=0x33f -I C:\MIOS\_SVNMIOS\trunk/modules/mios_wrapper C:\MIOS\_SVNMIOS\trunk/modules/mios_wrapper/mios_wrapper.asm -o _output/mios_wrapper.o sh C:\MIOS\_SVNMIOS\trunk\bin/mios-gpasm -c -p p18f452 -I./src -I C:\MIOS\_SVNMIOS\trunk/include/asm -I C:\MIOS\_SVNMIOS\trunk/include/share -I C:\MIOS\_SVNMIOS\trunk/modules/app_lcd/dummy -DDEBUG_MODE=0 C:\MIOS\_SVNMIOS\trunk/modules/app_lcd/dummy/app_lcd.asm -o _output/app_lcd.o sh C:\MIOS\_SVNMIOS\trunk\bin/mios-sdcc -c -mpic16 -p18f452 --fommit-frame-pointer --optimize-goto --optimize-cmp --disable-warning 85 --obanksel=2 -I./src -I C:\MIOS\_SVNMIOS\trunk/include/c -I C:\MIOS\_SVNMIOS\trunk/include/share -DDEBUG_MODE=0 main.c -o _output/main.o /home/sdcc-builder/build/sdcc-build/orig/sdcc/src/pic16/gen.c:9229 symbol iTemp0 = [ dummyb ] is in code space /home/sdcc-builder/build/sdcc-build/orig/sdcc/src/pic16/gen.c:9229 symbol iTemp1 = [ dummya ] is in code space C:\MIOS\_SVNMIOS\trunk\bin/mios-gpasm modifies _output/main.asm, result in _output/main__mios-gpasm-tmp.asm gplink -s C:\MIOS\_SVNMIOS\trunk/etc/lkr/p18f452.lkr -m -o project.hex C:\MIOS\_SVNMIOS\trunk/lib/libsdcc.lib C:\MIOS\_SVNMIOS\trunk/lib/pic18f452.lib _output/mios_wrapper.o _output/app_lcd.o _output/main.o C:\Temp\sdcc_skeleton> This is just a notification though, nothing to worry about. It gives you messages like this when you do a few things with the variables. It doesn't give any linker errors, and it does build the hex file and the output ASM looks OK: ; ; Starting pCode block S_main__Tick code _Tick: BANKSEL _dummyc ; .line 42; main.c dummyc++; INCF _dummyc, F, B BNC _10157_DS_ ; removed redundant BANKSEL INCF (_dummyc + 1), F, B _10157_DS_: RETURN ; ; Starting pCode block S_main__Init code _Init: ; .line 32; main.c void Init(void) __wparam MOVFF r0x00, POSTDEC1 MOVFF r0x01, POSTDEC1 MOVFF r0x02, POSTDEC1 MOVFF r0x03, POSTDEC1 ; .line 34; main.c dummyc = dummya+dummyb; MOVLW LOW(_dummyb) MOVWF TBLPTRL MOVLW HIGH(_dummyb) MOVWF TBLPTRH MOVLW UPPER(_dummyb) MOVWF TBLPTRU TBLRD*+ MOVFF TABLAT, r0x00 TBLRD*+ MOVFF TABLAT, r0x01 MOVLW LOW(_dummya) MOVWF TBLPTRL MOVLW HIGH(_dummya) MOVWF TBLPTRH MOVLW UPPER(_dummya) MOVWF TBLPTRU TBLRD*+ MOVFF TABLAT, r0x02 TBLRD*+ MOVFF TABLAT, r0x03 MOVF r0x00, W ADDWF r0x02, W BANKSEL _dummyc MOVWF _dummyc, B MOVF r0x01, W ADDWFC r0x03, W ; removed redundant BANKSEL MOVWF (_dummyc + 1), B MOVFF PREINC1, r0x03 MOVFF PREINC1, r0x02 MOVFF PREINC1, r0x01 MOVFF PREINC1, r0x00 RETURN ; ; Starting pCode block for Ival code _dummya: DB 0x00, 0x2d ; ; Starting pCode block for Ival _dummyb: DB 0x80, 0xc3 ; ; Starting pCode block __str_0: DB 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21 DB 0x00 You mentioned c++ a few times... but we should be using a C compiler... Are you sure you have the correct toolchain? perhaps you can check the versions, by doing : sh --version make --version sed --version sdcc --version gpasm --version and post the results here. Here are mine: C:\Temp\sdcc_skeleton>sh --version GNU bash, version 2.04.0(1)-release (i686-pc-msys) Copyright 1999 Free Software Foundation, Inc. C:\Temp\sdcc_skeleton>make --version GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for i386-pc-mingw32 C:\Temp\sdcc_skeleton>sed --version GNU sed version 3.02 Copyright (C) 1998 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, to the extent permitted by law. C:\Temp\sdcc_skeleton>sdcc --version SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.8.0 #5117 (Mar 23 2008) (MINGW32) C:\Temp\sdcc_skeleton>gpasm --version gpasm-0.13.5 beta C:\Temp\sdcc_skeleton> But if it's not that... I think there is more to the code than you think ;)(aaaand now you know why I'm such a nazi about posting your code) Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 26, 2008 Author Report Share Posted September 26, 2008 ok, here's the code you nazi ;D :// $Id: main.c 333 2008-05-10 20:49:56Z tk $ /* * MIDI-Box Channel-Mapper * * ========================================================================== * * Copyright (C) 2008 Matthias Mächler (maechler@mm-computing.ch) * Licensed for personal non-commercial use only. * All other rights reserved. * * ========================================================================== */ ///////////////////////////////////////////////////////////////////////////// // Include files ///////////////////////////////////////////////////////////////////////////// #include <cmios.h> #include <pic18fregs.h> ///////////////////////////////////////////////////////////////////////////// // Application specific ///////////////////////////////////////////////////////////////////////////// //each set bit of inputs/outputs assigns an channel to the bus (lsb = channel 0, msb = channel 16) struct midi_bus{ unsigned int inputs; unsigned int outputs; }; //--constants-- //--1 tick = 52.428ms; 20 ticks = ca. 1 sec-- //time that the user has to hold the preset/bus button down to init all presets/all buses #define init_request_ticks 60 //time that all the 16 value-leds will flash after a init #define init_ledflash_ticks 7 const unsigned int int_bit_ormask[16] = { 0x0001,0x0002,0x0004,0x0008, 0x0010,0x0020,0x0040,0x0080, 0x0100,0x0200,0x0400,0x0800, 0x1000,0x2000,0x4000,0x8000 }; //--current state-- unsigned char current_screen_num=0;//0:prs;1:bus;2:in;3:out;stored at 0x00 in EEPROM unsigned char current_preset_num=0;//stored at 0x01 of EEPROM unsigned char current_bus_num=0;//stored at 0x02 of EEPROM struct midi_bus current_preset[16];//stored in Bank Stick after change signed char midi_inout_map[16][16];//map the input-> output relations for faster msg forwarding const unsigned int dummyb = 30000000; //--timer-- unsigned char timer_ticks_count=0; //------------------------------------------ //----------application functions----------- //------------------------------------------ void store_preset(unsigned char num) __wparam{ MIOS_BANKSTICK_WritePage(num*64, @current_preset); } void load_preset(unsigned char num) __wparam{ unsigned char bus,chn_in,chn_out,i; MIOS_BANKSTICK_ReadPage(num*64, @current_preset); //extraxt midi_inout_map for(bus=0;bus<16;bus++){ for(chn_in=0;chn_in<16;chn_in++){ if(current_preset[bus].inputs & int_bit_ormask[chn_in]){ i=0; for(chn_out=0;chn_out<16;chn_out++){ if(current_preset[bus].outputs & int_bit_ormask[chn_out]) midi_inout_map[chn_in][i++] = chn_out; } midi_inout_map[chn_in][i] = -1;//terminate list } } } } void screen_init(void) __wparam{ //set bitmask for screen button MIOS_DOUT_SRSet(0x00,MIOS_HLP_GetBitORMask(current_screen_num)); //clear value screen MIOS_DOUT_SRSet(0x01,0x00); MIOS_DOUT_SRSet(0x02,0x00); switch(current_screen_num){ case 0://preset screen if(current_preset_num < 8) MIOS_DOUT_SRSet(0x01,MIOS_HLP_GetBitORMask(current_screen_num)); else MIOS_DOUT_SRSet(0x02,MIOS_HLP_GetBitORMask(current_screen_num-8)); break; case 1://bus screen if(current_bus_num < 8) MIOS_DOUT_SRSet(0x01,MIOS_HLP_GetBitORMask(current_bus_num)); else MIOS_DOUT_SRSet(0x02,MIOS_HLP_GetBitORMask(current_bus_num-8)); break; case 2://inputs screen MIOS_DOUT_SRSet(0x01,(unsigned char)(current_preset[current_bus_num].inputs & 0x00ff)); MIOS_DOUT_SRSet(0x02,(unsigned char)(current_preset[current_bus_num].inputs >>8 & 0x00ff)); break; case 3://outputs screen MIOS_DOUT_SRSet(0x01,(unsigned char)(current_preset[current_bus_num].outputs & 0x00ff)); MIOS_DOUT_SRSet(0x02,(unsigned char)(current_preset[current_bus_num].outputs >>8 & 0x00ff)); } } //inits and stores the current preset. bus0:in_ch,out_ch0;bus1:in_ch1,out_ch1;.. void preset_init(void) __wparam{ unsigned char i; for(i=0;i<16;i++){ current_preset[i].inputs = current_preset[i].outputs = int_bit_ormask[i]; midi_inout_map[i][0]=i; midi_inout_map[i][0]=-1;//terminate } store_preset(current_preset_num); } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS after startup to initialize the // application ///////////////////////////////////////////////////////////////////////////// void Init(void) __wparam{ MIOS_SRIO_UpdateFrqSet(1); // ms MIOS_SRIO_NumberSet(3);//need 20 inputs / outputs MIOS_SRIO_DebounceSet(10); MIOS_BANKSTICK_CtrlSet(0x00);//stick 0, verify enabled //load last application state current_screen_num = MIOS_EEPROM_Read(0x00); current_preset_num = MIOS_EEPROM_Read(0x01); current_bus_num = MIOS_EEPROM_Read(0x02); load_preset(current_preset_num); //init screen screen_init(); } ///////////////////////////////////////////////////////////////////////////// // This function is periodically called by MIOS. The frequency has to be // initialized with MIOS_Timer_Set ///////////////////////////////////////////////////////////////////////////// void Timer(void) __wparam{ unsigned char i; if(++timer_ticks_count >= init_request_ticks){ if(timer_ticks_count == init_request_ticks){ preset_init();//inits the current preset if(!current_screen_num){//page is preset.. for(i=0;i<16;i++)//inits all presets on bankstick(store reset preset) store_preset(i); } else//page is bank so.. store_preset(current_preset_num);//store the current (reset) preset //flash! MIOS_DOUT_SRSet(0x01,0xff); MIOS_DOUT_SRSet(0x02,0xff); } else if(timer_ticks_count >= init_request_ticks+init_ledflash_ticks){ MIOS_TIMER_Stop();//stops the init request countdown screen_init(); } } } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when a MIDI byte has been received ///////////////////////////////////////////////////////////////////////////// void MPROC_NotifyReceivedByte(unsigned char byte) __wparam{ //this function forwards all system messages to the output static unsigned char fx_status = 0; if(byte >= 0xf0){//system status byte MIOS_MIDI_TxBufferPut(byte); //determine status switch(byte){ case 0xf1://midi timecode case 0xf3://songselect fx_status = 1; break; case 0xf2://songposition pointer fx_status = 2; break; case 0xf0://sysex, forward until 0xf7 fx_status = 0xff; break; default://applies also on 0xf7! fx_status = 0; } } else if(fx_status){ MIOS_MIDI_TxBufferPut(byte); if(fx_status!=0xff) fx_status--; } } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when a complete MIDI event has been received ///////////////////////////////////////////////////////////////////////////// void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam{ unsigned char i; unsigned char evnt_type = evnt0 & 0xf0; unsigned char in_chn = evnt0 & 0x0f; unsigned char evnt2_send = !(evnt_type == 0xc0 || evnt_type == 0xd0); for(i=0;i<16 && midi_inout_map[in_chn][i]!=-1;i++){ MIOS_MIDI_TxBufferPut(evnt_type+midi_inout_map[in_chn][i]); MIOS_MIDI_TxBufferPut(evnt1); if(evnt2_send) MIOS_MIDI_TxBufferPut(evnt2); } } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when an button has been toggled // pin_value is 1 when button released, and 0 when button pressed ///////////////////////////////////////////////////////////////////////////// void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam{ unsigned char i,chn_out,chn_in,value; MIOS_TIMER_Stop();//stops the init request countdown if(pin_value) return;//button up, nothing more to do if(pin > 7){ value = pin - 8; switch(current_screen_num){ case 0://preset screen current_preset_num = value; load_preset(current_preset_num); MIOS_EEPROM_Write(0x01,current_preset_num); break; case 1://bus screen current_bus_num = value; MIOS_EEPROM_Write(0x02,current_bus_num); break; case 2://input screen if (MIOS_DIN_PinGet(0x02)){//set/unset input chanel current_preset[current_bus_num].inputs = current_preset[current_bus_num].inputs==int_bit_ormask[value] ? 0x0000 :int_bit_ormask[value]; } else{//add/remove input chanel current_preset[current_bus_num].inputs = (current_preset[current_bus_num].inputs & int_bit_ormask[value])? (current_preset[current_bus_num].inputs ^ int_bit_ormask[value]): (current_preset[current_bus_num].inputs | int_bit_ormask[value]); } //assign the bus's output channels to new input channel on the map i=0; for(chn_out=0;chn_out<16;chn_out++){ if(current_preset[current_bus_num].outputs & int_bit_ormask[chn_out])//this is a bus output midi_inout_map[value][i++] = chn_out; } midi_inout_map[value][i] = -1; break; case 3://output screen if (MIOS_DIN_PinGet(0x03)){//set/unset output chanel current_preset[current_bus_num].outputs = (current_preset[current_bus_num].outputs==int_bit_ormask[value]) ? 0x0000 :int_bit_ormask[value]; } else{//add/remove output chanel current_preset[current_bus_num].outputs = (current_preset[current_bus_num].outputs & int_bit_ormask[value])? (current_preset[current_bus_num].outputs ^ int_bit_ormask[value]): (current_preset[current_bus_num].outputs | int_bit_ormask[value]); } //assign the outputchannels to the bus's input-channels on the map for(chn_in=0;chn_in<16;chn_in++){ if(current_preset[current_bus_num].inputs & int_bit_ormask[chn_in]){//this is a bus input i=0; for(chn_out=0;chn_out<16;chn_out++){ if(current_preset[current_bus_num].outputs & int_bit_ormask[chn_out])//this is a bus output midi_inout_map[chn_in][i++] = chn_out; } midi_inout_map[chn_in][i] = -1; } } break; } } else if(pin < 4){ current_screen_num = pin; MIOS_EEPROM_Write(0x00, current_screen_num); if(pin < 2){//start init request countdown timer_ticks_count = 0; MIOS_TIMER_Init(0x03,0xffff); } } screen_init(); } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when the display content should be // initialized. Thats the case during startup and after a temporary message // has been printed on the screen ///////////////////////////////////////////////////////////////////////////// void DISPLAY_Init(void) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called in the mainloop when no temporary message is shown // on screen. Print the realtime messages here ///////////////////////////////////////////////////////////////////////////// void DISPLAY_Tick(void) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS in the mainloop when nothing else is to do ///////////////////////////////////////////////////////////////////////////// void Tick(void) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when a MIDI event has been received // which has been specified in the MIOS_MPROC_EVENT_TABLE ///////////////////////////////////////////////////////////////////////////// void MPROC_NotifyFoundEvent(unsigned entry, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when a MIDI event has not been completly // received within 2 seconds ///////////////////////////////////////////////////////////////////////////// void MPROC_NotifyTimeout(void) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS before the shift register are loaded ///////////////////////////////////////////////////////////////////////////// void SR_Service_Prepare(void) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS after the shift register have been loaded ///////////////////////////////////////////////////////////////////////////// void SR_Service_Finish(void) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when an encoder has been moved // incrementer is positive when encoder has been turned clockwise, else // it is negative ///////////////////////////////////////////////////////////////////////////// void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam{ } ///////////////////////////////////////////////////////////////////////////// // This function is called by MIOS when a pot has been moved ///////////////////////////////////////////////////////////////////////////// void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam{ } I get this output on compiling: this@this-laptop:~/mios/trunk/apps/midi_mapper$ make rm -rf _output/* rm -rf _output rm -rf *.cod *.map *.lst rm -rf *.hex mkdir -p _output /bin/bash /home/this/mios/trunk/bin/mios-gpasm -c -p p18f452 -I./src -I /home/this/mios/trunk/include/asm -I /home/this/mios/trunk/include/share -I /home/this/mios/trunk/modules/app_lcd/dummy -DDEBUG_MODE=0 -DSTACK_HEAD=0x37f -DSTACK_IRQ_HEAD=0x33f -I /home/this/mios/trunk/modules/mios_wrapper /home/this/mios/trunk/modules/mios_wrapper/mios_wrapper.asm -o _output/mios_wrapper.o /bin/bash /home/this/mios/trunk/bin/mios-gpasm -c -p p18f452 -I./src -I /home/this/mios/trunk/include/asm -I /home/this/mios/trunk/include/share -I /home/this/mios/trunk/modules/app_lcd/dummy -DDEBUG_MODE=0 /home/this/mios/trunk/modules/app_lcd/dummy/app_lcd.asm -o _output/app_lcd.o /bin/bash /home/this/mios/trunk/bin/mios-sdcc -c -mpic16 -p18f452 --fommit-frame-pointer --optimize-goto --optimize-cmp --disable-warning 85 --obanksel=2 -I./src -I /home/this/mios/trunk/include/c -I /home/this/mios/trunk/include/share -DDEBUG_MODE=0 main.c -o _output/main.o /home/this/mios/trunk/bin/mios-gpasm modifies _output/main.asm, result in _output/main__mios-gpasm-tmp.asm gplink -s /home/this/mios/trunk/etc/lkr/p18f452.lkr -m -o project.hex /home/this/mios/trunk/lib/libsdcc.lib /home/this/mios/trunk/lib/pic18f452.lib _output/mios_wrapper.o _output/app_lcd.o _output/main.o gplink: lst.c:187: write_src: Assertion `data & 0x80000000' failed. make: *** [project.hex] Aborted make: *** Datei »project.hex« wird gelöscht this@this-laptop:~/mios/trunk/apps/midi_mapper$ I don't use the const (line 56). so it seems more to matter where in the codespace the const is placed ? gplink: lst.c:187: write_src: Assertion `data & 0x80000000' failed. 0x80'000'000 is muchmuch over the limits of the codespace, so maybe the overflow makes the linker think it has to place the const there? the asm code at the end of the asm file: ; ; Starting pCode block for Ival code _int_bit_ormask: DB 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00 DB 0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08 DB 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80 ; ; Starting pCode block for Ival _dummyb: DB 0x80, 0xc3 ; Statistics: ; code size: 3620 (0x0e24) bytes ( 2.76%) ; 1810 (0x0712) words ; udata size: 320 (0x0140) bytes (25.00%) ; access size: 22 (0x0016) bytes end strange: if I put the const before my 16xint array const, it compiles without assertion. then the asm code looks like this: ; ; Starting pCode block for Ival code _dummyb: DB 0x80, 0xc3 ; ; Starting pCode block for Ival _int_bit_ormask: DB 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00 DB 0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08 DB 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80 ; Statistics: ; code size: 3620 (0x0e24) bytes ( 2.76%) ; 1810 (0x0712) words ; udata size: 320 (0x0140) bytes (25.00%) ; access size: 22 (0x0016) bytes end I can see no difference except of the position of the data.. the whole story with 31000000 except of 30000000 works again: ; ; Starting pCode block for Ival code _int_bit_ormask: DB 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00 DB 0x40, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08 DB 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80 ; ; Starting pCode block for Ival _dummyb: DB 0xc0, 0x05 ; Statistics: ; code size: 3620 (0x0e24) bytes ( 2.76%) ; 1810 (0x0712) words ; udata size: 320 (0x0140) bytes (25.00%) ; access size: 22 (0x0016) bytes end uuuuh.. 3000000 is the magic number ???You mentioned c++ a few times... but we should be using a C compiler... Are you sure y.....yes, my toolchain is ok. I was just not so clearly aware of the difference from c to c++. but I'am currentlyreading more about it. Quote Link to comment Share on other sites More sharing options...
stryd_one Posted September 27, 2008 Report Share Posted September 27, 2008 Hmm... your example makes this smell like a gplink bug or something.... but the code you posted doesn't compile here: main.c:66: error 78: incompatible types from type 'struct midi_bus [16] ' to type 'char generic* ' main.c:71: error 78: incompatible types from type 'struct midi_bus [16] ' to type 'char generic* ' make: *** [_output/main.o] Error 1 Which is still leaving me wondering about your toolchain.perhaps you can check the versions, by doing :sh --versionmake --versionsed --versionsdcc --versiongpasm --versionand post the results here.;) Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 29, 2008 Author Report Share Posted September 29, 2008 here my toolchain-info:bash --versionGNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)make --versionGNU Make 3.81sed --versionGNU sed Version 4.1.5sdcc --versionSDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.0 #4818 (Jan 18 2008) (UNIX)gpasm --versiongpasm-0.13.4 betamain.c:66: error 78: incompatible typesfrom type 'struct midi_bus [16] 'to type 'char generic* 'main.c:71: error 78: incompatible typesfrom type 'struct midi_bus [16] 'to type 'char generic* 'make: *** [_output/main.o] Error 1are you sure you did not mess something up in the code on copy? this errors make no sense to me.the version I posted has a comment line on line 66, line 71 is empty.. 66: //------------------------------------------ 67: 68: void store_preset(unsigned char num) __wparam{ 69: MIOS_BANKSTICK_WritePage(num*64, @current_preset); 70: } 71: 72: void load_preset(unsigned char num) __wparam{the app is in the repository in trunk/apps/midi_mapper/ if you want to check if this compliles with your toolchain. I just commited a version that compiles with no problem for me.by the way: is it normal that svn has delays of several seconds for every action?(commit, checkout, update etc.). for ex. if I 'svn commit', it takes about 10 secondsuntil It starts submiting. Quote Link to comment Share on other sites More sharing options...
stryd_one Posted September 29, 2008 Report Share Posted September 29, 2008 here my toolchain-info:bash --versionGNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)Your /bin/sh may not be pointing to bash. Can you run sh --version like I said? Sorry to be such a nazi again, but there are good reasons why I give the instructions I do.It's also important to run it from the same directory as you would normally run make. This ensures that your search path is setup correctly.FWIW, I don't think this is the problem at all, but it's still best to check.are you sure you did not mess something up in the code on copy? this errors make no sense to me.the version I posted has a comment line on line 66, line 71 is empty.. I'm sure; the code above has this on 66-71: (lines generating errors bolded by me) MIOS_BANKSTICK_WritePage(num*64, @current_preset); } void load_preset(unsigned char num) __wparam{ unsigned char bus,chn_in,chn_out,i; MIOS_BANKSTICK_ReadPage(num*64, @current_preset);I ran a comparison and you have edited some lines between the pasted code and the SVN copy.the app is in the repository in trunk/apps/midi_mapper/ if you want to check if this compliles with your toolchain. I just commited a version that compiles with no problem for me.BTW: I moved this into the processing directory. No, it doesn't compile for me. My SDCC version differs from yours (Mine's newer), but the error seems correct - it is trying to pass a struct (not even a pointer to a struct) to a function expecting a generic pointer. I'm very surprised that this actually works in a midibox, let alone that it compiles. Weird.I hesitated to ask before, but what the heck is that '@' operator for? The compiler seems to be ignoring it. (I'm guessing @ is a C++ operator? Never seen it before. That doesn't say much though hahaha). I replaced it with an '&', and at least it now thinks I'm passing a pointer: main.c:68: error 78: incompatible types from type 'struct midi_bus [16] near* ' to type 'char generic* ' main.c:73: error 78: incompatible types from type 'struct midi_bus [16] near* ' to type 'char generic* ' make: *** [_output/main.o] Error 1 When I forced a typecast, it complied, but I got this linker error: gplink -s C:\MIOS\_SVNMIOS\trunk/etc/lkr/p18f452.lkr -m -o project.hex C:\MIOS\_SVNMIOS\trunk/lib/libsdcc.lib C:\MIOS\_SVNMIOS\trunk/lib/pic18f452.lib _output/mios_wrapper.o _output/app_lcd.o _output/main.o error: multiple sections using address 0 make: *** [project.hex] Error 1 I've just tried it with the latest nightly build (todays - 2.8.4 build 5424) and get the same errors. I fooled with it a bit but I can't get it to behave. Sorry mate I'll have to leave it with you for now...by the way: is it normal that svn has delays of several seconds for every action?It always has for me. :-\and is it possible to configure the ssh stuff for not always havingto enter the passphrase? If you're on windows you can use pageant (see the svn doco on the wiki), not sure about linux though. I'd LOVE to know, if you find out! Quote Link to comment Share on other sites More sharing options...
This N°9 Posted September 29, 2008 Author Report Share Posted September 29, 2008 I'm sure; the code above has this on 66-71: (lines generating errors bolded by me) MIOS_BANKSTICK_WritePage(num*64, @current_preset); } void load_preset(unsigned char num) __wparam{ unsigned char bus,chn_in,chn_out,i; MIOS_BANKSTICK_ReadPage(num*64, @current_preset);oh, you just found a bug in my code... I'am used from pascal/delphi to use@ as address-operator, in c it's &.. shame on me.. thank you! I could nottest the app until now, because I wait for some DIL pin header.your newer compiler seems to be less "tolerant".. I'llupdate mine.BTW: I moved this into the processing directory.I originally put it in there.. somebody moved it out there. and younow move it in again. *ärger*anyway. please let it reside in processing now, because this is thematching category.and how did you move it? did you use "svn move"? becauseI could not commit my working copy after you moved thefolder. I guess with "svn move" the client will be informedabout the move if it commits the moved folder?Your /bin/sh may not be pointing to bash. Can you run sh --version like I said? Sorry to be such a nazi again, but there are good reasons why I give the instructions I do.I'am a kubuntu user, and I had to set the env var $MIOS_SHELL to point to bash.this@this-laptop:/bin$ echo $MIOS_SHELL/bin/bashmy /bin/sh is a link to dash:this@this-laptop:/bin$ ls -l shlrwxrwxrwx 1 root root 4 2008-09-04 04:58 sh -> dashthis@this-laptop:~/mios/trunk/apps/processing/midi_mapper$ sh --versionsh: Illegal option --don't worry about the nazi ;)If you're on windows you can use pageant (see the svn doco on the wiki), not sure about linux though. I'd LOVE to know, if you find out!I solved this for me, I use no passphrase at all. just dosh-keygen -p -t dsaenter your old passphrase, then just leave the new passphrase empty. the key stays the same 8) Quote Link to comment Share on other sites More sharing options...
stryd_one Posted September 30, 2008 Report Share Posted September 30, 2008 Yer, sorry about the move. What happened exactly, is a long story, so I'll cut it short and just say: tortoiseSVN went berserk.I am not so sure that's the only bug either, as the pointers to that struct appear to be address 0. I'm not so sure the vars are correctly declared.Nice hack on the passphrase, thanks! Quote Link to comment Share on other sites More sharing options...
This N°9 Posted October 1, 2008 Author Report Share Posted October 1, 2008 @stryd_onethanks for your help, I will check the pointer issue, and hope I'll soon receive my plugsso I can test the application. I documented the whole hardware-building with my camera,so I'll make a detailed doc for hardware and software as well, and hope that somebody elsewill find the device usefull :-)UPDATE: fixed the pointer bug. current_preset is a struct-array. an array variable is already a pointerto the first element, so no address-operator needed at all.. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.