void kernel_createtask(int* returnPtr, int priority, int code, int notUsed) { addr mem = allocate_user_memory(); if (mem == NULL) { *returnPtr = -2; } volatile TaskDescriptor* td = &tds[tid_counter]; td->id = tid_counter++; td->state = READY; td->priority = priority; kernel_mytid((int*)&(td->parent_id), 0, 0, 0); td->next = (TaskDescriptor*)NULL; td->sendQ = (TaskDescriptor*)NULL; td->sp = (int*)(mem + STACK_SIZE) - 16; // Bottom of stack are fake register values td->sp[13] = code; // PC_USR td->sp[14] = 0x50; // spsr, enabled IRQ interrupt, disable FIQ td->sp[15] = (int) Exit; // LR_USR scheduler_append(td); *returnPtr = td->id; }
/* * allocate_memory() * * This function attempts to locate sections using * a best-fit algorithm. The term "best-fit" implies * that the smallest suitable free block will be used * for each section. This approach makes efficient use * of the free block list and reduces fragmentation. * * Called by: ldemul_after_allocation() * * Calls: allocate_program_memory() * allocate_data_memory() * bfd_map_over_sections() * * If any of the sub-processes fail, report it * and continue. This helps to suppress misleading * messages, and follows the general philosophy * of doing as much work as we can, despite the * occurrence of fatal errors. */ static void allocate_memory() { int result; lang_output_section_statement_type **last_os; #define ERR_STR " Link Error: Could not allocate " /* save the last output section statement after sequential allocation */ last_os = (lang_output_section_statement_type **) statement_list.tail; /* * Build an ordered list of output sections * that were placed by sequential allocator. * It will help identify any gaps between * output sections that are available. */ pic32_init_section_list (&pic32_section_list); bfd_map_over_sections (link_info.output_bfd, &pic32_build_section_list, NULL); bfd_map_over_sections (link_info.output_bfd, &pic32_build_section_list_vma, NULL); if (pic32_debug) { pic32_print_section_list(unassigned_sections, "unassigned"); pic32_print_section_list(memory_region_list, "memory region"); } result = allocate_data_memory(); if (result != 0) einfo(_("%F%sdata memory\n"), ERR_STR ); result = allocate_program_memory(); if (result != 0) einfo(_("%F%sprogram memory\n"), ERR_STR ); #if 0 if (has_user_defined_memory) { result = allocate_user_memory(); if (result != 0) einfo(_("%F%suser-defined memory region\n"), ERR_STR ); } #endif /* allocate the heap, if required */ /* allocate the stack, unless the user has defined one */ /* free the output section list */ pic32_free_section_list(&pic32_section_list); /* * Scan over the output section statements * and merge any contiguous sections * with the same name, unless the * --unique option tells us not to. * * We start where the sequential allocator * finished, so that any merges are well understood. * For example, all of the best-fit output sections * contain a single input section. */ { lang_statement_union_type *os, *next; asection *sec, *next_sec; unsigned int len, match, merge_sec = 0; bfd_vma sec_len, next_len = 0, merge_len = 0; char *p,*p2; if (pic32_debug) printf("\nScanning the output statements\n"); for (os = (lang_statement_union_type *) *last_os; os != (lang_statement_union_type *) NULL; os = next) { /* clear the accumulator, if we didn't just merge */ if (!merge_sec) merge_len = 0; merge_sec = 0; next = os->header.next; if (os->header.type == lang_output_section_statement_enum) { if (os->output_section_statement.bfd_section == NULL) /* --gc-sections has discarded this section */ continue; sec = os->output_section_statement.bfd_section; if (os->output_section_statement.children.head ->input_section.section->rawsize) sec_len = os->output_section_statement.children.head ->input_section.section->rawsize; else sec_len = os->output_section_statement.children.head ->input_section.section->size; if (!sec || !sec->name) continue; if (next && (next->header.type == lang_output_section_statement_enum)) { next_sec = next->output_section_statement.bfd_section; if (next->output_section_statement.children.head) { if (next->output_section_statement.children.head-> input_section.section->rawsize) next_len = next->output_section_statement.children.head-> input_section.section->rawsize; else next_len = next->output_section_statement.children.head-> input_section.section->size; } if (!next_sec || !next_sec->name) continue; if (next->output_section_statement.children.head-> input_section.section->size == 0) continue; /* if section address and len don't match, continue */ if ((sec->lma + sec_len + merge_len) != next_sec->lma) continue; p = strchr(sec->name, '%'); p2 = strchr(next_sec->name, '%'); if (p && p2) { len = p - sec->name; if (len != (unsigned) (p2 - next_sec->name)) continue; match = (strncmp(sec->name, next_sec->name, len) == 0); } else match = (strcmp(sec->name, next_sec->name) == 0); if (match && !config.unique_orphan_sections && !pic32_unique_section(sec->name) && (pic32_attribute_map(sec) == pic32_attribute_map(next_sec))) { if (pic32_debug) { printf(" Merging output sections %s and %s\n", sec->name, next_sec->name); printf(" %s: addr = %lx, len = %lx\n", sec->name, sec->lma, sec_len + merge_len); printf(" %s: addr = %lx, len = %lx\n", next_sec->name, next_sec->lma, next_len); } merge_sec = 1; /* set a flag to indicate we're merging */ merge_len += next_len; next->output_section_statement.children.head-> input_section.section->output_section = NULL; lang_add_section (&os->output_section_statement.children, next->output_section_statement.children.head ->input_section.section, &os->output_section_statement); /* remove the merged section from output_bfd */ remove_section_from_bfd(link_info.output_bfd, next_sec); } } } if (merge_sec) { os->header.next = next->header.next; /* unlink the merged statement */ next = os; /* try to merge another one */ } } } } /* allocate_memory() */