I'm trying to run Virtual_COM_Port from STM32_USB-FS-Device_Lib_V4.0.0. I'm using IAR 7.3. Everything buld ok, but not run usb. I started use debugger. In the function
void USB_Init(void)
{
pInformation = &Device_Info;
pInformation->ControlState = 2;
pProperty = &Device_Property;
pUser_Standard_Requests = &User_Standard_Requests;
/* Initialize devices one by one */
pProperty->Init();
}
on line pProperty = &Device_Property; the debugger jumps to the exception handler HardFault_Handler. What could be the problem? Problem whith IAR or some settings?
You are accesing memmory you shouldn't. Hardfault_handler by default catches all exceptions, configurable fault exceptions are disabled. Try turning on the MemManage_fault:
SCB->CHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
//Set the priority of the MemManage fault (using CMSIS):
NVIC_SetPriority(MemoryManagement_IRQn, *priority*);
//Default name for MemManage fault function is:
void MemManage_Handler(void);
After this your hardfault will probably turn into MemManage_fault. Not much, but it gives you a better idea of what you are dealing with.
Also see this link for debugging hardfaults on iar.
I can't be sure without seeing where you set the Device_Property variable but double check that it is OK to give it's memory address to something else.
Related
I have seen that there are quite a few questions about jumping from an app to the ST system bootloader, for example this one. These use the method of setting the MSP and PC then doing the jump with a function pointer.
This seems to cause an issue with the system bootloader dual-bank management whereby the first jump fails and a second jump needs to be done.
My question is - would it be possible/better to use the user option bytes to jump to the bootloader instead?
Since the OB register is read during boot in the OBL phase, if we set both the "nBOOT1 bit" and "nBOOT_SEL bit" and clear the "nBOOT0 bit" then do a soft reset would this avoid the empty check weirdness and let us jump to the bootloader in one go?
(Just for context - this would be the first step of doing updates via CAN as the MCU in question has a CAN bootloader built in)
Thanks in advance!
After some time tinkering with a dev board and with some help from Tilen Majerle I found that this is indeed possible and does work well.
I added the following in my main() while(1) loop so that when the blue button is pressed, the user option bits are modified and a reset is performed.
I found that we don't have to do the soft reset ourselves as the HAL_FLASH_OB_Launch() function triggers the reset for us, after which we should boot into system memory according to the reference manual page 67.
Also I found that the flash and option bytes must be unlocked before setting the option bytes, but not locked afterwards or the reset won't occur.
Here is the code to do it:
if(HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin) == GPIO_PIN_RESET)
{
// Basic de-bounce for testing
HAL_Delay(100);
while(HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin) == GPIO_PIN_RESET)
{
__NOP();
}
// Read, modify & write user option bits
// nBOOT1 = 1, nBOOT_SEL = 1, nBOOT0 = 0; will select system memory as boot area
uint32_t optBits = FLASH->OPTR;
optBits = (optBits | FLASH_OPTR_nBOOT1 | FLASH_OPTR_nBOOT_SEL);
optBits &= ~(FLASH_OPTR_nBOOT0);
// Unlock flash
HAL_FLASH_Unlock();
// Clear OPTLOCK
HAL_FLASH_OB_Unlock();
// Set up struct with desired bits
FLASH_OBProgramInitTypeDef optionBytesSetting = {0};
optionBytesSetting.OptionType = OPTIONBYTE_USER;
optionBytesSetting.USERConfig = optBits;
optionBytesSetting.USERType = OB_USER_nBOOT0;
// Write Option Bytes
HAL_FLASHEx_OBProgram(&optionBytesSetting);
HAL_Delay(10);
// Soft reset
HAL_FLASH_OB_Launch();
NVIC_SystemReset(); // is not reached
}
I verified that the flash OPTR register is modified correctly (it goes from 0xFFFFFEAA to 0xFBFFFEAA, essentially just the nBOOT0 bit is cleared as the other two bits were already set). The MCU does reset at HAL_FLASH_OB_Launch() as expected and pausing the program reveals that after reset it is running the system bootloader based on the PC address.
I also verified it using STM32CubeProgrammer which allows me to view the PC and option bytes, plus lets me set nBOOT0 back to 1 and boot the board to my app.
As for reverting the OB settings programmatically, you could either use the Write Memory command before jumping to the app, or you could use the Go command to jump to the app then modify the option bytes first thing in your app.
I am trying to implement Counting semaphore using Test&Set.How can I solve the problem of deadlock in this code without disabling interrupts? Is it the case that no other solution is possible?
void wait(semaphore *s){
while(test_and_set(&lock_wait)):
s->val--;
if(s->val<0){
s->queue.enque(This_process);
block();
}
lock_wait = false;
}
void signal(semaphore *s)
{
while(test_and_set(&lock_signal));
s->val++;
if(s->val <= 0)
{
process p = s->queue.dequeue();
wakeup(p);
}
lock_signal = false;
}
Please comment your code. And one more thing what do you got as output while implementing ? Add the output here, also ,bro !
While it is true that turning interrupts off on one processor is insufficient to guarantee atomic memory access in a multiprocessor system (because, as you mention, threads on other processors can still access shared resources), we turn interrupts off for part of the multiprocessor semaphore implementation because we do not want to be descheduled while we are doing a test and set.
If a thread holding the test and set is descheduled, no other threads can do anything with the semaphore (because its count is protected by that test and set) the thread was using while it's asleep (this is not good). In order to guarantee that this doesn't happen we'll turn interrupts on our processor off while using the test and set.
I'm trying to write a kernel module that uses the proc file system to read the total memory of each running process. This is for an assignment and it is suggested that use the information of the "mm_struct" which is inside " "task_struct". I should compare the output of content of the proc file with what I obtain from running "ps -ef". I'm using the seq_file API to read from the proc file. My current read function looks like this:
static int proc_show(struct seq_file *m, void *v){
struct task_struct *task;
/*struct mm_struct *mm; Commented this since it's inside task_struct
*struct vm_area_struct *mmap; Commented this since it's inside task_struct */
unsigned long size;
for_each_process(task){
seq_printf(m,"Task = %s PID = %d\n",task->comm,task->pid);
down_read(&task->mm->mmap_sem);
if(task->mm){
size = (task->mm->mmap->vm_end - task->mm->mmap->vm_start );
seq_printf(m," VIRT = %lu\n",size);
}else{
seq_printf(m," VIRT = 0\n");
}
up_read(&task->mm->mmap_sem);
}
return 0;
}
The message "Killed" is promted as soon I try "~# cat proc/my_proc_file". So far what I think I now is that vm_area_struct is inside of mm_struct which is inside task_struct, all of them defined in the include /linux/sched.h.
A similar question, which is the one I partially based this code on, was posted by #confusedkid (see the post Linux Kernel programming: trying to get vm_area_struct->vm_start crashes kernel). However the replies contradict each other and no one actually explains the reasoning behind the code.
Could anyone please point out what the problem might be or suggest any documentation that explains how to access these structure correctly?
I'd like to use GPIO to turn on an LED in a craneboard (ARM processor). I'm very new to embedded programming. But, I'm quite good at C. I referred in some websites and learnt about GPIO related commands. I wrote a code, but I'm not quite sure in how to integrate it to the u-boot coding of the craneboard. I don't know where to start. Kindly guide me.
#define LED1 (1 << 6)
int getPinState(int pinNumber);
int main(void)
{
GPIO0_IODIR |= LED1;
GPIO0_IOSET |= LED1;
while (1)
{
GPIO0_IOCLR |= LED1;
}
}
int getPinState(int pinNumber)
{
int pinBlockState = GPIO0_IOPIN;
int pinState = (pinBlockState & (1 << pinNumber)) ? 1 : 0;
return pinState;
}
First of all, learn common bit (also pin in your case) manipulation expressions that you will use A LOT in embedded programming:
/* Set bit to 1 */
GPIO0_IODIR |= LED1; //output
/* Clear bit (set to 0) */
GPIO0_IOSET &= ~LED1; //low
/* Toggle bit */
GPIO0_IOSET ^= LED1;
Your while() loop actually does nothing, except for the first iteration, because the same logical OR operations do no change bit state (see logical table of this op). Also you should add delay, because if pin toggles too fast, LED might look like off all the time. Simple solution would look like:
while(1)
{
GPIO0_IOSET ^= LED1;
sleep(1); //or replace with any other available delay command
}
I do not have source files of U-Boot for Craneboard, so cannot tell you the exact place where to put your code, but basically there are several options: 1) add it in main(), where U-Boot start, thus hanging it (but you still have LED blinking!). 2) implement separate command to switch LED on/off (see command.c and cmd_ prefixed files for examples) 3) Integrate it in serial loop, so pin could be switched while waiting user input 4) build it as an application over U-Boot.
Get used to a lot of reading and documentation, TRM is your friend here (sometimes the only one). Also there are some great guides for embedded starters, just google around. Few to mention:
http://www.microbuilder.eu/Tutorials/LPC2148/GPIO.aspx (basics with examples)
http://beagleboard.org/ (great resource for BeagleBoard, but much applies to CraneBoard as they share the same SoC, includes great community).
http://free-electrons.com/ (more towards embedded Linux and other advanced topics, but some basics can also be found)
http://processors.wiki.ti.com/index.php/CraneBoard (official CraneBoard wiki, probably know this, but just in case)
P.S. Good luck in and don't give up!
If you want to do it in u-boot (and not in Linux), then you have to write an application for u-boot.
$5.12 of u-boot manual explains how to do it.
The source of u-boot provides some examples that you can use.
I'd like to add my answer. The coding that I have done previously was a generalized one. In craneboard, there are certain functions, that does the operation. So, I rewrote it accordingly. I included the file cmd_toggle.c in 'common' directory in the u-boot directory. And added it to the Makefile. The following code will make the LED to blink.
int glow_led(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret,i=0,num=0,ctr=0;
int lpin;
lpin=(int)strtoul(argv[1]);
ret=set_mmc_mux();
if(ret<0)
printf("\n\nLED failed to glow!\n\n");
else{
if(!omap_request_gpio(lpin))
{
omap_set_gpio_direction(lpin,0);
for(i=1;i<21;i++)
{
ctr=0;
if((i%2)==0)
{
num=num-1;
omap_set_gpio_dataout(lpin,num);
}
else
{
num=num+1;
omap_set_gpio_dataout(lpin,num);
}
udelay(3000000);
}
}
}
return 0;
}
U_BOOT_CMD(toggle,2,1,glow_led,"Glow an LED","pin_number");
I could've made this a little simpler by just using a while loop to repeatedly set it as 1 and 0.
This can be executed from the u-boot console as toggle 142, as I have connected the LED to the pin 142.
P.S
Thanks for all your guidance. A special thanks to KBart
I'm writing a program that updates flash memory. While I'm erasing/writing flash I would like to be executing from RAM. Ideally I'd link my code to an execution region that's stored in flash that on startup I would copy to the RAM location to which it is linked.
I don't include any of the normal generated C/C++ initialization code so I can't just tag my function as __ram.
If I could do the above then the debuggers symbols would be relevant for the copied to RAM code and I'd be able to debug business as usual.
I'm thinking that something along the lines of OVERLAY/RELOC might help but I'm not sure.
Thanks,
Maybe your application code can do it manually. Something like
pSourceAddr = &FunctionInFlash;
pDestAddr = &RamReservedForFunction;
while(pSourceAddr <= (&FunctionInFlash+FunctionSize))
{ *pDestAddr++ = *pSourceAddr++;
};
typedef int (*RamFuncPtr)(int arg1); //or whatever the signature is..
result = ((RamFuncPtr)&RamReservedForFunction)(argument1);
You should be able to get the linker definition file to export symbols for the FunctionInFlash and RamReservedForFunction addresses.