Code (does not work):
------
volatile uint32_t currentAlarm = 0xFFFFFFFF;
volatile uint8_t ticksPerMs;
void schedulerInit()
{
ticksPerMs = rtcFrequency / 1000.0;
}
int16_t schedulerAddTask(void(*task)(), uint32_t periodMs) __critical
{
uint8_t i;
int16_t id = -1;
__bit added = FALSE;
uint32_t alarm = currentAlarm;
uint32_t currentTime;
currentTime = rtcGetCurrentTime();
for (i = 0; i < MAX_TASKS; i++)
{
if (!added && !tasks[i].task)
{
tasks[i].alarm = currentTime + (periodMs * ticksPerMs);
tasks[i].task = task;
id = i;
printf("ADDED=%lu, %lu, %u, %lu\r\n", currentTime, periodMs, ticksPerMs, tasks[i].alarm);
added = TRUE;
}
if (tasks[i].task && tasks[i].alarm < alarm) alarm = tasks[i].alarm;
}
if (added && alarm != currentAlarm)
{
currentAlarm = alarm;
rtcWriteAlarm(currentAlarm);
}
return id;
}
Output:
--------
ADDED=45, 2000, 20, 20045
ADDED=20048, 2000, 20, 40048
Code: (works, after changing periodMs to float from uint32_t)
-------------
volatile uint32_t currentAlarm = 0xFFFFFFFF;
volatile uint8_t ticksPerMs;
void schedulerInit()
{
ticksPerMs = rtcFrequency / 1000.0;
}
/**
* Add a task to be processed
*
* Returns the task id or -1 if the task manager cannot handle any more simultaneous tasks
*/
int16_t schedulerAddTask(void(*task)(), float periodMs) __critical
{
uint8_t i;
int16_t id = -1;
__bit added = FALSE;
uint32_t alarm = currentAlarm;
uint32_t currentTime;
currentTime = rtcGetCurrentTime();
for (i = 0; i < MAX_TASKS; i++)
{
if (!added && !tasks[i].task)
{
tasks[i].alarm = currentTime + (periodMs * ticksPerMs);
tasks[i].task = task;
id = i;
printf("ADDED=%lu, %lu, %u, %lu\r\n", currentTime, (uint32_t)periodMs, ticksPerMs, tasks[i].alarm);
added = TRUE;
}
if (tasks[i].task && tasks[i].alarm < alarm) alarm = tasks[i].alarm;
}
if (added && alarm != currentAlarm)
{
currentAlarm = alarm;
rtcWriteAlarm(currentAlarm);
}
return id;
}
Output:
ADDED=45, 2000, 20, 40045
ADDED=40048, 2000, 20, 80048
arguments to sdcc.exe are -c --debug --nooverlay --stack-auto --int-long-reent --float-reent --use-stdout -V -I"C:\SiLabs\MCU\Inc"
Have you rebuilt the run-time library with --stack-auto as well? If the _mullong function (that implements the multiplication of longs) has not been compiled with --stack-auto, but is being used by a program compiled with --stack-auto, then the second operand to the multiplication will not have the correct value. Using float instead will work without rebuilding the run-time library because the corresponding float functions always (at least for mcs51) pass the parameters on the stack or in registers regardless of the --stack-auto option.
I think Erik explained well enough.
Set to pending since Michael never responded afterwards.
I was just using the library that came with sdcc small-stack-auto...
Diff:
I can guess how tasks is declared but I'd rather know from the source. The same goes for the rtcXXX prototypes.
But if I do and test this with the latest sdcc, I cannot reproduce this. If you still experience this problem, please update the report with a complete source to reproduce. For now I close it.